D3:具有固定Y范围的强制布局 - 减少链接重叠

时间:2014-02-06 08:56:53

标签: graph d3.js force-layout

我创建了一个图表,其中每个节点都适合固定的y范围之一。我使用强制布局来显示图形,但我不知道如何确保出现最小的交叉链接 - 某些交叉将是不可避免的。我认为这是重力,力量,链接距离等的组合,但我的改变似乎都没有效果

该图位于: http://plnkr.co/edit/wyWjk37mkDCWcwpZvzxe?p=preview

理想的配置是 enter image description here

但它常常像一团糟: enter image description here

任何想法都会非常感激

2 个答案:

答案 0 :(得分:3)

看看这个example

这是你的例子,但有点修改。基本思想是两次通过强制布局:

  • 首先允许更轻松的布局方式:允许节点偏离其“级别”;这将允许自发跳跃,以实现更好的链接布局(更少的交集)
  • 第二个将“返回”节点到各自的级别

代码的关键部分:

自定义力量:

  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;
  }

首次通过后的屏幕截图:

enter image description here

第二遍后:

enter image description here

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

编辑:注意:我刚注意到实际上数据是不变的,然而,布局不同于模拟到模拟。这不一定是那种方式。它可以更具确定性。我明天也会尝试解决这个问题。我还会用“结束”事件做更好的链接布局。

答案 1 :(得分:0)

D3中实施的力布局算法实际上并不允许您这样做。它不会尝试最小化交叉链接的数量 - 还有其他强制定向的布局实现(例如Fruchterman-Reingold)明确地执行此操作,但它们未在D3中实现。

所以简短的回答是,虽然您可能获得了适合特定情况的结果,但总的来说,您必须选择替代的力布局实现。如果您可以使用其他图表库,则Fruchterman-Reingold implementationsigma.js