bambooom - 9 months ago 50

CSS Question

I'm learning

`D3.js`

`svg.selectAll("circle")`

.data([32, 57, 112, 293])

.enter().append("circle")

.attr("cy", 60)

.attr("cx", function(d, i) { return i * 100 + 30; })

.attr("r", function(d) { return Math.sqrt(d); });

After binding the data, entering the element and appending one more

`circle`

`circle`

I hereby attached the codepen.

Is this behaviour normal or do I misunderstand something?

Answer

Yes, this is the normal behaviour. Here is your problem: you already have 3 circles in the SVG. So, when you bind the data, your "enter" selection has just one circle (the fourth one), and all the attributes are being set only for this last circle.

The enter/update/exit selections are based on the relationship between data and elements. When you bind your data (the 4 numbers in the array), you already have 3 elements in the SVG. Thus, you have:

Enter selection: data not corresponding to any element. In your case, 1 circle.

Update selection: data corresponding to an element. In your case, 3 circles.

Exit selection: element not corresponding to any data. In your case, zero circles.

To redraw all the 4 circles (3 previous and one new), you have to do something like this:

```
var svg = d3.select("svg");
var myCircles = svg.selectAll('circle')
.data([32, 57, 112, 293]);//binds the data
myCircles.enter().append("circle");//enter selection
myCircles.attr("cy", 60)
.attr("cx", function (d, i) {
return i * 100 + 30;
})
.attr("r", function(d) {
return Math.sqrt(d);
});//updates all circles
```

Doing this way, you set the attributes both for the "enter" and the "update" selections. Here is your updated Pen (I put a setTimeout of 1 second, just for you to see the original 3 circles before the change): http://codepen.io/anon/pen/vKxZxX

Please note that I'm not comparing your code with Bostock's tutorial, or saying what you did "wrong". I'm simply explaining why your code doesn't update the 4 circles.