【问题标题】:D3: Add element after delay, then transitionD3:延迟后添加元素,然后过渡
【发布时间】:2014-02-14 20:58:44
【问题描述】:

我有一个非常大的 csv 文件,我正在使用 D3.js 对其进行可视化。其中一个数据字段是时间戳,因此(而不是一次显示所有这些信息)我想在与时间戳成比例的延迟后创建一个 svg 元素(基于其他数据字段),然后将其淡出三个秒。由于数据的大小,我无法预先创建所有元素,即使它们是不可见的;每个元素应该只存在三秒钟。想要的效果是一堆点突然出现然后消失。

我的最佳尝试如下。该策略是使用两个转换:延迟,然后是淡入淡出转换。它似乎不起作用,而是一次创建了所有元素(尽管褪色起作用)。

d3.csv(datafile).get(function(error, rows) {
        for (var i = rows.length; i--;){
                var d = rows[i];
                plot.select("foo") // empty selection
                    .transition()
                    .delay(/*expression with d.timestamp*/)
                    .call(function(){
                        plot.append("circle")
                            .attr(/*several, snip */)
                            .style("opacity", 1)
                            .transition()
                            .duration(3000)
                            .style("opacity", 0)
                            .remove()
                    });
        }

    });

2015 年 4 月编辑 自从提出这个问题以来学到了很多东西,显而易见的事情似乎是立即以 0 不透明度插入所有内容。然后创建一个持续时间为 0 的可变延迟过渡以捕捉到 1 不透明度,然后从那里淡出。还使用嵌套选择来避免显式 for 循环。我还没有尝试过,但它应该工作。

【问题讨论】:

    标签: d3.js


    【解决方案1】:

    您是否尝试过使用 setTimeout 代替?

            rows.forEach(function(d, i){
                setTimeout(function(){
                        plot.append("circle")
                            .attr(/*several, snip */)
                            .style("opacity", 1)
                            .transition()
                            .duration(3000)
                            .style("opacity", 0)
                            .remove()
                }, /*expression with d.timestamp*/);
            })
    

    【讨论】:

    • 不怕。在 for 循环中运行时,重置 d 会破坏回调的闭包。想不出解决方法,但可能有一个。
    • 您必须将整个事物包装在一个函数中以创建一个新范围。在此范围内,我已对您的答案进行了修改。
    • 您必须接受更改,此时我可以接受答案。
    • 审稿人在我看到之前拒绝了编辑(叹气),我不知道如何接受它。我编辑使用 forEach 进行迭代,这也解决了问题。
    • 我今天找到的最佳答案? 谢谢@AdamPearce
    【解决方案2】:

    我知道这已经过时了,但我遇到了同样的问题并试图通过承诺来解决它,然后找到了一个比我做得更好的解决方案。

    The full post is here

    const sleep = (milliseconds) => {
      return new Promise(resolve => setTimeout(resolve, milliseconds))
    }
    

    然后

    sleep(500).then(() => {
      //do stuff
    })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-10
      • 2018-09-28
      相关资源
      最近更新 更多