2011-12-31 139 views
38

到目前为止,我一直在使用循环向D3可视化添加线条元素,但这看起来并不符合API的精神。在D3.js中绘制多条线

比方说,我已经得到了一些数据,

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}]); 

我想四条线,以时间为X的所有4

我可以做这样的事情:

然后逐个添加(或通过循环)。

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)); 

有没有更好的更一般的方法来添加这些路径?

回答

72

是的。首先,我会调整你的数据更容易重复,像这样:

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}] 
]; 

现在,你只需要一个通用的线:

var line = d3.svg.line() 
    .interpolate("basis") 
    .x(function(d) { return x(d.time); }) 
    .y(function(d) { return y(d.value); }); 

而且,那么你可以添加所有的路径元素一气呵成:

group.selectAll(".line") 
    .data(series) 
    .enter().append("path") 
    .attr("class", "line") 
    .attr("d", line); 

如果你想使数据结构的幅面,你也可以在次提取到一个单独的数组,然后使用该值的二维数组。这将是这样的:

var times = [1, 2, 3]; 

var values = [ 
    [2, 4, 8], 
    [5, 9, 12], 
    [3, 2, 2], 
    [2, 4, 15] 
]; 

由于矩阵不包含的时间价值,你需要从线发生器的X-访问查找。在另一方面,在Y-访问被简化了,因为你可以直接通过矩阵值到Y规模:

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); 
+1

迈克,我用了你这里的例子是为了在多行上取得一些进展,但是如何转换?想知道如果你可以眼球这个问题,请:http://stackoverflow.com/questions/10404283/d3-js-transform-transition-multiple-lines - 谢谢! – August 2012-05-02 15:36:18

+0

x(d.time);似乎是不正确的 - 对此没有特别的功能;它只适用于将其更改为简单d.time的情况。对应的y也是一样。 – LittleBobbyTables 2012-07-19 18:38:36

+14

'x'和'y'指的是尺度,你应该在使用前定义尺度。 – mbostock 2012-07-20 15:28:25