I'm trying to get the values for x
and y
to make a circles using d3.js v4. With the following code I manage to create the chart like behavior of the circles, but when I try to run the same code in v4 it doesn't work anymore. I know that there are some differences in the update to v4 but I didn't find any information about it. So i was wondering if someone can help me to run this code in d3.js v4.
Here is the code using v3 (it will break using v4):
var svg = d3.select('body').append('svg')
.attr('width', 250)
.attr('height', 250);
//render the data
function render(data) {
//Bind
var circles = svg.selectAll('circle').data(data);
//Enter
circles.enter().append('circle')
.attr('r', 10);
//Update
circles
.attr('cx', function(d) {
return d.x;
})
.attr('cy', function(d) {
return d.y;
});
//Exit
circles.exit().remove();
}
var myObjects = [{
x: 100,
y: 100
}, {
x: 130,
y: 120
}, {
x: 80,
y: 180
}, {
x: 180,
y: 80
}, {
x: 180,
y: 40
}];
render(myObjects);
<script src='https://d3js.org/d3.v3.min.js'></script>
This is the expected behaviour, and I've explained this before in this answer (not a duplicate, though).
What happened is that Mike Bostock, D3 creator, introduced a magic behaviour in D3 v2, which he kept in D3 v3.x, but decided to abandon in D3 v4.x. To read more about that, have a look here: What Makes Software Good? This is what he says:
Let's see it.
Here is your code with D3 v3:
Now the same code, with D3 v4. It will "break":
By "break" I mean the circles will be appended, but they will not receive the
x
andy
properties in the "enter" selection, and they will default to zero. That's why you see all circles at the top left corner.Solution: merge the selections:
According to the API,
merge()
...Here is the code with
merge()
:Update pattern was changed in d3v4. Excerpt from the documentation:
You should rewrite your code this way: