在D3.js中绘制多行 [英] Drawing Multiple Lines in D3.js
问题描述
到目前为止,我一直在使用循环来添加线元素到D3可视化,但这似乎不在API的精神。
Up until now, I've been using loops to add line elements to a D3 visualization, but this doesn't seem in the spirit of the API.
假设我有一些数据,
var data = {time: 1, value: 2, value2: 5, value3: 3,value4: 2},
{time: 2, value: 4, value2: 9, value3: 2,value4: 4},
{time: 3, value: 8, value2:12, value3: 2,value4:15}]);
我想要四行,时间为所有4的X。
I'd like four lines, with time as the X for all 4.
我可以这样做:
var l = d3.svg.line()
.x(function(d){return xScale(d[keys[0]]);})
.y(function(d,i){
return yScale(d[keys[1]]);})
.interpolate("basis");
var l2 = d3.svg.line()
.x(function(d){return xScale(d[keys[0]]);})
.y(function(d,i){
return yScale(d[keys[2]]);})
.interpolate("basis");
var l3 = d3.svg.line()
.x(function(d){return xScale(d[keys[0]]);})
.y(function(d,i){
return yScale(d[keys[3]]);})
.interpolate("basis");
var l4 = d3.svg.line()
.x(function(d){return xScale(d[keys[0]]);})
.y(function(d,i){
return yScale(d[keys[4]]);})
.interpolate("basis");
然后将这些一个一个添加(或循环)。
And then add these one by one (or by a loop).
var line1 = group.selectAll("path.path1")
.attr("d",l(data));
var line2 = group.selectAll("path.path2")
.attr("d",l2(data));
var line3 = group.selectAll("path.path3")
.attr("d",l3(data));
var line4 = group.selectAll("path.path4")
.attr("d",l4(data));
有更好的更通用的方法添加这些路径吗?
Is there a better more general way of adding these paths?
推荐答案
是的。首先,我将重组您的数据以便于迭代,如下所示:
Yes. First I would restructure your data for easier iteration, like this:
var series = [
[{time: 1, value: 2}, {time: 2, value: 4}, {time: 3, value: 8}],
[{time: 1, value: 5}, {time: 2, value: 9}, {time: 3, value: 12}],
[{time: 1, value: 3}, {time: 2, value: 2}, {time: 3, value: 2}],
[{time: 1, value: 2}, {time: 2, value: 4}, {time: 3, value: 15}]
];
现在您只需要一个通用行:
Now you need just a single generic line:
var line = d3.svg.line()
.interpolate("basis")
.x(function(d) { return x(d.time); })
.y(function(d) { return y(d.value); });
然后,您可以一次添加所有路径元素:
And, you can then add all of the path elements in one go:
group.selectAll(".line")
.data(series)
.enter().append("path")
.attr("class", "line")
.attr("d", line);
如果要使数据结构格式更小,还可以将时间提取到单独的数组,然后对这些值使用二维数组。它看起来像这样:
If you want to make the data structure format smaller, you could also extract the times into a separate array, and then use a 2D array for the values. That would look like this:
var times = [1, 2, 3];
var values = [
[2, 4, 8],
[5, 9, 12],
[3, 2, 2],
[2, 4, 15]
];
由于矩阵不包含时间值,因此您需要从x-线发生器的访问器。另一方面,y访问器被简化,因为你可以将矩阵值直接传递到y标度:
Since the matrix doesn't include the time value, you need to look it up from the x-accessor of the line generator. On the other hand, the y-accessor is simplified since you can pass the matrix value directly to the y-scale:
var line = d3.svg.line()
.interpolate("basis")
.x(function(d, i) { return x(times[i]); })
.y(y);
创建元素保持不变:
group.selectAll(".line")
.data(values)
.enter().append("path")
.attr("class", "line")
.attr("d", line);
这篇关于在D3.js中绘制多行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!