在力图中设置固定节点时遇到问题:修复节点断开链接(D3)

问题描述 投票:0回答:1

D3 新手,从我在互联网上发现的内容来看,很多问题/示例都相当过时,所以我很难找到解决方案。

最终我希望有一个由自动最佳间隔的节点和链接组成的网络图。有两个“起始”节点需要固定在中心。其余节点需要围绕这些节点间隔开。我不需要这个图表是可拖动的。

我的起点是这个力定向图。许多其他帖子提到固定节点的位置应该可行,其他节点自然会放置在该固定节点周围,但这不是我的经验。相反,虽然节点是固定的,但链接似乎被定位到空白空间(或节点本来所在的空间 - 参见下图)。

我正在像这样修复

ticked
函数中的节点:

  function ticked() {
    node
      .attr('cx', (d) => {
        if (d.id === 'NAME_ONE') {
          return -50;
        } else if (d.id === 'NAME_TWO') {
          return 50;
        } else {
          return d.x;
        }
      })
      .attr('cy', (d) => {
        if (FIXED_NODES.includes(d.id)) {
          return 0;
        } else {
          return d.y;
        }
      });

    link
      .attr('x1', (d) => d.source.x)
      .attr('y1', (d) => d.source.y)
      .attr('x2', (d) => d.target.x)
      .attr('y2', (d) => d.target.y);
  }

编辑: 我应该注意到,我已经尝试修复这两个节点之间的链接以及同一刻度函数内的链接,但这似乎也没有取得成果。当然有更简单的方法。

javascript typescript d3.js
1个回答
0
投票

力模拟不跟踪 SVG 中的圆圈,它不知道它们。因此,改变圆的 cx/cy 对力模拟没有影响。

力模拟通过数据数组中节点的 d.x 和 d.y 属性跟踪节点(因此链接端点)。由于这些属性通常用于在 SVG 中放置圆和线,因此更改这些值将改变它们的位置。

D3 力模拟每次都会检查两个属性:d.fx 和 d.fy,如果设置了这些属性,则模拟将使用 d.fx 和 f.fy 属性在模拟中定位节点,而不是施加任何力(固定节点就位)。因此,在您的情况下,不要使用 cx 值修复 SVG 节点,而是使用 d.fx 修复数据项:

if (d.id === 'NAME_ONE') {
      d.fx = -50;
}

现在您可以将带有 d.x 的所有节点放置在 tick 函数中。

当然,您不需要每次都设置 d.fx(除非您在模拟过程中更改节点的名称),您可以在开始时运行一次节点,并在适当的情况下设置一次 fx/fy 属性。

© www.soinside.com 2019 - 2024. All rights reserved.