Я пытаюсь создать силовую схему с изображениями в виде узлов, которые могут быть изменены в зависимости от пользовательского ввода (через пару флажков). Однако, когда пользователь меняет свой вход и макет перерисовывается, некоторые изображения отображаются вверху неправильного узла, и я не могу понять, почему.D3 Силовая компоновка с изображением в виде узла, но неправильные изображения добавляются
Я так структурирован мой код:
- Я вытащил данные из CSV
- Я создал функцию «Update», которая создает/изменяет массив данных в зависимости от ввода данных пользователя
- Я создал " чтобы каждый раз, когда пользователь меняет свой ввод (то есть каждый раз, когда вызывается функция «update»),
Первая часть моего кода, похоже, работает нормально. Массив данных создается из csv и динамически обновляется правильно.
Но когда график перерисовывается, некоторые изображения появляются на неправильном узле (хотя изображение, отображаемое в подсказке, является правильным).
Ниже приведена моя функция «рисования», я думаю, что здесь проблема.
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;
});
};
}
}
Любые помощь/предложения/указатели, чтобы помочь мне понять, почему неправильные изображения отображаются на верхней части этих узлов были бы оценены!
Сообщите мне, если что-то неясно.
Большое спасибо!
Возможно, вам нужна ключевая функция (второй аргумент '.data()'), который сообщает D3, как сопоставлять существующие узлы и данные. Значение по умолчанию - по индексу, что, вероятно, не то, что вы хотите. –
@LarsKotthoff спасибо за ваш комментарий, я все еще изучаю ключевые функции, но если я напишу что-то вроде: var node = svg.selectAll (". Node") .data (nodes, function (d) {return d. имя;}); Это должно работать правильно? – Charles
Из вашего кода, похоже, должно быть, да. –