score:0
You could think about modifying your original data and that way you could just use one data binding and one update pattern. Within that pattern, you could check/use the word but also check each letter of the word (you could also just do this on the fly later):
const test_data = [ 'hello', 'world', 'wthtvwls' ];
const modified_data = test_data.map((item,index) => {
return {
word: item,
array: Array.from(item)
}
});
console.log(modified_data);
Then using this data (demo - https://codepen.io/Alexander9111/pen/qBdZrLv):
svg = d3.select('body')
.append('svg')
.attr('width', 640)
.attr('height', 480);
svg.selectAll('text')
.data( modified_data )
.enter()
.append('text')
.attr('x', 10)
.attr('y', function( d, i ) {
return 20 + i * 20;
})
.html(function(d) {
return d.letters.map((letter,index) => {
if (['a', 'e', 'i', 'o', 'u', 'y'].includes(letter)){
return '<tspan class="vowel">' + letter + '</tspan>';
} else{
return '<tspan>' + letter + '</tspan>';
}
}).join("");
})
.attr('class', function( d, i ) {
for (letter of d.letters){
console.log('letter', letter);
if (['a', 'e', 'i', 'o', 'u', 'y'].includes(letter)) {
return 'strong';
}
}
})
.exit();
Note the use of the .html()
function and then .map()
within that using our current data.letters in the normal update pattern to add either '<tspan class="vowel">'
or '<tspan>'
(no class vowel).
https://codepen.io/Alexander9111/pen/qBdZrLv
But I am not sure if you want such a specific use case or a more general answer to the nested update pattern? If so then maybe this block helps? - https://bl.ocks.org/mpbastos/bd1d6763d34ac5d3ce533a581b291364
UPDATE - I realize I misread the question the first time
So it is now clear to me that my one-time solution is no more helpful than the other two solutions suggested by @Fabien (OP) (Moving the line up (before the second data()) or Using a separate statement svg.selectAll('text').attr('class', 'strong');
)
I tried patterns such as:
svg.selectAll('text')
.data( test_data )
.enter()
.append('text')
.attr('x', 10)
...
.selectAll('tspan')
.data( ...)
.enter()
.append('tspan')
.attr('class', 'example')
.exit()
.select(this.ParentNode)
.attr('class', 'example')
And also with the .select(this.ParentNode)
before the .exit()
but neither worked.
The only thing that works but it is also a workaround and probably an anti-pattern is this - hijack the attr function to "grab" parent outside nested update :
svg = d3.select('body')
.append('svg')
.attr('width', 640)
.attr('height', 480);
text = svg.selectAll('text')
.data( test_data )
.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(1, i, this.parentNode);
//hijack the attr function to "grab" parent outside nested update pattern
if (i == 0) {
d3.select(this.parentNode).attr('class', 'strong');
}
//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();
This is also not a beautiful solution.
I think because once the .data()
function is called on a selection, it is now longer a normal node list object, and the .exit()
function is only designed to be used one layer deep.
I think the two solutions the OP outlined are the best, but I would love to be proven wrong!
Source: stackoverflow.com
Related Query
- How to get out of nested selectAll in D3JS?
- How to get reference to SVG (child) elements nested in another SVG element (parent) using D3?
- How to get started with d3js examples using xampp?
- How to get axis ticks out of d3 without rendering in SVG?
- D3js : How to get the real bounding box of features crossing the anti-meridian?
- d3: How to append nested elements on enter()? My elements get appended, but subsequent select doesn't see them
- How should i use nested data in d3js
- How to get data from d3js polyline?
- How to get a single property of all children in a nested object using javascript?
- d3js v4 - Brush precision, how to get millis
- Get group from D3js selectAll in console?
- D3JS how to get the y postition with bisector?
- How to get value of bar in d3js bar chart
- d3js brush how to get values for selection
- d3js how to get rotated rect's corner coordinates?
- How to get parent node from child in json using d3js as Force Layout?
- How to get a value from a nested object in a GeoJson object in d3js?
- How to access nested data in D3js
- How to properly get data from a d3.js nested array
- how to get rid of overlap line graph in d3js
- how i get height of a svg element using d3js
- D3.js: How to get the computed width and height for an arbitrary element?
- How to get coordinates of an svg element?
- How to get data of parent node in d3.js
- How to use D3 selectAll with multiple class names
- How do I get the width of an svg element using d3js?
- How to find the max/min of a nested array in javascript?
- How to get absolute coordinates of object inside a <g> group?
- Get one element from d3js selection, by index
- How can I get the D3.js axis ticks and positions as an array?
More Query from same tag
- Code flow through callback in java script
- Dimple Specific Axis Variable Value
- D3 pie chart labels and value inside
- d3.js dynamic style filling only displays black bar chart
- How can I make the animation of a circle continous with hovering like this gif in d3.js?
- Array of objects javascript
- Percentage Change in dc.js/crossfilter
- Switch JSON file for a visualisation using a dropdown
- Unexpected token u in JSON at position 0 when try parse JSON
- d3: Avoid unchanged nodes?
- draw multiple lines in line chart dynamically
- position nodes in force layout graph vertically
- Is there a way to zoom in to the centre of an object in d3?
- Use Json file for d3.js-graph
- Are directed graphs only possible with files that contains a "source" and "target" value?
- Change default node shape in dagre-d3
- Nearest neighbor search in D3
- Auto width and height for SVG image
- First d3 transition on update inside interval is not transitioning
- d3.drag() in Angular2
- How do I display text for touch events in D3.js?
- d3.js - define grid line style with javascript
- 3 dimension (X, Y and Z) graph using D3.js
- D3 - Stacked bar chart, position bars
- How to use pack.sort() function in D3 circle pack?
- adding text values into a circle in html page using JS
- D3.js unknown number of columns and rows
- Multiline chart x-axis ticks not aligned with data points
- Bootstrap modal doesn't pop up when a node is clicked
- D3 force-directed: why transform-translate tick is required when displaying labels