1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/x5017-Learn-D3

В этом репозитории не указан файл с открытой лицензией (LICENSE). При использовании обратитесь к конкретному описанию проекта и его зависимостям в коде.
Клонировать/Скачать
Force layout.ch.md 14 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
Отправлено 02.06.2025 20:44 467f5f5

D3-force

D3-force-layout (力布局) модуль использует алгоритм velocity Verlet для реализации числового интегратора, который моделирует физические силы, действующие на частицы. Внутреннее моделирование упрощено, предполагая, что каждый шаг имеет временной шаг Δt = 1, а масса всех частиц m = 1. Таким образом, сила F, действующая на частицу, эквивалентна постоянному ускорению a за интервал времени Δt, которое можно моделировать путем простого добавления к скорости частицы, а затем добавления к её положению. Проще говоря, D3-force-layout использует определённые физические правила для позиционирования элементов визуализации (узлов и ребер). D3 использует физическое моделирование для позиционирования визуальных элементов. Можно настроить силу между элементами, например:

  • Все элементы могут быть настроены для взаимного отталкивания
  • Все элементы могут быть привлечены к центру, что означает, что среднее положение всех узлов близко к центру.
  • Связанные элементы могут быть настроены для поддержания фиксированного расстояния
  • Используя детекцию столкновений, элементы могут быть настроены для предотвращения перекрытия Настройка позволяет force-layout позиционировать элементы в определённом способе. В этой статье мы рассмотрим, как использовать D3-force-layout и как создавать сетевые визуализации (network visualisations), кластеры (clusters). Рассмотрим следующий пример force-layout: предположим, что у нас есть много circle, которые разделены на три категории (через поле category), затем мы добавляем forces:
  • circle притягиваются друг к другу (группировка circle)
  • Детекция столкновений (предотвращение перекрытия circle)
  • circle притягиваются к одному из трёх центров (поле category: A, B или C) ! [image-20220829141644227](. /image/image-20220829141644227. png)

https://codepen. io/wantnocode/pen/jOzjXqB? editors=1111 force-layout требует больше вычислительных ресурсов по сравнению с другими алгоритмами размещения, так как его реализация внутри является итеративной. Шаги постепенно приводят к оптимальному результату.

силовое моделирование

Обычно настройка силового моделирования включает 4 шага:

  • Создание массива объектов (узлов и ребер)
  • Вызов forceSimulation, передача массива объектов (узлов)
  • Добавление одного или нескольких force functions(функций силы) (например, forceManyBody, forceCenter)
  • Установка обратного вызова, обновление положения элементов после каждого шага (tick) Рассмотрим простой пример:
let width = 300, height = 300
let nodes = [{}, {}, {}, {}, {}]
let simulation = d3. forceSimulation(nodes)
.В данном примере мы создаем простой массив из 5 объектов и добавляем два силовых функционала `forceManyBody` и `forceCenter` (где первый заставляет элементы отталкиваться друг от друга, а второй притягивает элементы к центру).Каждый раз, когда происходит итерация симуляции, вызывается функция `ticked`. Эта функция связывает массив `nodes` с элементами `circle` и обновляет их положение:

```javascript
function ticked() {
var u = d3.select('svg')
 .selectAll('circle')
 .data(nodes)
 .join('circle')
 .attr('r', 5)
 .attr('cx', function(d) {
   return d.x
 })
 .attr('cy', function(d) {
   return d.y
 });
}

https://codepen.io/wantnocode/pen/qBozLjv

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

D3 включает множество полезных функций:

  • forceCenter (для установки центра системы)
  • forceManyBody (для притяжения или отталкивания элементов друг от друга)
  • forceCollide (для предотвращения перекрытия элементов)
  • forceX и forceY (для притяжения элементов к определенной точке)
  • forceLink (для создания фиксированного расстояния между связанными элементами)

Силовые функции добавляются к симуляции с помощью .force(), где первый параметр — это определенный идентификатор, а второй параметр — сама силовая функция:

simulation.force('charge', d3.forceManyBody())

Давайте рассмотрим встроенную силовую функцию forceManyBody более подробно.

forceCenter

forceCenter полезен для центрирования всех элементов вокруг определенного центра. Если центр не задан, то по умолчанию используется [0, 0].Можно задать положение [x, y] при инициализации:

d3.forceCenter(100, 100)

Или использовать методы конфигурации .x() и .y():

d3.forceCenter().x(100).y(100)

Затем добавьте его к симуляции:

simulation.force('center', d3.forceCenter(100, 100))

forceManyBody

forceManyBody заставляет все элементы притягиваться или отталкиваться друг от друга. Можно задать силу притяжения или отталкивания, используя метод .strength(), где положительное значение приводит к притяжению элементов друг к другу, а отрицательное значение — к отталкиванию. По умолчанию значение силы равно -30.```javascript simulation.force('charge', d3.forceManyBody().strength(-20))

   > При создании сетевого графика обычно конфигурируются элементы, которые взаимоисключают друг друга. Однако для потребностей, когда элементы должны собираться вместе, необходимо конфигурировать притяжение (сила притяжения) элементов.
   >
   > https://codepen.io/wantnocode/pen/qBozLjv
   ### forceCollide
   `forceCollide` используется для предотвращения перекрытия элементов (в данном случае это `circle`) и может "собирать" их вместе.
   `radius` элемента передается в `forceCollide` с помощью метода `.radius` доступника функции. Первый параметр `d` этого метода используется для `data join`, из которого можно получить `radius`.
   Например:

let numNodes = 100 let nodes = d3.range(numNodes).map(function(d) { return {radius: Math.random() * 25} }) let simulation = d3.forceSimulation(nodes) .force('charge', d3.forceManyBody().strength(5)) .force('center', d3.forceCenter(width / 2, height / 2)) .force('collision', d3.forceCollide().radius(function(d) { return d.radius }))

! [изображение-20220829155113093](./image/изображение-20220829155113093.png)
> https://codepen.io/wantnocode/pen/GRxbzMM
> `forceManyBody` собирает все узлы вместе и удерживает узлы в центре контейнера, `forceCollide` предотвращает перекрытие узлов.
### forceX и forceY
`forceX` и `forceY` устанавливают притяжение элементов к определенной позиции. Можно использовать один центр для всех элементов или добавлять его на основе каждого элемента. Также можно использовать `.strength()` для настройки силы притяжения.  Например, предположим, что у вас есть множество элементов, каждый из которых имеет свойство `category` со значением `0`, `1` или `2`. Вы можете добавить силу `forceX`, которая притягивает элементы к координатам `100`, `300` или `500` в зависимости от значения `category`:

let xCenter = [100, 300, 500]; let simulation = d3.forceSimulation(nodes) .force('charge', d3.forceManyBody().strength(5)) .force('x', d3.forceX().x(function(d) { return xCenter[d.category]; })) .force('collision', d3.forceCollide().radius(function(d) { return d.radius; }));

!  [изображение-20220829141644227](. /image/изображение-20220829141644227. png)
> https://codepen.io/wantnocode/pen/jOzjXqB
> `forceManyBody` собирает все узлы вместе, а затем `forceX` притягивает узлы к определенной координате x. `forceCollide` предотвращает перекрытие (организует) узлов.
Если у данных есть связанные координаты, конечно, можно использовать `forceX` или `forceY` одновременно для позиционирования элементов.

. . . .force('x', d3.forceX().x(function(d) {


 вернуть d.x;
})))

.сила('y', d3.силаY().y(функция(d) { вернуть d.y; })) . . .

```markdown
### силаLink
`силаLink` перемещает элементы, связанные с одной **фиксированной дистанции (distance)**. Она требует **связей (массив связей)** для указания, какие элементы должны быть связаны. Каждый объект связи указывает `источник` (источник) элемента и `цель` (цель) элемента, где значения являются **идентификаторами id** (id) элементов (`если id отсутствует, можно использовать индексы массива`):
 ```markdown
let links = d3.range(nodes.length - 1).map(function(i) {
```     вернуть {
      источник: Math.floor(Math.sqrt(i)),
      цель: i + 1,
    };
});
let links = [
  {источник: 0, цель: 1},
  ...
]

Затем, используя метод .links(), передайте links (массив связей) в функцию силаLink:

let симуляция = d3.силаSimulation(nodes)
 .сила('charge', d3.силаManyBody().сила(-100))
 .сила('center', d3.силаCenter(width / 2, height / 2))
 .сила('link', d3.силаLink().links(links));

> https://codepen.io/wantnocode/pen/QWmXYqZ?editors=1111

силаManyBody разделяет узлы, силаCenter поддерживает центрирование узлов относительно контейнера, силаLink поддерживает фиксированное расстояние между связанными узлами.


Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/x5017-Learn-D3.git
git@api.gitlife.ru:oschina-mirror/x5017-Learn-D3.git
oschina-mirror
x5017-Learn-D3
x5017-Learn-D3
main