我试图用d3.js生成一些动画。我对动画本身并没有太多问题(我正在使用补间功能,似乎我已经理解了基础知识),但随着值的更新,应该来自我定期阅读的json文件。
基本上:
d3.json(filename, function(error, json) {
if (error) {
console.log(error);
return;
}
callback(json);
});
在回调函数中,我尝试获取旧数据和新数据之间的差异,并准备补间中需要的相应插值函数(如果某个值已从0更改为10,我准备一个函数这个范围)。
我的大部分插值函数都类似于(如您所见,您需要指定旧数据和新数据):
d3.interpolate(old, new),
d3.interpolateRgb(oldColor, newColor),
之后,我选择一些元素(我需要设置动画),在差异集合中查找,如果定义了插值函数,则执行动画。
someElements
.transition()
.duration(Dashboard.settings.timers.animationTime)
.tween("d", function() {
return function(t) {
var data = lookupOnCollectionById(this.__data__.id, changes);
if (data.interpolationFunctions !== undefined) {
//Perform animation
}
};
这很有效,而且运行正常。问题是,我理解d3.js背后的概念(或其中之一)是让动画由数据驱动。我所做的基本上就是自己完成这个过程,只需使用框架来渲染"。
据我所知,在每个选择中,我都准备好将数据元素与绑定数据一起使用,但显然我没有"之前的"数据。我不确定这是否必须完成,因为我正在做或者我可能重新发明轮子。 d3.js有一些已经存在的机制来处理数据变化吗?。
非常感谢!
答案 0 :(得分:4)
如果您有一个在加载新数据时运行的更新功能,并且该功能计算数据连接,则您不必跟踪旧数据的内容。 d3将为您处理。例如,如果您的callback()
函数将数据连接到这样的选择......
function callback(json) {
d3.selectAll('.someClass')
// this is the data join
.data(json);
// do other things with the selection
}
...然后您可以选择是否将过渡应用于已绑定数据的元素,现在有新数据(称为“更新”选择),或者.enter()
或{{ 1}}选择。
.exit()
我希望这很清楚。如果没有,或者您只是想进一步阅读有关数据连接的内容,Mike Bostock(d3的作者)撰写了一篇关于该主题的优秀帖子>> Thinking with Joins
答案 1 :(得分:1)
如果使用过渡设置新属性值,动画将自动从上一个值开始。在这种情况下,不需要明确地存储数据,因为D3将处理所有事情。
仅在默认补间无法正常工作的情况下,您需要指定自定义补间,并且可能需要显式存储旧数据。一个主要的例子是饼图(参见例如this example)。更新饼图时,不能让D3使用默认补间来插入饼段所覆盖的区域 - 您需要一个使用弧生成器计算中间路径的自定义补间。为此,您需要明确地在旧角度和新角度之间创建插值 - 为此,您需要存储旧数据。
在我链接到的示例中,旧数据(在这种情况下只是角度)存储为DOM的一部分。你当然可以将它存储在一个单独的对象中,然后将其编入索引。