我正在尝试使用从CSV输入获得的点数据在D3中绘制一条线。虽然我可以遍历我的数据(dataSet
),但是甚至可以从下一个索引分配x2
和y2
坐标吗?
//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")
答案 0 :(得分: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
将引用一个不存在的倒数第二个元素。为了防范这种情况,您需要实施一个检查,根据您的情况,可以是这样的:
绘制零长度线以直观地结束连接线:
dataSet[Math.min(i + 1, dataSet.length - 1)]
通过将最后一个连接到第一个点来关闭线条:
dataSet[(i + 1) % dataSet.length]
将所有这些放在一起你的解决方案可能如下所示:
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];
});