您需要使用线生成器,当前正在传递一个表示每个点的对象数组,并为每个点附加一条线-这种方法不起作用(部分原因是线没有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>