D3路径动画 - 无法读取未定义的属性“长度”

时间:2018-04-13 02:07:34

标签: javascript d3.js

我收到上述错误,无法弄清楚原因。

我认为这是d3处理JSON数据的一个神秘问题。当我尝试在控制台中验证所有内容似乎都应该正常运行时,错误抛出,包括获取NestedDataX,Y和newData。它一定不喜欢我如何提供数据,而是关于如何.data()

的实际文档

我的想法是,在我的代码中,我需要通过存储X坐标(深度为几层)和Y坐标(也是)来将GeoJSON转换为可读格式,并将它们加载到一个新的数组中。让它更容易使用。我曾尝试使用.nest(),但我无法让它给我想要的数据。

 Private Sub Rtb_TextChanged()
  Dim lcount as Integer = rtb.Lines.Count
  Dim i As Integer
  If lcount > 1 Then 
    For i = 2 to lcount - 1
     Dim index As Integer = rtb.GetFirstCharIndexFromLine(i)
     Dim count As Integer = rtb.GetFirstCharIndexFromLine(i + 1) - start_index
     rtb.Text = rtb.Text.Remove(index, count)
    Next
   End if
  End Sub

JSON的格式为GEOJSON,格式为:

//Script will be included with an enqueue hook elswhere
//Google API will be included with an enqueue hook elsewhere 

$(document).ready(function() {
  d3.json("http://localhost/trip_animate/tripData.geojson")
    .then(function(data) {

      console.log("It just works");
      /*********
      Container
      *********/
      var svgContainer = d3.select("#svg2").append("svg")
        .attr("width", 1000)
        .attr("height", 1000);

      /************
      Scales
      ************/
      var width = 1000;
      var height = 1000;

      //TODO

      var x = d3.scaleTime()
        .range([0, width]);
      var y = d3.scaleTime()
        .range([height, 0]);


      var xAxis = d3.axisBottom()
        .scale(x);

      var yAxis = d3.axisLeft()
        .scale(y);
      //CREATE, THEN MODIFY
      /**********
          Format data for usage with our animation
          ***********/

      var i;
      var j;

      var arrLength = data.features[0]["geometry"]["coordinates"].length;

      /***********
          Create variable to bind x data to
          ***********/
      var nestedDataX = [];
      for (i = 0; i < arrLength; i++) {
        nestedDataX[i] = data.features[0]["geometry"]["coordinates"][i][0];
      }

      var nestedDataY = [];
      for (i = 0; i < arrLength; i++) {
        nestedDataY[i] = data.features[0]["geometry"]["coordinates"][i][1];
      }

      var newData = {
        "x": nestedDataX,
        "y": nestedDataY
      }

      /**********
          Accessor 
          **********/
      var lineFunction2 = d3.line(newData)
        .x(function(d) {
          return x(d.x);
        })
        .y(function(d) {
          return y(d.y);
        })
        .curve(d3.curveBasis);
      /********
          Drawer - Not sure about this one
          ********/
      var tripLine = svgContainer.append("path")
        .data(newData)
        .style("stroke-dasharray", "4,4")
        .attr("d", lineFunction2()) //ERROR THROWS HERE!!!
        .transition()
        .duration(2000)
        .style("stroke", "#ddd")
        .attr("stroke", "red")
        .attr("stroke-width", 4)
        .attr("fill", "none");

    });
});

1 个答案:

答案 0 :(得分:1)

您的代码中存在多个问题。

主要问题是:在D3中,data方法接受三件事:

  1. 数组;
  2. 一个功能;
  3. 没有
  4. 现在,您的newData是一个对象,因此不会显示任何内容(除非您将方法更改为datum,我们将执行此操作,但出于其他原因,请参阅下文)。

    一种可能的解决方案是直接传递数组:

    var tripLine = svg.append("path")
        .datum(data.features[0].geometry.coordinates)
    

    更改线路生成器:

    var lineFunction = d3.line()
        .x(function(d){return d[0]})
        .y(function(d){return d[1]})
        .curve(d3.curveBasis);
    

    小问题:

    1. 您无法将数据传递给d3.line,如下所示:d3.line(data);
    2. 使用datum,而不是data:此处只有一条路径,没有输入选择;
    3. 请勿拨打lineFunction2,删除括号:.attr("d", lineFunction);
    4. 您正在使用attrstyle更改转换后路径的填充。无论目的是什么,它都不会起作用。
    5. 以下是包含这些更改和虚假数据的代码的简化版本:

      &#13;
      &#13;
      var data = {
        "type": "FeatureCollection",
        "features": [{
          "type": "Feature",
          "properties": {
            "name": "Test Drive for data ",
            "time": "2018-04-03T01:48:51Z",
            "coordTimes": []
          },
          "geometry": {
            "type": "LineString",
            "coordinates": [
              [10, 10, 10],
              [30, 40, 10],
              [50, 20, 10],
              [70, 100, 10],
              [90, 20, 10],
              [110, 120, 10],
              [130, 100, 10],
              [150, 80, 10]
            ]
          }
        }]
      }
      
      var svg = d3.select("svg");
      
      var lineFunction = d3.line()
        .x(function(d) {
          return d[0]
        })
        .y(function(d) {
          return d[1]
        })
        .curve(d3.curveBasis);
      
      var tripLine = svg.append("path")
        .datum(data.features[0].geometry.coordinates)
        .style("stroke-dasharray", "4,4")
        .attr("d", lineFunction)
        .style("stroke", "#ddd")
        .transition()
        .duration(2000)
        .style("stroke", "red")
        .attr("stroke-width", 4)
        .attr("fill", "none");
      &#13;
      <script src="https://d3js.org/d3.v5.min.js"></script>
      <svg></svg>
      &#13;
      &#13;
      &#13;