Reputation: 29129
I want to create a list using D3 using the following data:
var dataSet = [
{ label: 'a', value: 10},
{ label: 'b', value: 20},
{ label: 'c', value: 30},
{ label: 'd', value: 40}
];
var circle = svg.selectAll('circle')
.data(dataSet)
.enter()
.append('circle')
.attr({
r:function(d){ return d.value },
cx:function(d, i){ return i * 100 + 50 },
cy:50,
fill: 'red'
});
Which works. Now after some time, I change the data
dataSet[0].value = 40;
dataSet[1].value = 30;
dataSet[2].value = 20;
dataSet[3].value = 10;
and I would like to draw the list again:
setTimeout(function () {
var circle = svg.selectAll('circle')
.data(dataSet, function (d) {
return d.label;
})
.sort(function (a,b){ return d3.ascending(a.value, b.value);})
.enter()
.append('circle')
.attr({
r:function(d){ return d.value },
cx:function(d, i){ return i * 100 + 50 },
cy:50,
fill: 'red'
});
},1000);
However, this list is not really updated. Any suggestions how to fix this ?
Upvotes: 0
Views: 317
Reputation: 109232
The problem is that you're handling only the enter selection, which will be empty on update -- you need to handle the update selection:
svg.selectAll('circle')
.data(dataSet, function (d) {
return d.label;
})
.sort(function (a,b){ return d3.ascending(a.value, b.value);})
.transition()
.attr({
r:function(d){ return d.value },
cx:function(d, i){ return i * 100 + 50 },
cy:50,
fill: 'red'
});
Updated fiddle here. For more information on the different selections, have a look at this tutorial.
Upvotes: 1
Reputation: 848
This can be accomplished by removing the existing circles first by calling:
svg.selectAll('circle').remove()
and then going through adding them again with different data set. I updated your fiddle http://jsfiddle.net/Q5Jag/1183/
Hope this helps.
Here is same fiddle with some enter and exit animations http://jsfiddle.net/Q5Jag/1184/
Upvotes: 1