简体   繁体   English

d3.js力导向图保持恒定的链接距离

[英]d3.js force-directed graph maintain constant link distances

Does anybody have an idea of how to maintain constant link distances while at the same time repulsing nodes? 有谁知道如何保持恒定的链路距离,同时排斥节点?

Here's an example of the problem (this is the standard FDG example, but with fewer nodes). 这是问题的一个示例(这是标准的FDG示例,但是节点较少)。

var graph = {
  "nodes":[
    {"name":"a","group":1},
      {"name":"a","group":1},
      {"name":"a","group":1},
      {"name":"a","group":1},
    {"name":"b","group":8}
  ],
  "links":[
    {"source":1,"target":0,"value":1},
      {"source":2,"target":0,"value":1},
      {"source":3,"target":0,"value":1},
      {"source":4,"target":0,"value":1}
  ]
};
var width = 300,
    height = 300;

var color = d3.scale.category20();

var force = d3.layout.force()
    .charge(-120)
    .linkDistance(30)
    .size([width, height]);

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

var drawGraph = function(graph) {
  force
      .nodes(graph.nodes)
      .links(graph.links)
      .start();

  var link = svg.selectAll(".link")
      .data(graph.links)
    .enter().append("line")
      .attr("class", "link")
      .style("stroke-width", function(d) { return Math.sqrt(d.value); });

  var gnodes = svg.selectAll('g.gnode')
  .data(graph.nodes)
  .enter()
  .append('g')
  .classed('gnode', true)
  .call(force.drag);

  var node = gnodes.append("circle")
      .attr("class", "node")
      .attr("r", 5)
      .style("fill", function(d) { return color(d.group); });

  node.append("title")
      .text(function(d) { return d.name; });

   var labels = gnodes.append("text")
              .text(function(d) { return d.name; })
              .attr('text-anchor', 'middle')
              .attr('font-size', 8.0)
              .attr('font-weight', 'bold')
              .attr('y', 2.5)
              .attr('fill', d3.rgb(50,50,50))
              .attr('class', 'node-label')
              .append("svg:title")
              .text(function(d) { return d.name; });

  force.on("tick", function() {
    link.attr("x1", function(d) { return d.source.x; })
        .attr("y1", function(d) { return d.source.y; })
        .attr("x2", function(d) { return d.target.x; })
        .attr("y2", function(d) { return d.target.y; })
    .each(function(d) { console.log(Math.sqrt((d.source.x - d.target.x) * (d.source.x - d.target.x) + (d.source.y - d.target.y) * (d.source.y - d.target.y))); });

                  gnodes.attr("transform", function(d) {
                      return 'translate(' + [d.x, d.y] + ')';
                  });
  });
};

drawGraph(graph);

http://jsfiddle.net/pkerpedjiev/vs3foo80/1/ http://jsfiddle.net/pkerpedjiev/vs3foo80/1/

There's one central node and four attached nodes. 有一个中央节点和四个附加节点。 The links should all have a length of 30, but because of the repulsion forces, they settle down to lengths of 35. Is there a way to counteract that and make the link lengths to converge to their desired values of 30 while maintaining the repulsion between non-connected nodes? 链节的长度均应为30,但由于排斥力,它们的长度减小到35。有没有办法抵消这种情况,并使链节的长度收敛到其期望值30,同时保持之间的排斥力。未连接的节点?

This would be akin to making the link force much stronger than the repulsion force. 这类似于使连接力比排斥力强得多。 Increasing that, however, leads to very unstable behaviour. 但是,增加它会导致非常不稳定的行为。

Another way of putting this question is, is there a way to spread the nodes as far apart from each other while maintaining the desired link lengths? 提出此问题的另一种方法是,是否有一种方法可以在保持所需的链路长度的同时将节点彼此分散开来?

Yes, use .chargeDistance(30) . 是的,请使用.chargeDistance(30) The .chargeDistance() setting determines the maximum distance when charge is applied, and is infinite by default. .chargeDistance()设置确定施加电荷时的最大距离,默认情况下为无限。 A setting of 30 set your charge to only apply to nodes that are within 30px, and should give you the behavior you want. 设置为30可将您的费用设置为仅适用于30像素以内的节点,并应为您提供所需的行为。

The drawback of this is that on a large graph, you will no longer see add-on effects that unfold the graph faster and the layout will have a more localized appearance. 这样做的缺点是,在大图上,您将不再看到可以更快地展开图的附加效果,并且布局将具有更局部的外观。 To achieve something like that, I would suggest experimenting with a dynamic chargeDistance tied to the alpha parameter of the force algorithm (the cooldown) so that it starts at infinite and then moves toward 30 (or whatever) as the graph cools down. 为了达到这样的效果,我建议尝试将动态的chargeDistance与力算法的alpha参数绑定(冷却),以便它从无穷大处开始,然后在图形冷却时朝30(或其他方向)移动。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM