Javascript D3力图-不';t重叠
我希望开发一个由节点链接图组成的viz。我有一系列的点,我不想改变它们的位置,除非在图上发生碰撞(一个节点在另一个节点上)。在碰撞节点的情况下,我希望将它们隔开,以便它们不会重叠。我的JS代码如下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
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