折线图中的路径太小
Path in Line Chart is too small
我目前正在使用 d3.js 创建折线图,但遇到了正确的路径宽度和高度问题。
const margin = {
top: 50,
right: 50,
bottom: 50,
left: 50
}
const width = 700
const height = 500
const dateConv = d3.timeParse("%Y-%m-%d")
const svg = d3.select("#temparatureGraph").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")")
d3.xml("https://raw.githubusercontent.com/ForceSergeant/D3LineGraph/6aa5b375dbc0bd2ca86f6fcef73369caae64232e/data.xml")
.then((xml) => {
let values = []
let dates = []
let times = []
//Processign the data
const document = d3.select(xml.documentElement)
const temperature = document.selectAll('temperature')
temperature.selectAll("average").each(function() {
values.push(+this.textContent)
})
const date = document.selectAll('utc')
date.selectAll("date").each(function() {
dates.push(dateConv(this.textContent))
})
const time = document.selectAll('utc')
time.selectAll("time").each(function() {
times.push(this.textContent)
})
console.log(dates)
console.log(times)
dates = dates.map((value, index) => {
value.setHours(times[index].split(":")[0])
return value
})
const data = []
for (var i = 0; i < dates.length; i++) {
data.push({
date: dates[i],
value: values[i]
})
}
console.log(data)
const xScale = d3.scaleTime().range([0, width])
const yScale = d3.scaleLinear().range([height, 0])
xScale.domain(d3.extent(data, d => d.date))
yScale.domain([d3.min(data, d => d.value), d3.max(data, d => d.value)])
const xaxis = d3.axisBottom()
.ticks(d3.timeMonth.every(1))
.tickFormat(d3.timeFormat('%b %y'))
.scale(xScale);
const yaxis = d3.axisLeft().scale(yScale);
//x-Achse
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + height + ")")
.call(xaxis);
//y-Achse
svg.append("g")
.attr("class", "axis")
.call(yaxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("dy", ".75em")
.attr("y", 6)
.style("text-anchor", "end")
.text("Grad Celsius");
const line = d3.line()
.x(function(d) {
return xScale(d.date);
})
.y(function(d) {
return yScale(d.value);
});
svg.append("path")
.datum(data)
.attr("class", "dataPath")
.attr("d", line)
})
.axis line {
stroke: red;
}
/* axis contour */
.axis path {
stroke: green;
}
/* axis text */
.axis text {
fill: blue;
}
.dataPath {
fill: none;
stroke: gold;
stroke-miterlimit: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="temparatureGraph"></div>
- Values 是每一天和每一小时的温度数组
- Dates是一个数组,对应的日期
- times是一个数组对应的Time
数据是具有以下形式的 obj 数组:[{date: , value: }]
一切正常,但路径太小,不适合 x 轴,如图所示。
她就是XML-file.
感谢您的帮助。
您的示例中缺少一些数据,具体来说,在 2018 年 1 月 31 日,value
为 NaN。
在 d3 中,您需要设置折线图可以跳过哪些值,否则它会尝试绘制它们、中断并(无益地)退出而不发出警告。您可以使用 d3.line().defined()
执行此操作,我在下面的(放大)示例中就是这样做的。请注意该行如何停止存在并稍后重新启动。
const margin = {
top: 50,
right: 50,
bottom: 50,
left: 50
}
const width = 700
const height = 500
const dateConv = d3.timeParse("%Y-%m-%d")
const svg = d3.select("#temparatureGraph").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")")
d3.xml("https://raw.githubusercontent.com/ForceSergeant/D3LineGraph/6aa5b375dbc0bd2ca86f6fcef73369caae64232e/data.xml")
.then((xml) => {
let values = []
let dates = []
let times = []
//Processign the data
const document = d3.select(xml.documentElement)
const temperature = document.selectAll('temperature')
temperature.selectAll("average").each(function() {
values.push(+this.textContent)
})
const date = document.selectAll('utc')
date.selectAll("date").each(function() {
dates.push(dateConv(this.textContent))
})
const time = document.selectAll('utc')
time.selectAll("time").each(function() {
times.push(this.textContent)
})
dates.forEach((value, index) => {
value.setHours(times[index].split(":")[0])
})
const data = []
// I just added this for simplicity,
// it's unrelated to the solution
for (var i = 700; i < 750; i++) {
data.push({
date: dates[i],
value: values[i]
})
}
const xScale = d3.scaleTime().range([0, width])
const yScale = d3.scaleLinear().range([height, 0])
xScale.domain(d3.extent(data, d => d.date))
yScale.domain([d3.min(data, d => d.value), d3.max(data, d => d.value)]);
const xaxis = d3.axisBottom()
.ticks(d3.timeMonth.every(1))
.tickFormat(d3.timeFormat('%b %y'))
.scale(xScale);
const yaxis = d3.axisLeft().scale(yScale);
//x-Achse
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + height + ")")
.call(xaxis);
//y-Achse
svg.append("g")
.attr("class", "axis")
.call(yaxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("dy", ".75em")
.attr("y", 6)
.style("text-anchor", "end")
.text("Grad Celsius");
const line = d3.line()
.defined(function(d) { return !isNaN(d.value); })
.x(function(d) {
return xScale(d.date);
})
.y(function(d) {
return yScale(d.value);
});
svg.append("path")
.datum(data)
.attr("class", "dataPath")
.attr("d", line)
})
.axis line {
stroke: red;
}
/* axis contour */
.axis path {
stroke: green;
}
/* axis text */
.axis text {
fill: blue;
}
.dataPath {
fill: none;
stroke: gold;
stroke-miterlimit: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="temparatureGraph"></div>
我目前正在使用 d3.js 创建折线图,但遇到了正确的路径宽度和高度问题。
const margin = {
top: 50,
right: 50,
bottom: 50,
left: 50
}
const width = 700
const height = 500
const dateConv = d3.timeParse("%Y-%m-%d")
const svg = d3.select("#temparatureGraph").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")")
d3.xml("https://raw.githubusercontent.com/ForceSergeant/D3LineGraph/6aa5b375dbc0bd2ca86f6fcef73369caae64232e/data.xml")
.then((xml) => {
let values = []
let dates = []
let times = []
//Processign the data
const document = d3.select(xml.documentElement)
const temperature = document.selectAll('temperature')
temperature.selectAll("average").each(function() {
values.push(+this.textContent)
})
const date = document.selectAll('utc')
date.selectAll("date").each(function() {
dates.push(dateConv(this.textContent))
})
const time = document.selectAll('utc')
time.selectAll("time").each(function() {
times.push(this.textContent)
})
console.log(dates)
console.log(times)
dates = dates.map((value, index) => {
value.setHours(times[index].split(":")[0])
return value
})
const data = []
for (var i = 0; i < dates.length; i++) {
data.push({
date: dates[i],
value: values[i]
})
}
console.log(data)
const xScale = d3.scaleTime().range([0, width])
const yScale = d3.scaleLinear().range([height, 0])
xScale.domain(d3.extent(data, d => d.date))
yScale.domain([d3.min(data, d => d.value), d3.max(data, d => d.value)])
const xaxis = d3.axisBottom()
.ticks(d3.timeMonth.every(1))
.tickFormat(d3.timeFormat('%b %y'))
.scale(xScale);
const yaxis = d3.axisLeft().scale(yScale);
//x-Achse
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + height + ")")
.call(xaxis);
//y-Achse
svg.append("g")
.attr("class", "axis")
.call(yaxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("dy", ".75em")
.attr("y", 6)
.style("text-anchor", "end")
.text("Grad Celsius");
const line = d3.line()
.x(function(d) {
return xScale(d.date);
})
.y(function(d) {
return yScale(d.value);
});
svg.append("path")
.datum(data)
.attr("class", "dataPath")
.attr("d", line)
})
.axis line {
stroke: red;
}
/* axis contour */
.axis path {
stroke: green;
}
/* axis text */
.axis text {
fill: blue;
}
.dataPath {
fill: none;
stroke: gold;
stroke-miterlimit: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="temparatureGraph"></div>
- Values 是每一天和每一小时的温度数组
- Dates是一个数组,对应的日期
- times是一个数组对应的Time 数据是具有以下形式的 obj 数组:[{date: , value: }]
一切正常,但路径太小,不适合 x 轴,如图所示。
她就是XML-file.
感谢您的帮助。
您的示例中缺少一些数据,具体来说,在 2018 年 1 月 31 日,value
为 NaN。
在 d3 中,您需要设置折线图可以跳过哪些值,否则它会尝试绘制它们、中断并(无益地)退出而不发出警告。您可以使用 d3.line().defined()
执行此操作,我在下面的(放大)示例中就是这样做的。请注意该行如何停止存在并稍后重新启动。
const margin = {
top: 50,
right: 50,
bottom: 50,
left: 50
}
const width = 700
const height = 500
const dateConv = d3.timeParse("%Y-%m-%d")
const svg = d3.select("#temparatureGraph").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")")
d3.xml("https://raw.githubusercontent.com/ForceSergeant/D3LineGraph/6aa5b375dbc0bd2ca86f6fcef73369caae64232e/data.xml")
.then((xml) => {
let values = []
let dates = []
let times = []
//Processign the data
const document = d3.select(xml.documentElement)
const temperature = document.selectAll('temperature')
temperature.selectAll("average").each(function() {
values.push(+this.textContent)
})
const date = document.selectAll('utc')
date.selectAll("date").each(function() {
dates.push(dateConv(this.textContent))
})
const time = document.selectAll('utc')
time.selectAll("time").each(function() {
times.push(this.textContent)
})
dates.forEach((value, index) => {
value.setHours(times[index].split(":")[0])
})
const data = []
// I just added this for simplicity,
// it's unrelated to the solution
for (var i = 700; i < 750; i++) {
data.push({
date: dates[i],
value: values[i]
})
}
const xScale = d3.scaleTime().range([0, width])
const yScale = d3.scaleLinear().range([height, 0])
xScale.domain(d3.extent(data, d => d.date))
yScale.domain([d3.min(data, d => d.value), d3.max(data, d => d.value)]);
const xaxis = d3.axisBottom()
.ticks(d3.timeMonth.every(1))
.tickFormat(d3.timeFormat('%b %y'))
.scale(xScale);
const yaxis = d3.axisLeft().scale(yScale);
//x-Achse
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + height + ")")
.call(xaxis);
//y-Achse
svg.append("g")
.attr("class", "axis")
.call(yaxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("dy", ".75em")
.attr("y", 6)
.style("text-anchor", "end")
.text("Grad Celsius");
const line = d3.line()
.defined(function(d) { return !isNaN(d.value); })
.x(function(d) {
return xScale(d.date);
})
.y(function(d) {
return yScale(d.value);
});
svg.append("path")
.datum(data)
.attr("class", "dataPath")
.attr("d", line)
})
.axis line {
stroke: red;
}
/* axis contour */
.axis path {
stroke: green;
}
/* axis text */
.axis text {
fill: blue;
}
.dataPath {
fill: none;
stroke: gold;
stroke-miterlimit: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="temparatureGraph"></div>