我尝试使用图像作为节点创建强制布局,可以根据用户输入(通过几个复选框)进行修改。但是,当用户更改他/她的输入并重新绘制布局时,某些图像会显示在错误的节点之上,我无法理解原因。
我构建代码的方式:
我的代码的第一部分似乎工作正常。数据数组是从csv创建的,并且可以正确地动态更新。
但是当重绘图形时,一些图像出现在错误的节点上(即使工具提示中显示的图像是正确的...)。
以下是我的" draw"功能,我认为这就是问题所在。
function draw(nodes) {
var force = d3.layout.force()
.nodes(nodes)
.size([width, height])
.on("tick", tick)
.charge(-0.01)
.gravity(0)
.start();
function tick(e) {
// Set initial positions
nodes.forEach(function(d) {
d.radius = radius;
});
var node = svg.selectAll(".node")
.data(nodes);
var newNode = node.enter().append("g")
.attr("class", "node")
.on("click", function(d) {
div.transition().duration(300).style("opacity", 1);
div.html("<img src=img_med/" + d.name + ".png >")
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY-10) + "px");
})
.on("mouseout", function (d) { div.transition().delay(1500).duration(300).style("opacity", 0);});
newNode.append("image")
.attr("xlink:href", function(d) { return "img_med/" + d.name + ".png"; })
.attr("x", -8)
.attr("y", -8)
.attr("width", 30)
.attr("height", 30)
.style("cursor", "pointer")
.call(force.drag);
node.exit().remove();
node.each(moveTowardDataPosition(e.alpha));
node.each(collide(e.alpha));
node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
}
function moveTowardDataPosition(alpha) {
return function(d) {
d.x += (x(d[xVar]) - d.x) * 0.1 * alpha;
d.y += (y(d[yVar]) - d.y) * 0.1 * alpha;
};
}
// Resolve collisions between nodes.
function collide(alpha) {
var quadtree = d3.geom.quadtree(nodes);
return function(d) {
var r = d.radius + radius + padding,
nx1 = d.x - r,
nx2 = d.x + r,
ny1 = d.y - r,
ny2 = d.y + r;
quadtree.visit(function(quad, x1, y1, x2, y2) {
if (quad.point && (quad.point !== d)) {
var x = d.x - quad.point.x,
y = d.y - quad.point.y,
l = Math.sqrt(x * x + y * y),
r = d.radius + quad.point.radius + padding;
if (l < r) {
l = (l - r) / l * alpha;
d.x -= x *= l;
d.y -= y *= l;
quad.point.x += x;
quad.point.y += y;
}
}
return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
});
};
}
}
任何帮助/建议/指示,以帮助我理解为什么错误的图像显示在这些节点之上将是非常感谢!
如果有什么不清楚,请告诉我。
非常感谢!
答案 0 :(得分:0)
好吧,我刚刚错过了一个关键功能,告诉D3如何匹配现有节点和数据。
我替换了
var node = svg.selectAll(".node")
.data(nodes);
通过
var node = svg.selectAll(".node")
.data(nodes, function(d) {return d.name;});
它有效。 谢谢Lars!