0

我正在学习 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],作为数据,它们分别使用圆、箭头闭合路径、箭头闭合路径和开放路径进行可视化。这也可能是完全想多了,因为这些属性是固定的。

4

1 回答 1

0

我想在思考问题的过程中,我很清楚我所要做的就是过滤掉数据,所以我只附加位置状态数据selectAll('circle.planet')而不是包含大量路径历史的完整基准值大批。这样它就可以准确地获取它负责显示的数据。

似乎我必须对子选择做更多的阅读(我对为什么(或是否)子选择仅限于层次结构的两个维度感到困惑),但这似乎完全合理。这似乎是合乎逻辑的,如果我想为每个数据绘制 4 个项目,我只需要以某种方式将我的数据结构的正确子集“分配”给每个 SVG 可视化器元素。

于 2013-10-04T01:27:25.467 回答