【问题标题】:d3 v5: How to transition only when a specific attribute changed?d3 v5:如何仅在特定属性更改时进行转换?
【发布时间】:2019-11-16 06:12:53
【问题描述】:

我有一张地图,每个国家的中心都有一个圆圈。在 Mike Bostock 的 general update pattern 之后,我应用了一个动画,每 3 秒更新一次圆圈。但是,我的问题是我想对保留在图表中的旧元素应用过渡(即不是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;
                            }
                        })

【问题讨论】:

    标签: javascript d3.js transition


    【解决方案1】:

    好的,解决方案有点直截了当(我是盲人......)。

    我没有为单个元素使用 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) {
        ...
    
    

    【讨论】:

    • 有没有 jsfiddle,这有点像我要找的东西?
    • 主属性是什么?您是否存储了一些值以供以后检查?请分享jsfiddle
    • @HarshaVardhan 为了使帖子保持简单,我专注于处理更新模式的代码。实际上,我的原始代码更复杂,不包含实际的“主要”属性,它只是用来强调它对问题的重要性。我没有时间提供小提琴。但是main 属性可以看作是对象列表的一部分,从每个对象代表一个国家的数据库中检索:[{country: "Albania", main: "5", ...},{country: "Armenia", main: "3", ...}, ....]
    猜你喜欢
    • 2021-10-21
    • 1970-01-01
    • 1970-01-01
    • 2021-11-22
    • 1970-01-01
    • 2020-07-31
    • 1970-01-01
    • 1970-01-01
    • 2018-02-22
    相关资源
    最近更新 更多