What is the difference between select() and selectAll()?
Why doesn't the second one append a p tag?
divSelection = d3.select('#div-vis').selectAll('p').data(['dummy']).enter().append('p');
divSelection = d3.select('#div-vis').select('p').data(['dummy']).enter().append('p');
What is the difference between select() and selectAll()?
Why doesn't the second one append a p tag?
divSelection = d3.select('#div-vis').selectAll('p').data(['dummy']).enter().append('p');
divSelection = d3.select('#div-vis').select('p').data(['dummy']).enter().append('p');
Share
Improve this question
edited Mar 2, 2018 at 15:03
CommunityBot
11 silver badge
asked Oct 23, 2012 at 9:09
user1767809user1767809
1311 silver badge3 bronze badges
2 Answers
Reset to default 18From Nested Selections:
Nesting selections has another subtle yet critical side-effect: it sets the parent node for each group. The parent node is a hidden property on selections that determines where to append entering elements. … There is an important difference between select and selectAll: select preserves the existing grouping, whereas selectAll creates a new grouping. Calling select thus preserves the data, index and even the parent node of the original selection!
When you say d3.select("#vis")
, the parent node of the selection is still the document element. When you then say selectAll("p")
, you define the parent node as the previously-selected #vis element, because selectAll is a nesting operator. That only happens with selectAll and not select.
In this HTML document:
<html>
<body>
<div id="viz">
</div>
<body>
</html>
Applying this code:
var viz = d3.select('#viz').selectAll('p').data([0])
.enter().append('p');
Gives this result:
<html>
<body>
<div id="viz">
<p></p>
</div>
<body>
</html>
This is because selectAll()
defines a parent element based on the preceding select
method, which is select('#viz')
. In that way:
console.log(viz[0].parentNode) // <div id="viz">
Whereas if you execute the following code in the first HTML document:
var viz = d3.select('#viz').select('p').data([0])
.enter().append('p');
It gives you this result:
<html>
<body>
<div id="viz">
</div>
<body>
<p></p> <!-- your p element is appended to <html> as its parent element
</html>
Since a selectAll()
is required to redefine your selection's parent element, the parent element of your selection is still <html>
which is set by default. If we log the selection's parent node:
console.log(viz[0].parentNode) // <html>
Remember that selections are arrays (groups) of arrays of elements. Writing viz[0]
gets the first group of elements, not the first element of your selection. To obtain the first element you should write:
console.log(viz[0][0].parentNode)
Which will give you the parent element of that specific element in the DOM tree, not in your d3 selection group.