score:5

Accepted answer

What you put in the selectAll() call before the call to .data() really only matters if you're changing/updating what's displayed. Imagine that you have a number of circles already and you want to change their positions. The coordinates are determined by the data, so initially you would do something like

svg.selectAll("circle")
   .data(data)
   .enter()
   .append("circle")
   .attr("cx", function(d) { return d; })
   .attr("cy", function(d) { return d; });

Now your new data has the same number of elements, but different coordinates. To update the circle positions, all you need to do is

svg.selectAll("circle")
   .data(newData)
   .attr("cx", function(d) { return d; })
   .attr("cy", function(d) { return d; });

What happens is that D3 matches the elements in newData to the existing circles (what you selected in selectAll). This way you don't need to append the circles again (they are there already after all), but only update their coordinates.

Note that in the first call, you didn't technically need to select circles. It is good practice to do so however just to make clear what you're trying to do and to avoid issues with accidentally selecting other elements.

You can find more on this update pattern here for example.


Related Query