我想从嵌套的对象结构中绘制多个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>
我确实找到了一个不使用组的解决方案(将作为答案发布),但我仍然想知道为什么组解决方案不起作用。
答案 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
的每个元素生成一个新路径 - 即每个点一个。