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

时间:2019-07-05 15:39:00

标签: javascript d3.js transition

我在每个国家的中心都有一张带有圆圈的地图。我应用了动画,该动画每3秒更新一次,紧随Mike Bostock的general update pattern之后。但是,我的问题是,我想对保留在图表中的旧元素(即不属于exit()的元素)应用过渡,但仅适用于对特定属性进行了更改的元素(因为此属性)定义圆圈的颜色)。我认为应该将旧值作为属性存储在圆圈中,然后将这个属性值与更新后的数据中新分配的值进行比较。

但是,当我使用普通的js if子句时,它仅向我提供第一个元素,这意味着当该圆的值更改时,所有其他圆也将获得过渡。

如何在此模式中检查新旧值?

这是示例代码:

//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;
                            }
                        })

1 个答案:

答案 0 :(得分:2)

好的,解决方案有些直截了当(我是瞎子...)。

我没有使用单个元素的if语句,而是使用 ptra 100 +-----+ +---+ | 200 | | 1 | +-----+ +---+ ptrb 200 +-----+ +---+ |100 | | 2 | +-----+ +---+ 函数并在其中检查更改。

[Delicarta]
A=55
B=80