我现在已经找了3个多小时试图找到一种无限期地链接过渡的方法......
我唯一的解决方案是将代码包装在一个函数中,然后使用setInterval重复调用该函数或等待转换'end'事件
示例一个班轮:
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)
答案 0 :(得分:0)
无论如何,我认为您必须将转换设置包装在一个函数中,以便您可以递归调用它。但是,@ Jun 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()
方法(为整个转换对象调用一次函数),但是目前无法延迟该调用。在转换结束时,重复的子转换调用被添加到队列中,直到控制台发出错误,其后面有一个巨大的堆栈跟踪。奇怪的是,它看起来并没有出现任何问题,因为所有排队的转换仍然在顺利进行 - 但它们最终会用完转换。
每个/最终方法 - 使用原始选择上调用的递归函数 - 替换完成的转换而不是链接到它,因此它可以无限期地继续而不会消耗增加的资源。