d3: confusion about selectAll() when creating new elements

d3.js, html, javascript

Solution

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 `circle`s. 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.

Problem

I am new to d3 and am using 'Interactive Data Visualization for the Web' by Scott Murray (which is great btw) to get me started. Now everything I saw so far works as described but something got me confused when looking at the procedure to create a new element. Simple example (from Scott Murray): ``` svg.selectAll("circle") .data(dataset) .enter() .append("circle"); ``` The name `"circle"` is used for the `selectAll` which returns an empty selection (which is ok as I learned). Then circles are appended by putting the same name into the `.append`. Great! Now what got me confused was what happens when you want to do the same thing again. So you have a second dataset and want to generate new circles in the same way. Using the same code just replacing the dataset will obviously not work as the `selectAll("circle")` will not return an empty selection anymore. So I played around and found out that I can use any name in the `selectAll` and even leave it empty like this: `selectAll()` Scott Murrays examples always just use one type (circle, text, etc.) per dataset. Finally I found in the official examples something like ``` svg.selectAll("line.left") .data(dataset) .enter() .append("line") .attr ... svg.selectAll("line.right") .data(dataset) .enter() .append("line"); .attr ... ``` Now my question: How is this entry in `selectAll("ENTRY")` really used? Can it be utilized later to again reference those elements in any way or is it really just a dummy name which can be chosen in any way and just needs to return an empty selection? I could not find this entry anywhere in the resulting DOM or object structure anymore. Thank you for de-confusing me.

Original source