Перемещение фиксированных узлов в 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 с теми же значениями, если вы хотите, чтобы узел оставался в определенной позиции.

Другие вопросы по тегам