为什么我的 D3js 折线图无法呈现值和 x 轴?

Why does my D3js line chart fail to render values and x-axis?

我正在尝试创建国家气象局数据的折线图。图表 x 轴应显示字符串时间值(“今天”、“今晚”等)。 y轴应该是当天的最高温度。

但是没有显示温度,而且 x 轴似乎都是左对齐的,以至于所有的文本都覆盖了它自己。

我也收到控制台错误:

这一行 .attr("d", valueline); 产生了这个错误:

Error: <path> attribute d: Expected number, "MNaN,111.86440677…"

这一行 .call(d3.axisBottom(x).ticks(10)) 产生了这些错误:

Error: <g> attribute transform: Expected number, "translate(NaN,0)".

Error: <path> attribute d: Expected number, "MNaN,6V0.5HNaNV6".

这是我的代码。它是我从几个网站获得的示例代码的组合。

<!DOCTYPE html>
<meta charset="utf-8">

<!-- Load d3.js -->
<script src="https://d3js.org/d3.v4.js"></script>


<div id="myChart"></div>

<style> /* set the CSS */
    .line {
      fill: none;
      stroke: steelblue;
      stroke-width: 2px;
    }
    body {
      font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
      font-weight: 400;
      font-size: 24px;
    }
    
</style>

<body>
  <script>
  // class to hold day data
  let DayData = class {
    constructor(name, high) {
      this.name = name;
      this.high = high;
    }
  }

  let daysData = new Array();

  var width = 0;
  var height = 0;
  // set the dimensions and margins of the graph
  var margin = {top: 10, right: 30, bottom: 60, left: 60},
      width = 1000 - margin.left - margin.right, //460
      height = 400 - margin.top - margin.bottom;

  /*------------------------------------------------------*/
  // get the data
  /*------------------------------------------------------*/
  d3.json("https://api.weather.gov/gridpoints/BOU/69,50/forecast", 

      function(resp) {

          let data = resp['properties']['periods'];
          console.log(data);

          // structure the data
          data.forEach(
          function(day) {    
              dayData = new DayData(day.name, day.temperature);
              daysData.push(dayData);
          });

          data = daysData;

          // set the ranges
          var x = d3.scaleBand().range(0, width);
          var y = d3.scaleLinear().range([height, 0]);


          // define the line
          var valueline = d3.line()
              .x(function(d) {
                return x(d.name); 
              })
              .y(function(d) {
                return y(d.high); 
              });

          // append the svg object to the body of the page
          var svg = d3.select("#myChart")
            .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 + ")");

          // scale the range of data
          x.domain(data.map(function(d) { 
            return d.name
          }));

          y.domain([0, d3.max(data, function(d) { 
            return d.high 
          })]);


          // Add the valueline path.
          svg.append("path")
          .data([data])
          .attr("class", "line")
          .attr("d", valueline);


      // Add the x Axis
      svg.append("g")
        .attr("class", "axis")
        .attr("transform", "translate(0," + height + ")")
        .call(d3.axisBottom(x).ticks(10))
        .selectAll("text")  
          .style("text-anchor", "end")
          .attr("dx", "-.8em")
          .attr("dy", ".15em")
          .attr("transform", "rotate(-65)");


          // text label for the x axis
          svg.append("text")             
              .attr("transform",
              "translate(" + (width/2) + " ," + 
              (height + margin.top + 20) + ")")
              .style("text-anchor", "middle")
              .text("Day");

          // Add the y Axis
          svg.append("g")
          .call(d3.axisLeft(y));

          // text label for the y axis
          svg.append("text")
              .attr("transform", "rotate(-90)")
              .attr("y", 0 - margin.left)
              .attr("x",0 - (height / 2))
              .attr("dy", "1em")
              .style("text-anchor", "middle")
              .text("Temperature");      


  }); // end get json weather

  </script>
</body>

请帮忙,谢谢。

d3 比例尺中的 .range() 方法接受定义比例尺输出值的数组。

在这一行:

  //set the ranges
   var x = d3.scaleBand().range(0, width);
   var y = d3.scaleLinear().range([height, 0]);

注意 Y 刻度范围如何正确定义,但 X 范围缺少 [ ],将数组变成两个无效参数。由于刻度输出无效,导致路径出现NaN错误,x轴无法正常渲染

将范围声明为数组应该可以修复错误:

   var x = d3.scaleBand().range([0, width]);