0

我已经寻找了超过 3 个小时,现在试图找到一种无限期链接转换的方法......

我唯一的解决方案是将代码包装在一个函数中,然后使用 setInterval 重复调用该函数或等待转换“结束”事件

示例一班轮:

d3.selectAll('circle').data([1,2,3]).enter().append('circle').attr('cy':function(d){return d * 100},'cx':function(){Math.random() * window.innerWidth},'r':'10px')

//sets initial locations for circles that are created to match data array

.transition().attr('cy':function(){Math.random() * window.innerHeight},'cx':function(){Math.random() * window.innerWidth}})
.transition().attr('cy':function(){Math.random() * window.innerHeight},'cx':function(){Math.random() * window.innerWidth}})
.transition().attr('cy':function(){Math.random() * window.innerHeight},'cx':function(){Math.random() * window.innerWidth}})
.transition().attr('cy':function(){Math.random() * window.innerHeight},'cx':function(){Math.random() * window.innerWidth}})
.transition().attr('cy':function(){Math.random() * window.innerHeight},'cx':function(){Math.random() * window.innerWidth}})

//I'm looking for something that can repeat the transition without using setInterval)
4

1 回答 1

0

无论如何,我认为您将不得不将转换设置包装在一个函数中,以便您可以递归调用它。但是,@Jon S. 是对的,您可以使用转换的“结束”事件而不是单独的计时器。

transition.each("end", callback)复杂之处在于(正如方法名称所暗示的那样)为数组中的每个元素调用回调函数。一个简单的检查可以确保递归只发生一次,对于第一个元素,并且不会无限分支。

这是一个例子: http: //fiddle.jshell.net/UD9ng/1/

关键代码:

var moving = false;

function move(selection) {

    moving = true;
    selection.transition().duration(5000).ease("sin-in-out")
        .attr("cx", function(){return Math.random()*width;})
        .attr("cy", function(){return Math.random()*height;})
        //.call(move); //stack overflow error!
        .each("end", function(d,i){ 
            if (!i) circles.call(move); //only run for i==0
        });

}

正如您从评论中看到的那样,我尝试使用转换的.call()方法(它为整个转换对象调用一次函数),但目前没有办法将该调用延迟到转换结束,因此重复子转换调用被添加到队列中,直到控制台吐出一个错误,后面有一个巨大的堆栈跟踪。奇怪的是,它看起来并没有什么问题,因为所有排队的过渡仍在顺利进行——但最终它们会用完过渡。

each/end 方法——在原始选择上调用递归函数——替换完成的转换而不是链接到它,因此它可以无限期地继续而不会消耗更多的资源。

于 2014-01-19T03:43:56.560 回答