2013-07-30 1 views
34

У меня есть компоновка силы, которую я создал с помощью d3.jsПочему d3.js v3 разбивает мой график силы при реализации масштабирования, когда v2 не работает?

Я хотел бы иметь как нормальную функциональность перетаскиваемого силового макета, так и возможность масштабирования.

У меня в основном скопирован/вставлен код масштабирования из этого кода (http://jsfiddle.net/nrabinowitz/QMKm3/). Это тот же самый способ масштабирования, который использует Майк Босток в этом примере (http://bl.ocks.org/mbostock/3680957).

Вот мой код: http://jsfiddle.net/kM4Hs/6/

Как можно ясно видеть в шахтах, зумирование работает отлично, но я не могу выбрать отдельные узлы в макете силы и перетащить их вокруг.

Я нашел, что причиной этого является тот факт, что оба других автора используют d3.v2.js, а не новый d3.v3.js, который я использую. Когда я меняю свой импорт на v2, он отлично работает. Однако, в интересах прогресса и просто всеобщей доброжелательности, я хотел бы использовать v3, если это возможно.

<script type='text/javascript' src='http://d3js.org/d3.v3.min.js'></script> 

        versus 

<script type='text/javascript' src='http://d3js.org/d3.v2.min.js'></script> 

Два вопроса: почему v3 разорвать макет силы, когда v2 нет, и, что более важно, что я могу сделать, если что-нибудь, чтобы исправить это?

Заранее благодарен!

ответ

76

Если вы изучите release notes, вы увидите полное объяснение всего, что изменилось между окончательной версией 2.x (2.10.3) и последней версии, 3.2.7. В частности, от выпуска 3.2.2:

Улучшенная обработка жестов перетаскивания в d3.behavior.drag, d3.behavior.zoom и d3.svg.brush, не предотвращая поведение по умолчанию или остановить распространение. Например, mousedown теперь меняет фокус, mouseup вне iframe работает правильно, и touchstart не заикается.

Итак, в V2 поведение перетаскивания может иметь приоритет над поведением масштабирования, останавливая распространение при событиях масштабирования. В V3 это больше не происходит автоматически, что дает вам выбор того, какое поведение имеет приоритет, и когда.

Если вы хотите придать приоритет поведения сопротивления при перемещении узлов, то вам нужно stopPropagation на событиях ввода при перемещении так, что эти события не может одновременно интерпретировать как панорамирование поведения масштабирования. Остановка распространения на dragstart достаточно:

var drag = d3.behavior.drag() 
    .on("dragstart", function() { d3.event.sourceEvent.stopPropagation(); }) 
    .on("drag", function() { /* handle drag event here */ }); 

При использовании макета силы, код:

var drag = force.drag() 
    .on("dragstart", function() { d3.event.sourceEvent.stopPropagation(); }); 

Рабочий пример:

drag and zoom

Примечание: комбинируя эти два поведения средства что интерпретация жестов неоднозначна и очень чувствительна к положению. Щелчок по кругу интерпретируется как перетаскивание этого круга, тогда как щелчок на один пиксель может быть интерпретирован как панорамирование фона. Более надежный метод объединения этих поведений заключается в использовании модальности. Например, если пользователь удерживает клавишу SPACE, нажатие и перетаскивание интерпретируется как панорамирование, а не перетаскивание, независимо от местоположения клика.Этот подход обычно используется в коммерческом программном обеспечении, таком как Adobe Photoshop.

+0

Я понял, что выполнение этого на макете силы, по-видимому, отменяет естественный способ компоновки реагирует на перемещение узла путем перенастройки некоторых других узлов/ребер. Я половину исправил это, имея метод перетаскивания, также обновил все ссылки, так что было достаточно легко исправить. Часть, которую я не могу понять, - это фиксация силовой функциональности. Я попытался сделать force.resume() в конце перетаскивания, но в то время как эта возобновленная сила функциональности, она также сбросила позиции всех узлов, которые я перетащил (я устанавливаю d.fixed = true в конце перетаскивания, поскольку Я хочу, чтобы перетаскиваемые узлы были исправлены). –

+6

Взгляните на пример [липкого силового макета] (http://bl.ocks.org/mbostock/3750558/5093e88c0462173a3d7b5859d7db75fbf5a7d8b8) и документацию для [force.drag] (https://github.com/mbostock/d3/вики/Force-Layout # вики-перетаскивание). Я просто обновил их. – mbostock

+0

@mbstock спасибо. пример применения липкой силы спас меня! – Saad