Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access attributes of an element inside a group?

I'm not sure if I've grouped my elements properly, but my layout in d3 is like so:

var circleGroup = svg.selectAll("g")
               .data(nodeList)
               .enter()
               .append("g")

This creates a bunch a groups, I need a circle in each group:

circleGroup.append("circle") 
         .attr("cx", function(d,i){
            return coordinates[i][0];
         })
         .attr("cy", function(d,i){
            return coordinates[i][1];
         })
         .attr("r", function(d){
            return 10;
         })
         .attr("fill", "white");

The data itself doesn't actually have any coordinate data so I dynamically arrange them in a circle and just position them based on index. I also add some labels. I repeat coordinates[i][0] here but is there a way to access the "cx" and "cy" attributes of the circles? I tried a few forms of d3.select(this) but I'm getting nothing.

circleGroup.append("text")
         .attr("x", function(d,i){
            return coordinates[i][0];
         })
         .attr("y", function(d,i){
            return coordinates[i][1];
         })
         .style("text-anchor","middle")
         .text(function(d,i){
            return d;
         });
like image 788
user2483724 Avatar asked Nov 13 '22 03:11

user2483724


1 Answers

Don't mess with indices, this is hard to maintain and error prone. Instead of that, given your specific tree structure, use node.previousSibling:

circleGroup.append("text")
  .attr("x", function() {
    return d3.select(this.previousSibling).attr("cx");
  })
  .attr("y", function() {
    return d3.select(this.previousSibling).attr("cy");
  })

Here is a demo using (most of) your code:

var svg = d3.select("svg")
var circleGroup = svg.selectAll("g")
  .data(d3.range(5))
  .enter()
  .append("g");

circleGroup.append("circle")
  .attr("cx", function(d, i) {
    return 20 + Math.random() * 280;
  })
  .attr("cy", function(d, i) {
    return 20 + Math.random() * 130;
  })
  .attr("r", function(d) {
    return 10;
  })
  .style("opacity", 0.2);

circleGroup.append("text")
  .attr("x", function() {
    return d3.select(this.previousSibling).attr("cx");
  })
  .attr("y", function() {
    return d3.select(this.previousSibling).attr("cy");
  })
  .style("text-anchor", "middle")
  .text("Foo");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg></svg>
like image 144
Gerardo Furtado Avatar answered Nov 14 '22 22:11

Gerardo Furtado