我想在d3.js中创建一个折线图,但只有我的轴出现了;这条线没有显示出来。
正在发挥作用的事情:1。我的轴标记正确2.在Chrome中查看页面元素时,该行的x和y属性似乎是“工作”。 (即,为线/定义的坐标数据不是' NaN'值)。我认为与我的行相关的属性肯定有问题(Javascript代码的结尾)。
有没有可能发生这种情况的原因?
这是我的情节/图表输出目前的样子:
这是我的HTML,Javascript和我用于剧情的数据:
HTML:
<html>
<head>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<div id="merit-order-chart"></div>
</body>
<script type="text/javascript" src="/src.js"></script>
</html>
JAVASCRIPT:
// create a SVG element
let svg2 = d3.select("#merit-order-chart").append("svg");
// sizing parameters
let margin2 = {top: 20, right: 50, bottom: 40, left: 80};
let width2 = 800;
let height2 = 400;
let chartWidth2 = width2 - margin2.left - margin2.right;
let chartHeight2 = height2 - margin2.top - margin2.bottom;
// sizing the SVG
svg2.attr("width", width2 + "px")
.attr("height", height2 + "px");
// creating the x and y scales
let y2 = d3.scaleLinear()
.clamp(true)
.range([chartHeight2, 0]);
let x2 = d3.scaleTime()
.clamp(true)
.range([0, chartWidth2]);
// formatting of the x and y axes
let xAxis2 = d3.axisBottom()
.scale(x2)
.tickFormat(d3.timeFormat("%Y-%m-%d %H:%M:%S"))
.ticks(4);
let yAxis2 = d3.axisLeft()
.scale(y2)
.ticks(8);
// adding a 'group' element for all the things attached to the chart
let chart2 = svg2.append("g")
.attr("transform", `translate(${margin2.left},${margin2.top})`);
// adding the x and y axis elements to the chart group (g)
const xg2 = chart2.append("g")
.classed("x axis", true)
.attr("transform", `translate(0,${chartHeight2})`)
.call(xAxis2);
const yg2 = chart2.append("g")
.classed("y axis", true)
.call(yAxis2);
d3.csv("/price-data.csv", (err, csv) => {
const clean2 = csv.map(d2 => {
// clean up number formats
d2.p = parseFloat(d2.p);
d2.settlementdate = Date.parse(d2.settlementdate)
d2.index = parseFloat(d2.index);
return d2;
});
// re-sizing the x and y axes
x2.domain([d3.min(clean2, d2 => d2.settlementdate), d3.max(clean2, d2 => d2.settlementdate)]);
xg2.call(xAxis2);
y2.domain([-1000, 14125]);
yg2.call(yAxis2);
chart2.selectAll(".prices")
.data(clean2)
.enter()
.append("line")
.attr("x", d2 => x2(d2.settlementdate))
.attr("y", d2 => y2(d2.p))
.attr("stroke-width", 5)
.attr("stroke", "black")
//.style("stroke", "rgb(6,120,155)");
});
DATA(.csv):
settlementdate,p,index
1/1/2017 0:00,50,1
1/1/2017 0:05,35,2
1/1/2017 0:10,100,3
1/1/2017 0:15,5000,4
答案 0 :(得分:1)
你需要使用一个线生成器,目前你正在传递一个代表每个点的对象数组,并为每个点附加一条线 - 这种方法不起作用(部分原因是线没有x和y属性,但是x1,x2,y1,y2属性)。
您需要使用线路生成器:
let line = d3.line()
.x(function(d) { return x2(d.settlementdate); }) // x value for each point
.y(function(d) { return y2(d.p); }) // y value for each point
这将返回一个路径,其中每个坐标都有一个顶点。因此,您需要附加路径而不是行,并且路径的绘图说明包含在d
属性中,因此您可以使用.attr("d", line)
。
最后,由于每个数据集需要一个路径,而不是每个数据点一个路径,因此将数据嵌套到数组中。通过这样做,你得到一条有很多点的线,而不是很多没有点的线。
我更改了比例以显示曲线,但结果却缩小了峰值:
chart2.selectAll(".prices")
.data([clean2])
.enter()
.append("path")
.attr("d",line)
.attr("stroke-width", 5)
.attr("stroke", "black")
.attr("fill","none")
var csv = [
{ settlementdate: "1/1/2017 0:00",p:50,index:1 },
{ settlementdate: "1/1/2017 0:05",p:35,index:2 },
{ settlementdate: "1/1/2017 0:10",p:100,index:3 },
{ settlementdate: "1/1/2017 0:15",p:5000,index:4 }
]
// create a SVG element
let svg2 = d3.select("#merit-order-chart").append("svg");
// sizing parameters
let margin2 = {top: 20, right: 50, bottom: 40, left: 80};
let width2 = 800;
let height2 = 400;
let chartWidth2 = width2 - margin2.left - margin2.right;
let chartHeight2 = height2 - margin2.top - margin2.bottom;
// sizing the SVG
svg2.attr("width", width2 + "px")
.attr("height", height2 + "px");
// creating the x and y scales
let y2 = d3.scaleLinear()
.clamp(true)
.range([chartHeight2, 0]);
let x2 = d3.scaleTime()
.clamp(true)
.range([0, chartWidth2]);
// formatting of the x and y axes
let xAxis2 = d3.axisBottom()
.scale(x2)
.tickFormat(d3.timeFormat("%Y-%m-%d %H:%M:%S"))
.ticks(4);
let yAxis2 = d3.axisLeft()
.scale(y2)
.ticks(8);
// adding a 'group' element for all the things attached to the chart
let chart2 = svg2.append("g")
.attr("transform", `translate(${margin2.left},${margin2.top})`);
// adding the x and y axis elements to the chart group (g)
const xg2 = chart2.append("g")
.classed("x axis", true)
.attr("transform", `translate(0,${chartHeight2})`)
.call(xAxis2);
const yg2 = chart2.append("g")
.classed("y axis", true)
.call(yAxis2);
let line = d3.line()
.x(function(d) { return x2(d.settlementdate); })
.y(function(d) { return y2(d.p); })
const clean2 = csv.map(d2 => {
// clean up number formats
d2.p = parseFloat(d2.p);
d2.settlementdate = Date.parse(d2.settlementdate)
d2.index = parseFloat(d2.index);
return d2;
});
// re-sizing the x and y axes
x2.domain([d3.min(clean2, d2 => d2.settlementdate), d3.max(clean2, d2 => d2.settlementdate)]);
xg2.call(xAxis2);
y2.domain([0, 200]);
yg2.call(yAxis2);
chart2.selectAll(".prices")
.data([clean2])
.enter()
.append("path")
.attr("d",line)
.attr("stroke-width", 5)
.attr("stroke", "black")
.attr("fill","none")
//.style("stroke", "rgb(6,120,155)");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
<div id="merit-order-chart"></div>