简体   繁体   English

d3 v5:仅在特定属性更改时如何过渡?

[英]d3 v5: How to transition only when a specific attribute changed?

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. 我按照Mike Bostock的常规更新模式 ,应用了每3秒更新一次圆圈的动画。 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). 但是,我的问题是,我想对保留在图表中的旧元素(即不属于exit()元素)应用过渡,但仅适用于那些对特定属性进行了更改的元素(因为此属性定义了圆圈的颜色)。 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. 但是,当我使用通常的js if子句时,它仅为我提供第一个元素,这意味着当该圆的值更改时,所有其他圆也将获得过渡。

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. 我没有使用单个元素的if语句,而是使用each()函数并在其中检查更改。

...
//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) {
    ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM