嵌套数据中的组和行

时间:2013-01-28 16:39:47

标签: javascript d3.js

我想从嵌套的对象结构中绘制多个svg行(使用D3.js),如下所示:

data = [ 
{ Name: "jim", color: "blue", Points: [{x:0, y:5 }, {x:25, y:7 }, {x:50, y:13}] },
{ Name: "bob", color: "green", Points: [{x:0, y:10}, {x:25, y:30}, {x:50, y:60}] }
];

var line_gen = d3.svg.line().interpolate("linear")
                .x(function(d){return d.x;})
                .y(function(d){return d.y;}); 

我的第一次尝试,基于this question,是使用svg:g来表示第一个嵌套级别,然后访问组内的第二个嵌套级别来渲染这些行:

var g = svg.selectAll(".linegroup")
.data(data).enter()
.append("g")
.attr("class", "linegroup")
.style("stroke", function(d) { return d.color; })
.style("fill", "none");

g.selectAll(".line")
.data(function(d) { return d.Points;})
.enter().append("svg:path")
  .attr("d", line_gen);

但这并没有呈现任何线条。相反,在每个组内部,我为三个数据点中的每一个都获得了一个空路径标记。显然,数据的形状造成了问题。

<g class="linegroup" style="stroke: #0000ff; fill: none;">
    <path></path>
    <path></path>
    <path></path>
</g>

我确实找到了一个不使用组的解决方案(将作为答案发布),但我仍然想知道为什么组解决方案不起作用。

2 个答案:

答案 0 :(得分:2)

这是一个答案,主要基于this question,除了它不使用d3.entries:

data = [ 
{ Name: "jim", color: "blue", Points: [{x:0, y:5 }, {x:25, y:7 }, {x:50, y:13}] },
{ Name: "bob", color: "green", Points: [{x:0, y:10}, {x:25, y:30}, {x:50, y:60}] }
];

svg = d3.select("body").append("svg:svg").attr("width", 100).attr("height", 100)

var line_gen = d3.svg.line().interpolate("linear")
                .x(function(d){return d.x;})
                .y(function(d){return d.y;});

svg.selectAll(".line")
  .data(data)
  .enter().append("svg:path")
    .attr("d", function(d) { return line_gen(d.Points); })   // <<<
    .style("stroke", function(d) { return d.color; })
    .style("fill", "none");

这里的关键方法是不将line_gen函数直接返回到“d”属性,而是将其包装在另一个从外部对象传递正确嵌套数组的函数中。

另请参阅d3.entries与d3.values上的great discussion。 d3.entries似乎对类似问题提出了很多建议,但我不认为这对我的情况有帮助。

答案 1 :(得分:1)

原因是您想为列表中的每个元素绘制一条线 - 嵌套选择适用于存在更多级别的情况。例如,如果您有一个列表作为元素列表,并且每个列表元素包含一组路径(例如,组曲线组),嵌套选择将是合适的。

在您的情况下发生的事情是d3为Points的每个元素生成一个新路径 - 即每个点一个。