(D3)数据驱动文档 - 转换重复

时间:2014-01-19 00:09:20

标签: d3.js transition data-driven

我现在已经找了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)

1 个答案:

答案 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()方法(为整个转换对象调用一次函数),但是目前无法延迟该调用。在转换结束时,重复的子转换调用被添加到队列中,直到控制台发出错误,其后面有一个巨大的堆栈跟踪。奇怪的是,它看起来并没有出现任何问题,因为所有排队的转换仍然在顺利进行 - 但它们最终会用完转换。

每个/最终方法 - 使用原始选择上调用的递归函数 - 替换完成的转换而不是链接到它,因此它可以无限期地继续而不会消耗增加的资源。