关于力布局中的碰撞检测有几个问题,但没有一个我可以解决问题。 最接近的是:rect collision detection d3js
在下面的代码中,我确实有圆圈,但我将它们视为矩形(因为这就是我想要在最后解决的方框 - 圆形加上标签)。
以下是代码:
var graph = {
"nodes":[
{"name":"name-1","rating":1,"id":2951},
{"name":"name-2","rating":2,"id":654654},
{"name":"3","rating":3,"id":6546544},
{"name":"4","rating":4,"id":68987978},
{"name":"5","rating":5,"id":9878933},
{"name":"6","rating":6,"id":6161},
{"name":"7","rating":7,"id":64654},
{"name":"8","rating":8,"id":354654},
{"name":"9","rating":9,"id":8494},
{"name":"10","rating":10,"id":6846874},
{"name":"11","rating":11,"id":5487},
{"name":"12","rating":12,"id":34},
{"name":"13","rating":13,"id":65465465},
{"name":"14","rating":14,"id":5443},
{"name":"15","rating":15,"id":313514},
{"name":"16","rating":16,"id":36543614},
{"name":"17","rating":17,"id":3434},
{"name":"18","rating":18,"id":97413},
{"name":"19","rating":19,"id":97414},
{"name":"27","rating":20,"id":9134371}
],
"links":[
{"source":0,"target":5,"value":6, "label":"publishedOn"},
{"source":2,"target":5,"value":6, "label":"publishedOn"},
{"source":7,"target":1,"value":4, "label":"containsKeyword"},
{"source":8,"target":10,"value":3, "label":"containsKeyword"},
{"source":7,"target":14,"value":4, "label":"publishedBy"},
{"source":8,"target":15,"value":6, "label":"publishedBy"},
{"source":9,"target":1,"value":6, "label":"depicts"},
{"source":10,"target":1,"value":6, "label":"depicts"},
{"source":7,"target":1,"value":6, "label":"manageWebsite"},
{"source":16,"target":2,"value":5, "label":"manageWebsite"},
{"source":5,"target":3,"value":6, "label":"manageWebsite"},
{"source":16,"target":4,"value":6, "label":"manageWebsite"},
{"source":12,"target":9,"value":2, "label":"postedOn"},
{"source":13,"target":1,"value":6, "label":"childOf"},
{"source":10,"target":8,"value":8, "label":"describes"},
{"source":8,"target":11,"value":6, "label":"containsKeyword"},
{"source":2,"target":5,"value":3, "label":"manageWebsite"}
]
}
var width = 900;
var height = 700;
var color = d3.scale.category20();
var force = d3.layout.force()
.charge(-500)
.linkDistance(function(d) { return d.value * 10;})
.gravity(0.5)
.size([width, height]);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g");
var rect = svg.append("rect")
.attr("width", width)
.attr("height", height)
.style("fill", "none")
.style("pointer-events", "all");
var container = svg.append("g");
force.nodes(graph.nodes).links(graph.links).start();
var links = container.append("g")
.attr("class", "links")
.selectAll(".link")
.data(graph.links)
.enter().append("path")
.attr("class", "link")
.style("stroke-width", 2);
var nodes = container.append("g")
.attr("class", "nodes")
.selectAll(".node")
.data(graph.nodes)
.enter().append("g")
.attr("class", "node")
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
var circle = nodes.append("circle")
.attr("r", function(d) { return d.weight * 2+ 12; })
.style("fill", function(d) {
return color(1/d.rating);
});
nodes.append("text")
.attr("x", function(d) { return d.weight * 2+ 12 + 4; })
.text(function(d) { return d.name });
force.on("tick", function() {
var xnodes = force.nodes();
var len = xnodes.length;
var q = d3.geom.quadtree(xnodes);
for (i = 0; i < len; i++) {
//does not work
//q.visit(collideNew2(xnodes[i]));
}
links.attr("d", function(d) {
var dx = d.target.x - d.source.x,
dy = d.target.y - d.source.y,
dr = Math.sqrt(dx * dx + dy * dy);
return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
});
nodes.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
});
function collideNew2(node) {
var nx1, nx2, ny1, ny2, size;
size = 250;
nx1 = node.x;
nx2 = nx1 + size;
ny1 = node.y;
ny2 = ny1 + size;
return function(quad, x1, y1, x2, y2) {
var dx, dy;
if (quad.point && (quad.point !== node)) {
if (overlap(node, quad.point)) {
dx = Math.min(nx2 - quad.point.x, quad.point.x2 - nx1) / 2;
node.x -= dx;
quad.point.x -= dx;
dy = Math.min(ny2 - quad.point.y, quad.point.y2 - ny1) / 2;
node.y -= dy;
quad.point.y += dy;
}
}
return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
};
};
function overlap(n, p) {
var nx1, nx2, ny1, ny2, size;
size = 250;
nx1 = n.x;
nx2 = nx1 + size;
ny1 = n.y;
ny2 = ny1 + size;
var x1 = p.x;
var x2 = x1 + size;
var y1 = p.y;
var y2 = y1 + size;
if (((x1 > nx1 && x1 < nx2) || (x2 > nx1 && x2 < nx2)) && ((y1 > ny1 && y1 < ny2) || (y2 > ny1 && y2 < ny2))) {
return true;
}
return false;
}
似乎重叠功能以及所选的“节点”是错误的。我该如何解决这个问题?