In the answer Mike posted here, he overviews three different ways to apply a change to a matched element based on a index or custom filter. I'm trying to clarify, hopefully for more people than just myself, the actual selections in these solutions.
So given a document with 6 SVG rects with class .bar
, we have these different selections and what they return:
d3.select(".bar"):
[Array[1]
0: rect.[object SVGAnimatedString]
length: 1
parentNode: html
__proto__: Array[0]
d3.selectAll(".bar"):
[Array[6]
0: rect.[object SVGAnimatedString]
1: rect.[object SVGAnimatedString]
2: rect.[object SVGAnimatedString]
3: rect.[object SVGAnimatedString]
4: rect.[object SVGAnimatedString]
5: rect.[object SVGAnimatedString]
length: 6
parentNode: html
__proto__: Array[0]
$(".bar"):
[
<rect class="dataBars" x="53.191489361702125" width="212.7659574468085" y="4.761904761904762" height="11.11111111111111"></rect>,
<rect class="dataBars" x="74.46808510638297" width="372.3404255319149" y="20.634920634920636" height="11.11111111111111"></rect>,
<rect class="dataBars" x="127.6595744680851" width="212.7659574468085" y="36.507936507936506" height="11.11111111111111"></rect>,
<rect class="dataBars" x="31.914893617021274" width="212.7659574468085" y="52.38095238095238" height="11.11111111111111"></rect>,
<rect class="dataBars" x="159.5744680851064" width="265.9574468085106" y="68.25396825396825" height="11.11111111111111"></rect>,
<rect class="dataBars" x="234.04255319148936" width="138.29787234042553" y="84.12698412698413" height="11.11111111111111"></rect>,
]
Now here's where it get's more tricky (for me at least), say I want to apply a style
to the 3rd rectangle, this rectangle can be found using
d3.selectAll(".bar")[0][2]
But if we want to then use the d3.selection.attr()
, that returns
TypeError: Property 'style' of object #<SVGRectElement> is not a function
But we can then wrap this selection
d3.select(d3.selectAll(".bars rect")[0][2]).style("fill", "red")
and this will work as expected.
Then, if we want to apply a filter, such as
filter(function (d) { return d === 5 || d === 15;}
the d3.selectAll(".bar")
must be used, and d3.select(d3.selectAll(".bar"))
will not work correctly.
I've read Mike's excellent tutorials and documentation on selections, but just when I think I have it figured out, something pops up and surprises me. So what is the difference between these selections, and how do I know which one to use when? Thank you very much, and sorry for the long post!