我知道这里有很多D3嵌套问题和答案,但是我似乎无法弄清楚我的问题是什么。
刚开始进行嵌套时,我创建了以下要点:
http://bl.ocks.org/AndrewStaroscik/5686192。数据位于parentElement变量中:
var parentElement = [
{name: "Path 1", startX: 25, startY: 75, segments: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]},
{name: "Path 2", startX: 25, startY: 125, segments: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}
];
以下脚本按预期方式呈现了一系列线段:
var g = svg.selectAll(".parent")
.data(parentElement);
var gEnter = g.enter()
.append("g")
.attr("class", "parent")
.attr('transform', function(d) { return 'translate(' + d.startX + ',' + d.startY + ')'; })
.style('fill', 'none')
.style('stroke', '#232323');
gEnter.selectAll(".child")
.data(function(d) {
console.log(d.segments);
return d.segments; })
.enter()
.append("line")
.attr('class', 'child')
.attr('x1', function(d,i) { return lineLength * d; })
.attr('y1', 0)
.attr('x2', function(d,i) { return lineLength * (1 + d); })
.attr('y2', 0);
现在,我尝试通过在嵌套中使用对象数组而不是数字数组来扩展此对象。我将数据修改如下:
var parentElement = [
{name: "Path 1", startX: 25, startY: 75, segments: [
{type: "line", val: 1},
{type: "line", val: 2},
{type: "line", val: 3},
{type: "line", val: 4},
{type: "line", val: 5},
{type: "line", val: 6},
{type: "line", val: 7},
{type: "line", val: 8},
{type: "line", val: 9}
]},
{name: "Path 2", startX: 25, startY: 125, segments: [
{type: "line", val: 1},
{type: "line", val: 2},
{type: "line", val: 3},
{type: "line", val: 4},
{type: "line", val: 5},
{type: "line", val: 6},
{type: "line", val: 7},
{type: "line", val: 8},
{type: "line", val: 9}
]},
];
而selectAll子部分如下:
gEnter.selectAll(".child")
.data(function(d) {
console.dir(d.segments);
return d.segments; })
.enter()
.append(function(d) {
console.log(d.type);
return d.type;
})
.attr('class', 'child')
.attr('x1', function(d,i) { return lineLength * d.val; })
.attr('y1', 0)
.attr('x2', function(d,i) { return lineLength * (1 + d.val); })
.attr('y2', 0);
最终目标是能够使用相同的代码将不同类型的多个元素(圆形,正方形,路径等)添加到“ g”元素中。所以
.append(function(d) {
console.log(d.type);
return d.type;
})
在此示例中显然没有必要,但最终将很重要。
这是完整的无法正常运行的版本:http://bl.ocks.org/AndrewStaroscik/e394056440e603374404
数据结构的更改如何破坏代码?
最佳答案
问题在于.append()
不采用返回元素名称的函数-您必须将元素名称指定为字符串,或者从该函数返回DOM元素。因此,在您的情况下,它看起来像这样:
.append(function(d) {
return document.createElementNS(d3.ns.prefix.svg, d.type);
})
虽然这确实使您可以使用,但是通常这样做还需要您指定数据中的所有属性,因为不同类型的元素具有不同的属性。如果指定了错误的数据类型,这可能会使您的代码和数据非常混乱,并引入难以调试的错误。
坚持使用标准D3方法通常更容易,更安全。您可以通过在将数据传递给
.data()
之前过滤数据来实现相同的目的:gEnter.selectAll("line.child")
.data(function(d) {
return d.segments.filter(function(e) { return e.type == "line"; });
})
.enter()
.append("line")
同样适用于其他类型的元素。
关于javascript - d3中嵌套数据的类型节点错误的参数编号,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27387104/