Ограниченный макет статической силы в D3js v5

#javascript #d3.js #observable #force-layout

#javascript #d3.js #наблюдаемый #принудительный макет

Вопрос:

Макет с ограниченным статическим усилием — помощь?

Как мы можем создать ограниченный макет статической силы, в котором simulation.tick() вызывается вручную?

В документации D3js мы видим, что событие «tick» не отправляется при ручном запуске sim-карты. Обычно привязка может быть наложена на значения x amp; y для каждого события tick (см. Этот макет ограниченной силы). Следовательно, этот вопрос сосредоточен на том, как сделать так, чтобы координаты x amp; y узла соответствовали границам на каждом шаге моделирования.

В качестве примера, где мы могли бы разместить границы для этого блока, чтобы значения x и y узла оставались в пределах красной рамки?

Требуется ограничивающая рамка.

Сбой # 1

Я попытался создать ограничивающую прямоугольную функцию силы. Пока не уверен, что здесь происходит.

ошибка 1

Код

Весь код для этих примеров доступен на Observable.

Комментарии:

1. Сбой произошел из-за того, что .force(«x», d3.forceX()) и .force(«y», d3.forceY()) вытягивали все до [0,0].

Ответ №1:

Проблема с вашим кодом заключается не в пропущенных событиях, а в неправильной настройке сил вашей симуляции. Исходный пример — построение с использованием значений по умолчанию для сил позиционирования d3.forceX и d3.forceY , которые равны 0. Это центрирует все вычисления вокруг начала координат. Вся сложность сосредоточена в окне просмотра путем перевода g элемента в width/2 и height/2 . Поскольку вы прокомментировали перевод, это центрирование больше не работает, что приводит к смещению ваших узлов к верхней и левой границе.

Это можно легко исправить, правильно настроив силы позиционирования:

 .force("x", d3.forceX(d3.mean(xExtent)))
.force("y", d3.forceY(d3.mean(yExtent)))
  

Это переместит центр макета в центр вашего ограничивающего прямоугольника.

Хотя это уже работает, вы можете захотеть уменьшить силу отталкивания, которая слишком велика, заставляя большинство узлов находиться на внешней границе. Уменьшение этого значения вдвое немедленно приводит к визуально приятным результатам.

 .force("charge", d3.forceManyBody().strength(-40))
  

Вот обновленный ноутбук.

Ответ №2:

Fil изменил мою ошибку № 1, чтобы создать следующее решение: введите описание изображения здесь

Код для этого решения находится в Observable.