我知道这里有很多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/

10-09 08:16
查看更多