【发布时间】:2013-10-04 01:24:42
【问题描述】:
我正在学习 D3,我的玩具应用程序是使用 Symplectic Velocity Verlet Integration 进行二维重力模拟的可视化工具。
我在使用绑定的结构化数据制作动画和绘制路径方面取得了相当大的成功,但在我看来,D3 并不是真正为将数据附加到多个元素而设计的。它有点假设对于任何给定的数据,都有一个清晰简单的 SVG 元素应该拥有它,这在 DOM 内的__data__ 属性中直接存储数据很明显。
不过,尚不清楚用多个 SVG 元素表示数据的正确方法。例如,我真的更喜欢为每个行星绘制一条路径和一个圆,该路径追踪其过去的位置(并且可以应用一系列巧妙的线长和颜色插值),并且圆圈绘制其当前位置。
我什至可以想出一些我可能想要绘制的元素:一个矢量箭头表示速度...一个矢量箭头表示加速度...
在我的例子中,我的主数据结构是这样构造的,并在这个结构中动态维护:
var data = [];
function makeParticle(x, y, vx, vy) {
// state vector plus goodies
return [
x, y,
vx, vy,
0, 0,
[] // path
];
}
data.push(makeParticle(400, 100, -0.5, 1));
data.push(makeParticle(300, -100, 0.5, 2)); // and so on
数据的每个元素都是一个行星,它包含其当前状态向量(位置、速度和缓存的加速度(积分器所需))以及它的路径历史,它是一个位置数组,被截断为一些相当大的长度。
目前我正在像这样更新路径历史:
var paths = d3.select('svg').selectAll("path").data(data);
paths.enter().append('path'); // put cool transitions here
paths.exit().remove();
paths.attr("stroke", "red")
.attr("d", function(d){
return lineDrawer(d[6]);
})
这很好用,每条路径都跟踪自己的行星路径的副本。
我并不清楚如何优雅地扩展它以将我的圆圈包含在每条路径的开头。我当然不想将整个数据复制到圆的 DOM 元素中(因为它根本不需要路径数据)。
编辑根据我的自我回答:
我希望有人可以帮助阐明一种使用“组”来使数据驱动的一组事物为每个数据绘制的方法。例如[position, velocity, force, path] 作为数据,它们分别使用圆、箭头闭合路径、箭头闭合路径和开放路径进行可视化。这也有可能是完全想多了,因为这些属性是固定的。
【问题讨论】:
-
执行此操作的方法通常是使用
g元素并绑定数据,然后在下面添加基于该数据的所有内容。如果您使用.select()进行子选择,则来自g元素的数据也会被新的子元素自动继承。
标签: javascript html svg d3.js