Accepted answer

You shouldn't feel dumb — I think everyone who uses d3 does this at some point (me repeatedly).

What's happening is that enter() is returning the selection made when you add data. Everything you chain after enter() will be called on the appended circle created with the enter() selection. That's why your first example works.

When you break chain however, you are now calling attire() on the original selection, which won't work. It's equivalent to doing this:

const circles = svg.selectAll('circle').data(data)
.attr("cx", function (d) { return ( xScale(d.x) )})
.attr("cy", function (d) { return d.y});

To separate them you need to make a new selection:

.attr("cx", function (d) { return ( xScale(d.x) )})
.attr("cy", function (d) { return d.y});

This is a nice way to separate things that will need to be updated.

p.s. I think the reason the youtube video works is because he's using the old version of D3. In the new version, selections are immutable. See the first section here:

Related Query

More Query from same tag