Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Appending multiple elements in a single Join

Tags:

d3.js

I am trying to append multiple elements within the enter function of a single join using d3v5.

What is the proper method for appending multiple elements to a single group when using selection.join()?

The DOM structure I am trying to create looks something like this:

<svg id="chart">
    <g class="data-group">
        <rect class="data-rect" x="5" y="5" width="10" height="10" style="fill: red;"></rect>
        <text class="data-text" x="15" y="20">data1</text>
    </g>
    <g class="data-group">
        <rect class="data-rect" x="25" y="25" width="10" height="10" style="fill: green;"></rect>
        <text class="data-text" x="35" y="40">data2</text>
    </g>
    <g class="data-group">
        <rect class="data-rect" x="50" y="50" width="10" height="10" style="fill: gray;"></rect>
        <text class="data-text" x="60" y="65">data3</text>
    </g>
</svg>

I can easily produce this structure manually by looping through data fiddle

for(var i = 0; i < data.length; i++){
let o = data[i];
let g = d3.select('#chart')
    .append('g')
  .datum(o)
  .attr('class', 'data-group');
  
g.append('rect')
  .attr('class', 'data-rect')
  .attr('x',5)
  .attr('y', d => d.id * offset)
  .attr('width', 10)
  .attr('height', 10)
  .style('fill', d => d.color);
  
g.append('text')
  .attr('class', 'data-text')
  .attr('x', 15)
  .attr('y', d => d.id * offset + 9)
  .text(d => d.text);
}

I want to use selection.join() so I can cleanly take advantage of enter, update, and exit.

I can get close to this structure, however, I can't append the text element because it would be appended to the rect instead of the g (and ya can't append text to a rect!) fiddle

d3.select('#chart')
    .selectAll('.data-group')
    .data(data, d => d.id)
  .join((enter) => {
    return enter
      .append('g')
      .attr('class', 'data-group')
      .append('rect')
      .attr('class', 'data-rect')
      .attr('x',d => d.id * offset)
      .attr('y', 5)
      .attr('width', 10)
      .attr('height', 10)
      .style('fill', d => d.color);
  })

Appending multiple elements then returning enter doesn't work either, it throws an exception fiddle

like image 588
rundy Avatar asked Oct 19 '25 03:10

rundy


1 Answers

See BallPointBen's comment on my original question.

Multiple elements can be appended in a join by doing the following:

d3.select('#chart')
    .selectAll('.data-group')
    .data(data, d => d.id)
    .join((enter) => {
        let g = enter;
    
        g.append('g')
         .attr('class', 'data-group')

        g.append('rect')
         .attr('class', 'data-rect')
         .attr('x',d => d.id * offset)
         .attr('y', 5)
         .attr('width', 10)
         .attr('height', 10)
         .style('fill', d => d.color);

        g.append('text')
         .attr('class', 'data-text');

    return g;
  })
like image 85
rundy Avatar answered Oct 22 '25 06:10

rundy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!