Библиотека D3 отлично подходит для создания многофункциональных и интерактивных визуализаций данных, работающих в вашем браузере. D3 - это библиотека JavaScript, которая обеспечивает простой мост между возможностями SVG (масштабируемая векторная графика) в браузере и вашими (и моими) собственными приложениями JavaScript. Независимо от того, используете ли вы React, Angular, Vue или какой-либо другой веб-фреймворк или программу в традиционных технологиях W3C, D3 предоставляет простые в использовании API-интерфейсы для управления объектами SVG и создания их интерактивных и анимированных. Некоторые простые шаги по работе с SVG и D3.js описаны в моей предыдущей статье Создание простой игры с D3.

Мощным компонентом библиотеки D3 является библиотека Force d3-force. Вы можете найти в Интернете потрясающие анимации, созданные с помощью d3-force. Библиотека d3-force особенно привлекательна для людей, занимающихся физикой, которые хотели бы визуализировать взаимодействия между маленькими частицами или большими телами, подчиняющиеся законам притяжения и ускорения.

Мне потребовалось время, чтобы понять, что такое d3-force и что это не так. Позвольте мне попытаться объяснить:

  • d3-force может вычислять положение и скорость элементов в системе, управляемой правилами, напоминающими законы физики, например, закон гравитации или другие силы взаимодействия или силовые поля.
  • d3-force может использоваться для определения элементов с размером, массой, начальным положением и скоростью, их местоположением и скоростью (в любой данный момент или по прошествии определенного времени) - например, чтобы найти стабильное конечное состояние (если оно существует) .
  • d3-force не действует на элементы SVG; d3-force действует на данные
  • мы можем взять результаты расчета (также называемого симуляцией) d3-force и визуализировать их с помощью элементов SVG; если мы хотим визуализировать результаты моделирования d3-force, мы должны сделать это сами, потому что это не то, что d3-force делает. После каждой итерации симуляции (называемой «галочкой») мы можем использовать промежуточные результаты вычислений и рисовать визуализацию из этих результатов с помощью SVG - или мы этого не делаем (d3-force в любом случае не заботится)
  • мы также можем позволить d3-force пройти множество этапов моделирования и использовать только «окончательный» результат для визуализации (или даже не для визуализации) возможных положений элементов в системе, используемой для моделирования.
  • d3-force можно использовать без какой-либо другой части d3 и без какой-либо степени визуализации.

Я использовал d3-force, чтобы найти способ наилучшего распределения визуальных представлений (кругов разного размера) элементов данных - без их перекрытия и с определенным отталкиванием между элементами с некоторыми характеристиками я не мог придумать хороший алгоритм для расчета позиции этих кругов; d3-force может запустить симуляцию, которая выдает приемлемые конечные положения для этих кругов.

Вот визуализированная симуляция в действии:

Суть кода, который производит такое поведение:

Библиотека d3 загружается в этот статический HTML-документ. Генерируется массив из 40 элементов. Каждому элементу назначаются рандомизированные свойства: свойства, называемые x и y, значения которых берутся из случайного диапазона от 0 до w и h (которые представляют ширину и высоту некоторой области) и r, отображаемые в радиусе круга, и цвет. Обратите внимание, что изначально это просто объекты данных - они не имеют отношения к объектам SVG, элементам HTML или чему-либо, что связано с визуализацией. Моделирование силы D3 ожидает - или создает - свойства, называемые x и y (и, возможно, vx и vy для компонентов вектора скорости и, возможно, fx и fy, чтобы указать значения x и y, которые моделирование не должно изменять).

Функция doSVG () в этом случае выполняет сопоставление этих элементов данных с объектами SVG, созданными с использованием d3, чтобы мы могли видеть анимированное представление симуляции и ее окончательного результата. И когда симуляция силы d3 воздействует на эти элементы данных, она обновляет координаты x и y, и мы используем их для перерисовки элементов SVG.

Обратите внимание, что мы можем запустить моделирование без создания каких-либо элементов SVG. Обработчик tick может просто зарегистрировать окончательные координаты x и y после ряда итераций и считать это единственным результатом моделирования.

Однако в этом случае - blipElements - это объекты круга SVG, созданные для элементов массива node_data - с использованием свойств этих элементов для рисования круга. В обработчике tick положение каждого кружка обновляется (путем настройки инструкции перевода атрибута transform) на основе вновь вычисленных значений свойств x и y.

Симуляция определяется тремя силами: силой x и y, притягивающей все элементы к центру области SVG, и силой столкновения, которая не позволяет окружностям приближаться. Расстояние между кругом и всеми остальными кругами устанавливается равным его радиусу плюс константа nodePadding.

sim = d3.forceSimulation(node_data)
.force(“x”, d3.forceX(w / 2))
.force(“y”, d3.forceY(h / 2))
.force(“collide”, d3.forceCollide().radius(d => d.r + nodePadding))

Сила x притягивает все элементы к вертикальной линии при x = 300. Сила y притягивает элементы к горизонтальной линии при y = 200. Без силы столкновения (противодействия) все элементы переместились бы на (300, 200) , все перекрывается в центре этой маленькой системы. Однако сила столкновения предотвращает столкновения (или перекрытие) и удерживает элементы на расстоянии. Каждый элемент круга не приближается к другим элементам ближе, чем его собственный радиус плюс константа заполнения узла, равная 3. Поскольку та же самая логика (определенная в функции, которая передается в d3.forceCollide (). Radius ()) применяется ко всем элементам, все круги имеют буферную зону между собой не менее 6.

Как только моделирование определено, оно запускается. Его можно остановить (с помощью sim.stop ()). И обработчики могут быть зарегистрированы с ним - например, обработчик tick, показанный здесь. После каждой итерации моделирования - когда новые значения свойств x и y были вычислены для всех элементов данных, вызывается функция, зарегистрированная как обработчик тиков. Доступны новые значения x и y, и их можно использовать для… .. чего угодно. Один из вариантов - обновить представление элементов данных в пользовательском интерфейсе, но помните, что это совершенно необязательно.

Custom Force

В дополнение к готовым силам, поставляемым в d3-force, разработчики могут включать в симуляцию собственные силы. Когда симуляция запускается, вызывается пользовательская функция силы, чтобы отрегулировать положения и скорости всех элементов в системе по своему усмотрению. Эффекты специальной силы сочетаются с эффектами других действующих сил.

Здесь вы видите эффект специальной силы, которая была определена для выталкивания элементов из центральной области, изображенной красным прямоугольником:

На всякий случай: d3-force не знает красный прямоугольник. Он нарисован исключительно для вашего удобства. Однако настраиваемая сила, добавленная к моделированию, исправляет любой элемент, попадающий в область.

Мы можем определять нестандартные силы с любой логикой, которая нам нравится - и заставлять, например, элементы круга собираться вокруг различных интересных форм.

Ресурсы

Моя предыдущая статья - Введение в SVG и D3 для создания простой игры на основе браузера https://technology.amis.nl/frontend/starting-my-own-game-studio-on-the-ease-and- the-power-of-svg /

Источники для моделирования, обсуждаемого в этой статье: https://github.com/lucasjellema/code-cafe-intro-to-svg

Статья о круговой упаковке D3 (группировка форм): разные силы x, y для каждой группы, которую мы различаем - https://www.d3-graph-gallery.com/graph/circularpacking_group.html

Документы D3 по Force - https://github.com/d3/d3-force

Демонстрация использования d3-force для моделирования солнечной системы: https://bl.ocks.org/vasturiano/54dd054d22be863da5afe2db02e033e2

Первоначально опубликовано на https://technology.amis.nl 24 мая 2021 г.