D3.js强制有向图,通过使边相互排斥来减less边交叉

所以我已经有一个页面绘制一个有力的图,就像这里展示的那样 。

这工作正常。 我从这里使用JS,只需稍作调整即可将节点稍微分散一些。

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

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(); 

在减less链接强度的地方似乎使得链接更像是弹簧,所以它变得类似于经常使用的Fruchterman&Reingold技术。 这工作相当好,但只适用于相当小的图表。 随着更大的图表,交叉口的数量正在上升 – 正如人们所期望的那样,但是它所处的解决scheme通常远不是最佳的。 我不想找一个方法来获得最佳的解决scheme,我知道这是非常困难的。 我只是希望它有一些粗加法,试图强制拆分线以及节点。

有没有办法在链接之间以及节点之间添加斥力? 我不熟悉D3强制的方式,我似乎无法find任何说这是可能的…

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

D3中没有内置的机制来排斥边缘或减less边缘交叉。 你可能会认为在边缘实行收费并不难,但我们在这里。

而且,在任何地方似乎都没有任何减less边缘交叉的机制。 我已经浏览了几十个可视化库和布局algorithm,并没有一个处理减less通用无向图上的边交叉。

有许多algorithm对于平面图或2级图或其他简化很适用。 达格尔在理论上对于2级图很好地工作,尽pipe完全缺乏文档使得几乎不可能合作。

部分原因是布局图很难 。 特别是,边缘交叉的最小化是非常困难的,所以我怀疑大多数布局devise者都遇到了这个问题,几次把它们撞在键盘上,放弃了。

如果有人为此提出了一个好的图书馆,请为我们其他人发布:)

比试图强行击退边缘要容易一些的东西是摆动节点,直到系统中交叉线的数量较低。

http://en.wikipedia.org/wiki/Simulated_annealing

从具有最less连接数的节点开始,向下摆动。

如果你尝试和使用边缘作为节点,我怀疑你只是会得到相同的空间locking问题。 解决的办法是找出存在边界交点的地方,以及是否可以解决。 你可能会发现,解决许多边缘交叉是不可能的

可视化的一个更侧面的方法是animation化它,使得它一次只显示节点和连接的子集。 或者使边缘变为透明的,直到用户将鼠标焦点放置在节点上,相关联的边缘变得更加可见。

我跟着部队编辑器的例子,我看到设置chargelinkDistance值解决了这个问题。

  ... .charge(-200) .linkDistance(50) ... 

截图:

在这里输入图像说明

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

 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; }); [...] } 

http://mbostock.github.io/d3/talk/20110921/parent-foci.html

这不是我们想要的,而是像以前一样更好。 Importend是,你定义一个“根”节点,并修复它。

 nodes[0].fixed = true; 

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