我已经设置了一个带有过渡的 D3 圆形动画。我使用最小日期作为初始数据点,使用最大日期作为过渡的最终数据点。我的问题是:
我正在使用一个相当大的数据集,恐怕因为我只是告诉转换从最小值到最大值,它会错过中间的所有其他点,例如如果圆圈 A 有一个疯狂的跳跃怎么办之间?当我对其进行测试时,它似乎只是跳过了跳跃。
有没有更好的方法来设置过渡以考虑介于两者之间的所有点?
我已经设置了一个带有过渡的 D3 圆形动画。我使用最小日期作为初始数据点,使用最大日期作为过渡的最终数据点。我的问题是:
我正在使用一个相当大的数据集,恐怕因为我只是告诉转换从最小值到最大值,它会错过中间的所有其他点,例如如果圆圈 A 有一个疯狂的跳跃怎么办之间?当我对其进行测试时,它似乎只是跳过了跳跃。
有没有更好的方法来设置过渡以考虑介于两者之间的所有点?
如果您告诉对象从 min 转换为 max,它将仅尊重这两个值,并且正如您所说,它将跳过其间的任何有趣的跳跃。
我猜你目前通过推入所有数据来绘制一次图表。相反,您可以逐步将数据推送到图表:
var data = [{id: o1, v: []}, {id: o2, v: []}]; // values for 2 objects
function getTransform(d) {
return "translate(" + d.v[d.v.length-1] + ")";
}
function update() {
var elems = d3.selectAll(...).data(data, function(d) {return d.id;})
elems.enter()
.append(...) //append DOM/SVG objects and
.attr(...) //initalize their start values and
.attr("transform", getTransform ) //their start animation values
// animate the existing elements to move to their new values
elems.transition().attr("transform", getTransform )
}
function play(){
// pushing in "crazy" values
data[0].v.push( Math.random()*10 );
data[1].v.push( Math.random()*10 );
update();
}
setTimeout(play, 500)
setTimeout(play, 1000)
setTimeout(play, 1500)
基本思想是不要一次将所有数据扔到 d3 中,而是按照您希望它动画化的顺序和及时性添加数据。
此外,或者您可以设置时间索引并在getTransform
函数中使用它来动画到您想要的任何状态。如果您逐步执行此操作,则可以使动画使用您的“疯狂”值。
var time = 0;
var maxTime = 2;
function getTransform(d) {
return "translate(" + d.v[time] + ")";
}
function next(){
update();
if(time++ < maxTime) setTimeout(next, 500)
}
play(); play(); play(); // add some data ;)
next() // start index based playback from `time` to `maxTime`
您可能需要将超时值500
与您想要的动画duration(..)
速度相匹配,以使动画达到您的疯狂峰值。否则 d3 可能会平滑动画路径(如果更新速度比动画快)。