Перемещение фиксированных узлов в D3
У меня есть узлы в силовой направленности D3, которые установлены на.исправлено = правда. Если я установлю значения.x или.y, сами узлы не переместятся на новую позицию.
Вот моя функция:
function fixNode(idArray, locationX, locationY) {
for ( x = 0; x < idArray.length; x++ ) {
for ( y = 0; y < nodes.length; y++ ) {
if (nodes[y].id == idArray[x]) {
nodes[y].fixed = true;
nodes[y].x = 50;
nodes[y].y = 50;
break;
}
}
}
}
ОБНОВЛЕНИЕ 1:
Вот рабочая функция, основанная на совете Джейсона:
function fixNode(idArray, locationX, locationY) {
for ( x = 0; x < idArray.length; x++ ) {
for ( y = 0; y < nodes.length; y++ ) {
if (nodes[y].id == idArray[x]) {
nodes[y].fixed = true;
nodes[y].x = 50;
nodes[y].y = 50;
nodes[y].px = 50;
nodes[y].py = 50;
break;
}
}
}
tick();
}
1 ответ
Направленное на принуждение расположение отделено от фактического рендеринга. Обычно у вас есть обработчик тиков, который обновляет атрибуты ваших элементов SVG для каждого "тика" алгоритма компоновки (хорошая вещь в развязке - это рендеринг в <canvas>
вместо этого или что-то еще).
Поэтому, чтобы ответить на ваш вопрос, вам просто нужно вызвать этот обработчик напрямую, чтобы обновить атрибуты ваших элементов SVG. Например, ваш код может выглядеть так:
var node = …; // append circle elements
var force = d3.layout.force()
.nodes(…)
.links(…)
.on("tick", tick)
.start();
function tick() {
// Update positions of circle elements.
node.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
}
Так что вы можете просто позвонить tick()
в любой момент и обновите позиции элементов.
Вы могли бы соблазниться force.tick()
, но это должно быть использовано как синхронная альтернатива force.start()
: вы можете вызывать его повторно, и каждый вызов выполняет шаг алгоритма компоновки. Тем не менее, есть внутренний alpha
переменная, используемая для управления моделируемым отжигом, используемым внутри, и после того, как макет "остынет", эта переменная будет 0
и дальнейшие звонки force.tick()
не будет иметь никакого эффекта. (Правда, было бы неплохо, если force.tick()
всегда срабатывает событие галочки независимо от охлаждения, но это не текущее поведение).
Как вы правильно заметили в комментариях, если вы установили вручную d.x
а также d.y
Вы также должны установить d.px
а также d.py
с теми же значениями, если вы хотите, чтобы узел оставался в определенной позиции.