Javascript D3.js力定向图,通过使边相互排斥来减少边交叉

Javascript D3.js力定向图,通过使边相互排斥来减少边交叉,javascript,graph,d3.js,force-layout,Javascript,Graph,D3.js,Force Layout,所以我已经有了一个页面,它绘制了一个力定向图,如图所示 这很好。我使用的是来自的JS,经过一些调整,节点的分布稍微好一点 这些或多或少是唯一的区别: d3.json("force.json", function(json) { var force = d3.layout.force() .gravity(0.1) .charge(-2000) .linkDistance(1) .linkStrength(0.1) .nodes(js

所以我已经有了一个页面,它绘制了一个力定向图,如图所示

这很好。我使用的是来自的JS,经过一些调整,节点的分布稍微好一点

这些或多或少是唯一的区别:

d3.json("force.json", function(json) {
  var force = d3.layout.force()
      .gravity(0.1)
      .charge(-2000)
      .linkDistance(1)
      .linkStrength(0.1)
      .nodes(json.nodes)
      .links(json.links)
      .size([w, h])
      .start();
在这种情况下,降低连杆强度似乎会使连杆更像弹簧,因此与常用的技术类似。这相当有效,但仅适用于相当小的图形。对于较大的图,交叉点的数量只会增加——正如人们所期望的那样,但它所使用的解决方案通常远不是最优的。我不是在寻找一种获得最优解的方法,我知道这很难。我只希望它有一些粗制滥造的补充,试图迫使线和节点分开


有没有办法在in链接之间以及节点之间添加排斥力?我不熟悉D3力的工作方式,我似乎找不到任何东西表明这是可能的…

比尝试强制排斥边缘更容易的事情是摆动节点,直到系统中交叉线的数量减少

从连接数最少的节点开始,然后向下摆动

如果您尝试将边用作节点,我怀疑您将遇到相同的空间锁定问题。解决方案是找出哪里有边交点,以及它们是否可以解决。您可能会发现,解决许多交叉边是不可能的


可视化的一种更横向的方法是对其设置动画,使其一次仅显示节点和连接的子集。或者使边透明,直到用户将鼠标焦点放在节点上,此时关联的边变得更加可见。

比尝试强制排斥边更容易的方法是晃动节点,直到系统中交叉线的数量减少

从连接数最少的节点开始,然后向下摆动

如果您尝试将边用作节点,我怀疑您将遇到相同的空间锁定问题。解决方案是找出哪里有边交点,以及它们是否可以解决。您可能会发现,解决许多交叉边是不可能的


可视化的一种更横向的方法是对其设置动画,使其一次仅显示节点和连接的子集。或者使边透明,直到用户将鼠标焦点放在节点上,节点上的关联边变得更加可见。

我遵循了Force Editor示例,我发现设置
charge
linkDistance
值可以解决问题

  ...
  .charge(-200)
  .linkDistance(50)
  ...
截图:


我遵循了Force Editor示例,发现设置
charge
linkDistance
值可以解决问题

  ...
  .charge(-200)
  .linkDistance(50)
  ...
截图:


不幸的是,您的问题不存在答案。

D3中没有排斥边缘或最小化边缘交叉的内置机制。你可能会认为在边缘实施充电并不难,但我们到了

此外,似乎在任何地方都没有任何机制可以减少边缘交叉。我浏览了几十个可视化库和布局算法,其中没有一个涉及到减少通用无向图上的边缘交叉

有许多算法适用于平面图、二级图或其他简化。在理论上,它可以很好地用于二级图,尽管完全缺乏文档使得它几乎不可能使用

部分原因是布局图很难。特别是,最小化边缘交叉是NP困难的,所以我怀疑大多数布局设计师遇到了这个问题,他们的头撞了几次键盘,然后放弃了


如果有人为此提供了一个好的库,请为我们其他人发布:)

不幸的是,您的问题不存在答案。

D3中没有排斥边缘或最小化边缘交叉的内置机制。你可能会认为在边缘实施充电并不难,但我们到了

此外,似乎在任何地方都没有任何机制可以减少边缘交叉。我浏览了几十个可视化库和布局算法,其中没有一个涉及到减少通用无向图上的边缘交叉

有许多算法适用于平面图、二级图或其他简化。在理论上,它可以很好地用于二级图,尽管完全缺乏文档使得它几乎不可能使用

部分原因是布局图很难。特别是,最小化边缘交叉是NP困难的,所以我怀疑大多数布局设计师遇到了这个问题,他们的头撞了几次键盘,然后放弃了


如果有人为此提供了一个好的库,请为我们其他人发布:)

我已经“解决”了这个问题:

nodes[0].x = width / 2;
nodes[0].y = 100;
nodes[0].fixed = true;
force.on("tick", function(e) {

    var kx = .4 * e.alpha, ky = 1.4 * e.alpha;
    links.forEach(function(d, i) {
      d.target.x += (d.source.x - d.target.x) * kx;
      d.target.y += (d.source.y + 80 - d.target.y) * ky;
    });
    [...]
 }

这不完全是我们想要的,但比以前更好。 重要的是,定义一个“根”节点并修复它

nodes[0].fixed = true;

它看起来更像一棵树,但因此更清晰。

我已经“解决”了这个问题:

nodes[0].x = width / 2;
nodes[0].y = 100;
nodes[0].fixed = true;
force.on("tick", function(e) {

    var kx = .4 * e.alpha, ky = 1.4 * e.alpha;
    links.forEach(function(d, i) {
      d.target.x += (d.source.x - d.target.x) * kx;
      d.target.y += (d.source.y + 80 - d.target.y) * ky;
    });
    [...]
 }

这不完全是我们想要的,但比以前更好。 重要的是,定义一个“根”节点并修复它

nodes[0].fixed = true;

它看起来更像一棵树,但更清晰。

你有没有弄明白这一点?不幸的是没有。不过我没有深入研究js,因为我不熟悉这种语言。我确实试过使用一个真正的Fruchterman&Reingold te