|
|
|
|
|
by mgold
4050 days ago
|
|
D3 has nested selections that let you handle cases like this. The data for a single element can be an array, and if that element is a div (HTML) or g (SVG) you can do another join and bind those data to its children. More info: http://bost.ocks.org/mike/nest/ To "substitute the objects with new ones", do another join, pass a key function as the second argument if necessary, and use the enter/update/exit pattern. |
|
And key functions are non-trivial to create if 1. you use d3.nest[2] (not to be confused with nested selections) 2. you modify the data in a way that changes the grouping 3. you try to match existing nodes back to the changed groupings. Key-based computation is insufficient for dynamically matching DOM nodes to changing sets.
Those two things aren't showstoppers. They just make the data-binding fairly brittle.
The thing that it's bound to a non-namespaced __data__ property is more problematic in my opinion since you always have to pay attention to not overwrite the datum with a different selection on any DOMnode, otherwise you will break callbacks that rely on the data. It basically requires a 1:1 correspondence for DOM to data on the whole subtree.
This makes decomposing the selections into separate steps difficult. I.e. building a base tree and then populating the leaves with a separate data set can easily end up overwriting the data bindings of the base tree. Again, it's possible to avoid these pitfalls but if __data__ had been namespaced it would be far less hazardous.
[1] https://github.com/mbostock/d3/issues/2034 [2] https://github.com/mbostock/d3/wiki/Arrays#-nest