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
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;
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With