2016-11-22 100 views
1

我想在D3中使用从CSV输入中获取的点数据绘制一条线。虽然我可以循环访问我的数据(在dataSet中),但是甚至可以从下一个索引分配x2y2坐标吗?如何在D3中使用csv绘制一条线

//variable 'dataSet' holds all data points 
//x-coordinate in index [0], and y-coordinate in index [1] 

svg.selectAll("line") 
    .data(dataSet) 
    .enter().append("line") 
    .attr("x1", function(d){ 
     return d[0]; 
    }) 
    .attr("y1", function(d){ 
     return d[1]; 
    }) 
    .attr("x2", function(d){ 
     return d[0]; //here's the problem, how can I access the next x-coordinate? 
    }) 
    .attr("y2", function(d){ 
     return d[1]; //here's the problem, how can I access the next y-coordinate? 
    })     
    .attr("interpolate", "linear") 

回答

1

提供给selection.attr()回调将被传递的当前索引作为与基准作为第一个参数沿第二个参数。该指数可以用来访问下一个元素在原dataSet必然选择:

.attr("x2", function(d, i) { // d is the datum, i is the index 
    return dataSet[i+1][0];  // Peek ahead to the next element of the data array 
} 

事实上,在回调,你可以安全地假设d === dataSet[i]

请记住,虽然,—提前偷看时—这最终会抛出一个RangeError最后数据,因为i + 1将引用一个不存在的下一个到最后一个元素。为了防范这一点,你需要实现一个支票,根据您的情况,可能是这样的:

  1. 画一个零长度线在视觉上结束连接线:

    dataSet[Math.min(i + 1, dataSet.length - 1)] 
    
  2. dataSet[(i + 1) % dataSet.length] 
    

把所有T:

由最后连接到第一点,关闭线帽子在一起你的解决方案可能看起来像这样:

var len = dataSet.length; 

function next(i) { 
    var nextIndex = Math.min(i + 1, len - 1); // open 
    // var nextIndex =(i + 1) % len;   // closed 
    return dataSet[nextIndex]; 
} 

svg.selectAll("line") 
    .data(dataSet) 
    .enter().append("line") 
    // ... set x1, x2 
    .attr("x2", function(d, i) { 
     return next(i)[0]; 
    }) 
    .attr("y2", function(d, i) { 
     return next(i)[1]; 
    });     
+0

真棒,感谢高积云,这是非常合理的!由于我仍然习惯于这个'data(dataSet).enter()...'成语,请你帮我进一步告诉我怎样才能遍历'dataSet'的所有元素,而不需要迭代最后一个元素(因为那么i + 1会抛出异常错误)。通常对于许多其他语言,你会告诉编译器停在(array.length - 1)处,但我不确定这将如何完成。 – cicero38

+0

您必须执行检查,主要取决于您在连接的线路末端所查找的内容。 1)没有更多的行:'return dataSet [Math.min(i + 1,dataSet.length - 1)]' - 2)关闭到第一个点:'return dataSet [(i + 1)%dataSet.length] '。 – altocumulus

+0

谢谢++ !!!!!!! – cicero38