Силовая модель в D3.js представляет собой численную симуляцию системы частиц (узлов графа), на которые действуют абстрактные физические силы. Каждый узел имеет координаты, скорость и массу, а поведение системы формируется набором независимых силовых функций. На каждом шаге симуляции вычисляются новые ускорения и обновляются позиции.
Основная сущность — симуляция, к которой подключаются силы:
const simulation = d3.forceSimulation(nodes);
Каждая сила добавляется через:
simulation.force("name", d3.forceX(...));
Система работает итеративно: на каждом тике пересчитываются взаимодействия между узлами и внешними полями.
Сила forceCenter задаёт точку притяжения, к которой
стремится вся система. Она не фиксирует узлы жёстко, а создаёт мягкое
смещение координат, стабилизируя граф в пределах заданной области.
d3.forceCenter(width / 2, height / 2)
Каждый узел получает корректировку координат:
forceCenter не учитывает массу узлов и не формирует
локальные структуры.
forceManyBody реализует взаимодействие всех узлов со
всеми остальными. Поведение напоминает электростатические силы: узлы
могут отталкиваться или притягиваться.
d3.forceManyBody()
.strength(-50)
Для каждого узла:
Полная сложность (O(n^2)) заменяется приближёнными алгоритмами (например, квадродерево Barnes–Hut), что позволяет работать с большими графами.
forceLink формирует ограничения между узлами, задавая
«ребра» графа как пружины.
d3.forceLink(links)
.id(d => d.id)
.distance(80)
.strength(1)
Каждая связь между двумя узлами рассматривается как пружина:
Определяет желаемое расстояние между связанными узлами.
Регулирует жёсткость связи:
Метод id() задаёт способ сопоставления ссылок:
.id(d => d.id)
Это необходимо при работе с объектами ссылок вида:
{ source: "A", target: "B" }
forceManyBody, балансируя
отталкиваниеforceCollide вводит радиусную модель узлов, предотвращая
наложение элементов.
d3.forceCollide()
.radius(10)
Каждый узел рассматривается как окружность:
Может задаваться как функция:
.radius(d => d.size)
Также использует пространственные индексы для оптимизации поиска потенциальных пересечений.
forceX создаёт направленное поле вдоль оси X, притягивая
узлы к заданным координатам.
d3.forceX(width / 2)
.strength(0.1)
Для каждого узла:
forceY аналогичен forceX, но действует
вдоль оси Y.
d3.forceY(height / 2)
.strength(0.1)
Силы D3 не работают изолированно. Поведение системы определяется их суммарным влиянием.
forceManyBody раздвигает узлыforceLink фиксирует расстоянияforceCenter стабилизирует всю системуforceCollide устраняет пересеченияforceX и forceY формируют глобальную
геометриюconst simulation = d3.forceSimulation(nodes)
.force("link", d3.forceLink(links).id(d => d.id).distance(80))
.force("charge", d3.forceManyBody().strength(-40))
.force("center", d3.forceCenter(width / 2, height / 2))
.force("collision", d3.forceCollide().radius(12))
.force("x", d3.forceX(width / 2).strength(0.05))
.force("y", d3.forceY(height / 2).strength(0.05));
Стабильность достигается подбором параметров:
manyBody разрушает связиlink подавляет структуруcollision может замедлить схождение системыx и y формируют глобальную сетку, но могут
«перетянуть» графНа каждом тике симуляции выполняется:
Упрощённо:
[ v = v + a t] [ x = x + v t]
Где ускорение формируется суммой всех активных сил.
Симуляция использует параметр затухания энергии:
alpha — хаотичное движениеalpha — стабилизация системыКаждый тик:
[ _{t+1} = _t decay]
Когда alpha становится ниже порога, симуляция
останавливается.
Комбинация forceCenter + forceManyBody +
forceCollide:
Комбинация forceX или forceY с
forceLink:
Усиленный forceManyBody с умеренными связями:
При росте числа элементов:
Сложные графы требуют уменьшения жёсткости связей и увеличения затухания alpha для устойчивости.
Силовая симуляция обычно привязывается к отрисовке:
simulation.on("tick", () => {
node
.attr("cx", d => d.x)
.attr("cy", d => d.y);
});
Каждый тик обновляет координаты элементов, формируя непрерывную анимацию движения системы.
Силовая модель формирует непрерывное многомерное поле:
forceCenter — точка минимума потенциальной энергииforceManyBody — поле взаимодействия частицforceLink — ограниченные потенциалы между парамиforceCollide — барьерные функцииforceX, forceY — линейные потенциальные
градиентыСистема стремится к состоянию минимальной энергии, но постоянные внешние воздействия сохраняют динамику.