简体   繁体   中英

Nested SVG selections in D3

I have a list of n associative arrays.

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

Within a large SVG, I want to: a) create rects ("buckets") whose dimensions are proportional to the lengths of their 'relevant' sublists, and b) create rects ("pieces"), for each of the elements in the sublists, placed "inside" their respective buckets.

After reading Mike Bostock's response to a similar question , I'm sure that I need to use group ("g") elements to group the pieces together. I can get the code below to produce the DOM tree that I want, but I'm stumped on how to code the y values of the pieces. At the point where I need the value, D3 is iterating over the subarrays. How can I get the index of the current subarray that I'm iterating over from inside it when i no longer points to the index within the larger array?

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");

Is there a method on d available to find the index of the node it's currently inside? In this case, is there a method I can call on a "piece" to find the index of its parent "bucket"?

You can use the secret third argument to the function:

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

There's a simpler way however. You can simply translate the g element and everything you add to it will fall into place.

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");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM