线条没有出现在d3.js折线图中(只有轴可见)

问题描述 投票:2回答:1

我想在d3.js中创建一个折线图,但只有我的轴出现了;这条线没有显示。

有效的事情:1。我的轴标记正确2.在Chrome中查看页面元素时,该行的x和y属性似乎是“正常”(即,为行定义的坐标数据/不是'NaN'值)。我认为与我的行相关的属性肯定有问题(Javascript代码的结尾)。

这有可能发生的原因吗?

这是我的情节/图表输出目前的样子:

Current state of plot

这是我的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
javascript d3.js linechart linegraph
1个回答
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>
© www.soinside.com 2019 - 2024. All rights reserved.