D3中的嵌套SVG选择

时间:2013-11-28 22:23:46

标签: javascript svg d3.js

我有一个n个关联数组的列表。

[{'path': 'somepath', 'relevant': [7, 8, 9]}, {'path': 'anotherpath', 'relevant': [9], ...}

在一个大的SVG中,我想:a)创建其尺寸与其'relevant'子列表的长度成比例的rects(“buckets”),以及b)为每个创建rects(“pieces”)在子列表中的元素中,放置在各自的桶内“。

在阅读Mike Bostock对similar question的回复之后,我确信我需要使用组(“g”)元素将这些部分组合在一起。我可以获得下面的代码来生成我想要的DOM树,但是我对如何编写片段的y值感到困惑。在我需要该值的点上,D3正在遍历子阵列。当i不再指向较大数组中的索引时,如何获取当前从其内部迭代的子数组的索引?

var piece_bukcets = svg.selectAll("g.piece_bucket")
                      .data(files)
                      .enter()
                      .append("g")
                      .attr("class", "piece_bucket")
                      .attr("id", function (d, i) { return ("piece_bucket" + i) })
                      .append("rect")
                      .attr("y", function (d, i) { return (i * 60) + 60; })
                      .attr("class", "bar")
                      .attr("x", 50)
                      .attr("width", function (d) { 
                        return 10 * d["relevant"].length;
                      })
                      .attr("height", 20)
                      .attr("fill", "red")
                      .attr("opacity", 0.2)

        var pieces = svg.selectAll("g.piece_bucket")
                        .selectAll("rect.piece")
                        .data( function (d) { return d["relevant"]; })
                        .enter()
                        .append("rect")
                        .attr("class", "piece")
                        .attr("id", function (d) { return ("piece" + d) })
                        .attr("y", ????)  // <<-- How do I get the y value of d's parent?
                        .attr("x", function (d, i) { return i * 10; })
                        .attr("height", 10)
                        .attr("width", 10)
                        .attr("fill", "black");

d上有一个方法可以找到它当前所在节点的索引吗?在这种情况下,是否有一种方法可以调用“片段”来查找其父“桶”的索引?

1 个答案:

答案 0 :(得分:4)

您可以使用函数的第三个秘密参数:

.attr("y", function(d, i, j) {
  // j is the i of the parent
  return (j * 60) + 60;
})

然而,有一种更简单的方法。您只需翻译g元素,您添加的所有内容都将落实到位。

var piece_buckets = svg.selectAll("g.piece_bucket")
                  .data(files)
                  .enter()
                  .append("g")
                  .attr("class", "piece_bucket")
                  .attr("transform", function(d, i) {
                    return "translate(0," + ((i*60) + 60) + ")";
                  })
                  .attr("id", function (d, i) { return ("piece_bucket" + i) });
piece_buckets.append("rect")
                  .attr("class", "bar")
                  .attr("x", 50)
                  .attr("width", function (d) { 
                    return 10 * d["relevant"].length;
                  })
                  .attr("height", 20)
                  .attr("fill", "red")
                  .attr("opacity", 0.2);

var pieces = piece_buckets.selectAll("rect.piece")
                    .data(function (d) { return d["relevant"]; })
                    .enter()
                    .append("rect")
                    .attr("class", "piece")
                    .attr("id", function (d) { return ("piece" + d); })
                    .attr("x", function (d, i) { return i * 10; })
                    .attr("height", 10)
                    .attr("width", 10)
                    .attr("fill", "black");