2012-05-08 4 views
7

У меня есть узлы в макете с принудительной настройкой D3, на которые установлены. исправлено = true. Если я установил значения .x или .y, сами узлы не переместятся в их новую позицию.Перемещение фиксированных узлов в D3

Вот моя функция:

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; 
      } 
     } 
    } 
} 

UPDATE 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(); 
} 

ответ

12

Компоновка сила направленная отсоединяется от фактический рендеринг. Обычно у вас есть обработчик тика, который обновляет атрибуты ваших элементов 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 с теми же значениями, если вы хотите, чтобы узел оставаться в определенном положении.

+0

Спасибо, теперь я понимаю. Я просто проверял поведение и хотел указать на то, что может отбросить людей, которые приходят из примеров по умолчанию: вам нужно изменить значения px/py, а также значения x/y, если узел перемещается. Я опубликую обновленную функцию выше. – Elijah

Смежные вопросы