Getting reacquainted with hos D3JS works and, in particular .selectAll/.data/.enter
; learning how to nest data.
I have this working demo:
svg = d3.select('body')
.append('svg')
.attr('width', 640)
.attr('height', 480);
svg.selectAll('text')
.data( [ 'hello', 'world' ] )
.enter()
.append('text')
.attr('x', 10)
.attr('y', function( d, i ) {
return 20 + i * 20;
})
.selectAll('tspan')
.data( function( d, i ) { // d is from the first data
return Array.from(d); // if needed, could return an array or object that includes the initial value, too.
})
.enter()
.append('tspan')
.attr('class', function( d, i ) {
console.log( 'tspan class:', d, i );
if ( ['a', 'e', 'i', 'o', 'u', 'y'].includes(d) ) {
return 'vowel';
}
})
.text( function( d, i, foo ) { // d is from the second data
console.log( 'tspan text:', d, i, /*foo*/ );
return d;
})
.exit()
.attr('class', 'strong') // this will set strong on <tspan>, but I wanted it on <text>
;
(See it on on Codepen: D3JS selectAll SVG nested.)
Notice how we have two data()
, with the second (for <tspan>
s) nested inside the first one (for <text>
s).
What I'm trying to do:
- I want to set the
strong
class attribute on<text>
. - I thought
exit()
would get me out of the "scope"/nest of working with the tspans… but I'm wrong. - If I comment out
exit()
, then the strong class attribute is set on the<tspan>
s… while I want it on the parent<text>
!
How can I achieve that, besides:
- Moving the line up (before the second
data()
). - Using a separate statement (
svg.selectAll('text').attr('class', 'strong');
)
I could use one of these two options and in this example it would be trivial…
But I want to know if it's possible to get out of nested selections and, if so, how?
I hope this was clear enough; if not please comment and I'll clarify :)