在力布局D3.js中保持节点之间的动态链接距离

时间:2016-03-17 10:10:38

标签: javascript json d3.js

我正在解析json字符串中每个链接的链接距离。

 {
  "nodes" : [ {
    "name" : "cricket",
    "category" : "main",
    "id" : 0
  }, {
    "name" : "record1",
    "category" : "twitter",
    "id" : 1
  }, {
    "name" : "record2",
    "category" : "web",
    "id" : 2
  }],
  "links" : [ {
    "source" : 0,
    "target" : 1,
    "linkDistance" : 13.17538
  }, {
    "source" : 0,
    "target" : 2,
    "linkDistance" : 13.17538
  } ]
}

在javascript中,链接距离作为函数给出。

var force = d3.layout.force()
     .gravity(0.3)
     .charge(0)
     .size([width,height])
     .nodes(jsonstring.nodes)
     .links(jsonstring.links)
     .linkDistance(function (d) {
           return d.linkDistance;
     })
     .start();

但是节点没有绘制给定的链接距离。充电值为0.当通过json解析时,是否有人知道如何保持动态链接距离?

1 个答案:

答案 0 :(得分:0)

每次编辑d.linkDistance时,都需要再次拨打电话

force.linkDistance(function (d) {
       return d.linkDistance;
 })

使修改生效。

还要记住,d3中的链接距离实施得非常弱,因此根据我的经验编辑链接距离无论如何都不会对图形布局产生很大影响。您可以随时尝试force.linkStrength(10)或更高的值来增加距离的重要性,但这可能不足以让精确正确的值。

要尝试的东西:

  • 找到图表的spanning tree(这会将边缘列为“骨架”st

  • 运行以下操作以强制边长是正确的:

    force.on('tick', function() {
       //consider all edges of a spanning tree, from root to leaves
       //using links directly instead of st would yield strange results, but depending on your data it might work well enough
       st.forEach(function(d) {
           //compute link coordinates  
           var dx = d.target.x - d.source.x; 
           var dy = d.target.y - d.source.y;
           //ratio desired length / actual length
           var r = d.linkDistance / Math.sqrt(dx*dx+dy*dy) 
           //add r=Math.sqrt(r) for something smoother (but less constrained)
           //move target to desired length
           d.target.x = d.source.x + dx * r; 
           d.target.y = d.source.y + dy * r;
    
       })
    })
    

它会严重降低力布局的自然流动(可能会稍微降低r=Math.sqrt(r),但仍然如此),如果你使用它会弄乱节点拖动,但它应该强制一些弧长如果可能的话。