In d3 v3, selectAll returned an array, in d3 v4 it returns an object.
From note v3 :
Choices are arrays of elements - literally (maybe not literally ...). D3 associates additional methods with an array so that you can apply operators to selected elements, such as setting an attribute on all selected elements.
Where as a change in v4 includes:
Choosing to no longer subclass Array using prototype chain injection; they are now simple objects that improve performance. Internal fields (selection._groups, selection._parents) are private; Use the documented public API for election management. The new selection.nodes Method generates an array of all nodes in the selected item.
If you want to access each node in v4, try:
selection.nodes().forEach( function(d,i) { ... })
But this is just a node to get the data you need to select each node:
var data = [0,1,2]; var svg = d3.select("body").append("svg") .attr("width",500) .attr("height",200) var circles = svg.selectAll("circle") .data(data) .enter() .append("circle") .attr("cx", function(d,i) { return i * 20 + 50 }) .attr("cy", 50) .attr("r", 4); circles.nodes().forEach(function(d,i) { console.log(d3.select(d).data()); })
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
But, if you need data or change selection properties, it would be easier to use selection.each (). d3.each iterates through each element of the d3 selection itself and allows you to call a function for each element in the selected fragment (see the API docs here ):
var data = [0,1,2]; var svg = d3.select("body").append("svg") .attr("width",500) .attr("height",200) var circles = svg.selectAll("circle") .data(data) .enter() .append("circle") .attr("cx", function(d,i) { return i * 20 + 50 }) .attr("cy", 50) .attr("r", 4); circles.each( function() { console.log(d3.select(this).data()); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
In v3 of this histogram in a forEach loop
`states.selectAll("rect").forEach(function(d,i) {`
d - an array of nodes (rectangles in each .g ).
But in v4 variants d3 are not arrays, you cannot use the forEach loop in the same way. But you can still get the nodes in it without significant changes using selection.nodes() , and then get childNodes to replicate the array in v3:
state.nodes().forEach(function(d, i) { var nodes = d.childNodes;
Here we look at each element / node in state and get the child element rect s returned as an array. Here's the updated fiddle .