Graph D3:具有固定Y范围的力布局-减少连杆重叠

Graph D3:具有固定Y范围的力布局-减少连杆重叠,graph,d3.js,force-layout,Graph,D3.js,Force Layout,我已经创建了一个图,其中每个节点都位于一个固定的y范围内。我正在使用强制布局来显示图形,但我不知道如何确保交叉链接的数量达到最小-某些交叉将是不可避免的。我认为这是重力、力、连接距离等因素的综合作用,但我的任何改变似乎都不起作用 图表位于: 理想的配置是 但结果往往是一团糟: 如果您有任何想法,我们将不胜感激。D3中实现的部队布局算法并不允许您这样做。它并没有试图最小化交叉链接的数量——还有其他强制导向布局实现(例如)明确地做到了这一点,但它们没有在D3中实现 因此,简单的回答是,虽然您可

我已经创建了一个图,其中每个节点都位于一个固定的y范围内。我正在使用强制布局来显示图形,但我不知道如何确保交叉链接的数量达到最小-某些交叉将是不可避免的。我认为这是重力、力、连接距离等因素的综合作用,但我的任何改变似乎都不起作用

图表位于:

理想的配置是

但结果往往是一团糟:


如果您有任何想法,我们将不胜感激。

D3中实现的部队布局算法并不允许您这样做。它并没有试图最小化交叉链接的数量——还有其他强制导向布局实现(例如)明确地做到了这一点,但它们没有在D3中实现

因此,简单的回答是,虽然您可能会获得适用于特定情况的结果,但总体而言,要做到这一点,您必须选择替代的部队布局实施方案。如果您可以使用其他图形库,则有一个解决方案。

看看这个

这是您的示例,但有一点修改。基本思想是在两个过程中进行强制布局:

  • 首先,将允许更宽松的布局方式:允许节点偏离其“级别”;这将允许自发地相互跳跃,以实现更好的链接布局(更少的交叉点)
  • 第二个将“返回”节点到各自的级别
代码的关键部分:

海关部队:

  graph.nodes.forEach(function(o, i) {
    o.y += (y(o.level) - o.y) * k; 
  });
布局定义:

  var force = d3.layout.force()
    .charge(-1000)
    .gravity(0.2)
    .linkDistance(30)                    
    .size([width, height])
调用force.start()两次:

force
  .nodes(graph.nodes)
  .links(graph.links)
  .on("tick", tick)
  .start();

setTimeout(function() {
  first = 0;
  force.start();
}, 6000);  
变量“first”:

var first=1

  if(first) {
    var k = e.alpha;
  }
  else{
    var k = 10 * e.alpha;
  }
第一次通过后的屏幕截图:

第二次通过后:

我将尝试改进这个示例,这是一个有点“脏”的开发原型,但我现在没有时间,也许明天


编辑:注意:我刚刚注意到,实际上数据是恒定的,但是,不同模拟的布局不同。不一定要这样。它可以更具确定性。我明天也会设法解决的。我还将使用“end”事件更好地链接布局。

我已经看过Sigma.js。它看起来非常强大,可能更适合我,但它需要对代码进行更多的挖掘才能使其正常工作。不幸的是,Fruchterman Reingold实现不适用于sigma.js v1.0。此外,在阅读了文档之后,我认为没有一种方法可以在不编写完整的定制渲染器的情况下将“固定”y级别应用于节点。你知道我将如何实现固定的y级别吗?如果不是的话,我现在可能会坚持使用D3。听起来要实现它需要很多工作。这太棒了。请告诉我您将如何使图形具有确定性。我考虑的一个方面是为每个节点添加一个顺序,但顺序将与相关节点相关。我已经更新了您的plunkr,并在订单字段中添加了节点。这可以用于图形的确定性版本吗?