我正在学习 D3,我的玩具应用程序是使用Symplectic Velocity Verlet Integration进行二维重力模拟的可视化工具。
我在使用绑定的结构化数据制作动画和绘制路径方面取得了相当大的成功,但在我看来,D3 并不是真正为将数据附加到多个元素而设计的。它有点假设对于任何给定的数据,都有一个清晰而简单的 SVG 元素应该拥有它,这在__data__
DOM 内的属性中直接存储数据很明显。
但是,尚不清楚用多个 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]
,作为数据,它们分别使用圆、箭头闭合路径、箭头闭合路径和开放路径进行可视化。这也可能是完全想多了,因为这些属性是固定的。