Javascript D3力图-不';t重叠

Javascript D3力图-不';t重叠,javascript,graph,d3.js,collision-detection,Javascript,Graph,D3.js,Collision Detection,我希望开发一个由节点链接图组成的viz。我有一系列的点,我不想改变它们的位置,除非在图上发生碰撞(一个节点在另一个节点上)。在碰撞节点的情况下,我希望将它们隔开,以便它们不会重叠。我的JS代码如下 var chartWidth = 200; var chartHeight = 200; var widthPadding = 40; var heightPadding = 40; var link, node; $(function(){ initialize(); }); fun

我希望开发一个由节点链接图组成的viz。我有一系列的点,我不想改变它们的位置,除非在图上发生碰撞(一个节点在另一个节点上)。在碰撞节点的情况下,我希望将它们隔开,以便它们不会重叠。我的JS代码如下

var chartWidth = 200;
var chartHeight = 200;
var widthPadding = 40;
var heightPadding = 40;

var link, node;

$(function(){
    initialize();
});


function initialize() {
    var jsonString  = '{"nodes":[{"x":40,"y":64,"r":6,"fixed":true},{"x":40,"y":63,"r":6,"fixed":true},{"x":119,"y":53,"r":6,"fixed":true},{"x":119,"y":73,"r":6,"fixed":true},{"x":137,"y":73,"r":6,"fixed":true},{"x":140,"y":140,"r":6,"fixed":true},{"x":68,"y":57,"r":6,"fixed":true},{"x":70,"y":75,"r":6,"fixed":true},{"x":51,"y":59,"r":6,"fixed":true},{"x":51,"y":54,"r":6,"fixed":true},{"x":137,"y":40,"r":6,"fixed":true}],"links":[{"source":0,"target":1},{"source":1,"target":2},{"source":2,"target":3},{"source":3,"target":4},{"source":4,"target":5},{"source":0,"target":1},{"source":1,"target":6},{"source":6,"target":7},{"source":7,"target":4},{"source":4,"target":5},{"source":0,"target":1},{"source":1,"target":8},{"source":8,"target":9},{"source":9,"target":10},{"source":10,"target":5}]}';
    drawForceDirectedNodeLink($.parseJSON(jsonString));
}


function drawForceDirectedNodeLink(graph){
var width = chartWidth + (2*widthPadding);
var height = chartHeight + (2*heightPadding);

var q = d3.geom.quadtree(graph.nodes),
  i = 0,
  n = graph.nodes.length;

while (++i < n) {
    q.visit(collide(graph.nodes[i]));
}

var force = d3.layout.force()
    .size([width, height])
    .gravity(0.05)
    .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; });

        node.attr("cx", function(d) { return d.x; })
            .attr("cy", function(d) { return d.y; })
            .attr("r", function(d) { return d.r; });
    });

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

var link = svg.selectAll(".link"),
    node = svg.selectAll(".node");

force
  .nodes(graph.nodes)
  .links(graph.links)
  .start();

link = link.data(graph.links)
    .enter().append("line")
    .attr("class", "link");

node = node.data(graph.nodes)
    .enter().append("circle")
    .attr("class", "node");
}


function collide(node) {
  var r = node.radius + 16,
      nx1 = node.x - r,
      nx2 = node.x + r,
      ny1 = node.y - r,
      ny2 = node.y + r;
  return function(quad, x1, y1, x2, y2) {
        if (quad.point && (quad.point !== node)) {
          var x = node.x - quad.point.x,
              y = node.y - quad.point.y,
              l = Math.sqrt(x * x + y * y),
              r = node.radius + quad.point.radius;
          if (l < r) {
            l = (l - r) / l * .5;
            node.x -= x *= l;
            node.y -= y *= l;
            quad.point.x += x;
            quad.point.y += y;
          }
        }
        return x1 > nx2
            || x2 < nx1
            || y1 > ny2
            || y2 < ny1;
  };
}
var chartWidth=200;
var chartHeight=200;
var=40;
var heightPadding=40;
var链路,节点;
$(函数(){
初始化();
});
函数初始化(){
目前,美国“x”40,“y”40,“x”40,“y”40,“x”40,“y”40,“y”63,“r”:6,“r”:6,”6,“固定”6,“固定的”:真实的,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,},{“x”:51,“y”:54,“r”:6,“固定的”:真的},{“x”:137,“y”:40,“r”:6,“固定的”:真的}],“链接”:[{“源”:0,“目标”:1},{“源”:1,“目标”:2},{“源”:2,“目标”:3},{“源”:3,“目标”:4,“目标”:4,“目标”:5},{“源”:0,“目标”:1},{“源”:1,“目标”:6,{“源”:6,“目标”:7,“目标”:7,“源”:4,“目标”:4},{“源”:5},{{“源”:1,“目标”:8},{“源”:8,“目标”:9},{“源”:9,“目标”:10},{“源”:10,“目标”:5}]};
drawForceDirectedNodeLink($.parseJSON(jsonString));
}
函数drawForceDirectedNodeLink(图形){
变量宽度=图表宽度+(2*宽度填充);
变量高度=图表高度+(2*高度填充);
var q=d3.geom.quadtree(图节点),
i=0,
n=graph.nodes.length;
而(++inx2
||x2ny2
||y2
正如你所看到的,我已经尝试实现了前面提到的碰撞检测逻辑,但是我还没有完成这部分的工作


更新


node.radius
更改为
node.r
并将
quad.point.radius
更改为
quad.point.r
。它应该可以工作。看起来这只是一个
NaN
问题。

更新


node.radius
更改为
node.r
并将
quad.point.radius
更改为
quad.point.r
。它应该可以工作。看起来这只是一个
NaN
问题。

更新


node.radius
更改为
node.r
并将
quad.point.radius
更改为
quad.point.r
。它应该可以工作。看起来这只是一个
NaN
问题。

更新


node.radius
更改为
node.r
并将
quad.point.radius
更改为
quad.point.r
。它应该可以工作。看起来这只是一个
NaN
问题。

请注意
jsonString
声明中的
initialize()
,每个节点都被赋予一个
r
属性。但是,在
collide()
中,您将执行以下操作:

.attr("r", function(d) { return d.radius - 2; })
确保节点附加了
radius
属性。如果没有,则应进行以下更改:

.attr("r", function(d) { return d.r - 2; })
在Mike Bostock脚本的第30行可以看到,他的节点最初是用
radius
属性声明的,而不是
r
属性

var nodes = d3.range(200).map(function() { return {radius: Math.random() * 12 + 4}; }),

请注意,在
initialize()
中的
jsonString
声明中,每个节点都被赋予了
r
属性。但是,在
collide()
中,您正在执行以下操作:

.attr("r", function(d) { return d.radius - 2; })
确保节点附加了
radius
属性。如果没有,则应进行以下更改:

.attr("r", function(d) { return d.r - 2; })
在Mike Bostock脚本的第30行可以看到,他的节点最初是用
radius
属性声明的,而不是
r
属性

var nodes = d3.range(200).map(function() { return {radius: Math.random() * 12 + 4}; }),

请注意,在
initialize()
中的
jsonString
声明中,每个节点都被赋予了
r
属性。但是,在
collide()
中,您正在执行以下操作:

.attr("r", function(d) { return d.radius - 2; })
确保节点附加了
radius
属性。如果没有,则应进行以下更改:

.attr("r", function(d) { return d.r - 2; })
在Mike Bostock脚本的第30行可以看到,他的节点最初是用
radius
属性声明的,而不是
r
属性

var nodes = d3.range(200).map(function() { return {radius: Math.random() * 12 + 4}; }),
注意,w