I have a map with a circle at the center of each country. I apply an animation that updates the circles every 3 seconds, following the general update pattern by Mike Bostock. However, my problem is that I want to apply a transition to old elements that stay in the chart (ie are not part of the exit()
), but only for those that have a change in a particular attribute (because this attribute defines the color of the circle). I figured that I should store the old value as an attribute in the circle and then just compare this attribute value with the newly assigned value from the updated data.
However, when I use a usual js if
clause it only provides me with the first element, which means when this circle's value changes, all other circles will get the transition as well.
How can I check between the old and the new value inside this pattern?
Here is a sample code:
//DATA JOIN
var countryCircles = circleCont.selectAll(".dataCircle")
.data(filData, function(d){ return d.id})
//EXIT OLD CIRCLES THAT ARE NOT INCLUDED IN NEW DATASET
countryCircles.exit()
.transition()
.ease(d3.easeLinear)
.duration(500)
.attr("r",0)
.remove()
//CHECK IF OLD CIRCLES THAT ARE INCLUDED CHANGED THE CRITICAL ATTRIBUTE VALUE (main)
if (countryCircles.attr('main') != countryCircles.data()[0].main) {
countryCircles
.attr("main", function(d) {return d.main})
.attr("id", function(d) {return "circle" + d.id})
.attr("class","dataCircle")
.transition()
.ease(d3.easeLinear)
.duration(500)
.ease(d3.easeLinear)
.attr("r",0)
.transition()
.duration(500)
.ease(d3.easeLinear)
.attr("r",10)
.style("fill", function(d) {
if (d.main === "nodata") {
return "grey"
} else {
return color_data.find(function (y) {
return y.main === d.main;
}).color;
}
})
} else {
countryCircles
.attr("main", function(d) {return d.main})
.attr("id", function(d) {return "circle" + d.id})
.attr("class","dataCircle")
}
//CREATE CIRCLES THAT ARRE NEW IN THE UPDATED DATASET
var newCircle = countryCircles.enter()
.append("circle")
.attr("class","dataCircle")
.attr("cx", getCX)
.attr("cy", getCY)
.attr("id", function(d) {return "circle" + d.id})
.attr("main", function(d) {return d.main})
.style("cursor","crosshair")
.attr("r", 0)
.transition()
.delay(500)
.duration(500)
.ease(d3.easeLinear)
.attr("r",10)
.style("fill", function(d) {
if (d.main === "nodata") {
return "grey"
} else {
return color_data.find(function (y) {
return y.main === d.main;
}).color;
}
})
OK, the solution was somewhat straight forward (and I was blind...).
Instead of having the if statement for a single element, I use the each()
function and within there check for a change.
...
//CHECK IF OLD CIRCLES THAT ARE INCLUDED CHANGED THE CRITICAL ATTRIBUTE VALUE (main)
countryCircles.each(function(d) {
if (d3.select(this).attr('main') != d3.select(this).data()[0].main) {
...
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.