3

我有一些类似于力导向图示例的东西。主要区别在于没有强制力——布局是静态的,除了用户拖动交互。我添加了在用户定义的节点组周围绘制凸包(作为 svg:path 元素)的代码。随着节点的移动(即.on("drag")),计算外壳的代码被触发。这意味着当节点被拖动时它会不断触发。通常有 10 到 30 个船体;一个节点可能在一个或多个外壳中。见下文:

船体图示例

我试图弄清楚是否有更有效(更高性能)的方式来做我正在做的事情。暂时保持高水平:

拖动时,更新所有船体图形:

  1. 对于每个船体,创建组成节点坐标的数组。
  2. 将上述数组中的每个坐标对替换为与原始点相距一定距离r的 8 个点。这是为了填充/扩张船体,因此它实际上不会接触任何节点。
  3. 将计算出的坐标馈送到d3.geom.hull.

我在 Chrome 中获得了大约 50 fps,这一点也不差,但它似乎是一个非常低效的设置。

我唯一明确的想法是将节点包含在节点数组中的船体的 ID 存储在节点数组中,并且只更新那个/那些船体而不是所有船体。我还想知道更有效的数据结构来存储船体数据(而不是路径本身)。目前数据结构如下所示:

hulls = {1:{nodeIDs:[1,2,3,4,5], name:"hull1"}, 2:{...}, ...};

请原谅这个开放式问题,但我希望有一些我不熟悉的编程技术在这里可以很好地工作。

4

1 回答 1

1

最有效的方法是仅重新计算围绕正在拖动的节点运行的 8 元组坐标的位置,然后在父外壳中传播该信息以进行重绘。

您可以通过进行一些更改来做到这一点。

  • 在每个节点的数据结构中,添加以下元素。
    • 对所有父外壳的引用(如您所建议的)
    • 围绕该节点运行的“填充”坐标的 8 元组(缓存它们)
  • 在拖动时,只考虑被拖动的节点。
  • 更新该节点的 8 元组。
  • 收集该节点的父外壳的子节点并将它们的 8 元组折叠在一起并将它们提供给它们hull(如有必要,销毁前一个外壳)。

我对d3.js的 API 不熟悉,但我相信您可以填写我留下的任何空白。

于 2012-08-25T19:55:58.123 回答