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

OSCHINA-MIRROR/x5017-Learn-D3

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

Соединение данных D3

В этом разделе мы рассмотрим, как соединять массивы данных с D3 Selection. Мы обсудим, как создавать соединения данных, как обновлять соединения данных и как соединять массивы объектов. Data Joins (соединения данных) создают соответствие между массивами данных и выборками HTML или SVG элементов. Соединение массива с HTML/SVG элементами означает:

  • Добавление или удаление HTML (или SVG) элементов, чтобы каждый элемент массива имел соответствующий HTML (или SVG) элемент
  • Каждый HTML/SVG элемент может быть изменен по размеру и стилю в соответствии со значением соответствующего элемента массива. Например, предположим, что у вас есть массив из пяти чисел, и вы хотите соединить его с элементами circle:
[40, 10, 20, 60, 30]

Установите радиус каждого круга равным соответствующему значению массива. Радиус первого круга равен 40, радиус второго круга равен 10 и так далее:

d3.select('.chart')
  .selectAll('circle')
  .data(myData)
  .join('circle')
  .attr('cx', function(d, i) {
    return i * 100;
  })
  .attr('cy', 50)
  .attr('r', function(d) {
    return d;
  })
  .style('fill', 'blue');

Попробуйте редактировать пример выше на Codepen

Как создать соединение данных

 > Перед версией 5 D3, `Data Joins` (соединения данных) были не такими простыми для понимания (вы должны были знать `enter, exit, append, remove`). К счастью, для версий 5+ `data joining` стало гораздо проще! **[d3 V-1.4 join notebook](https://observablehq.com/@d3/selection-join)**
 Общий шаблон для создания соединения данных выглядит так:
d3.select(container) // container css-селектор обычно представляет собой один элемент html/svg-контейнер
  .selectAll(element-type) // element-type определяет тип элемента, который будет соединен, например circle / div
  .data(array) // array имя массива, который будет соединен
  .join(element-type); // выполнить соединение

Обычно используются четыре метода функции в соединении данных:

  • .select определяет элемент, который будет служить контейнером (или родителем) для соединения HTML/SVG элементов.
  • .selectAll определяет тип элемента, который будет соединен с каждым элементом массива.
  • .data определяет массив, который будет соединен.
  • .join выполняет соединение. Можно добавлять и удалять HTML/SVG элементы. Пример: дан массив:
let myData = [40, 10, 20, 60, 30];

И элемент svg с элементом g:

<svg>
  <g class="chart">
  </g>
</svg>

Вы можете использовать следующий метод для соединения элементов myData с circle:

let myData = [40, 10, 20, 60, 30];
d3.select('.chart')
 .selectAll('circle')
 .data(myData)
 .join('circle');

В этом примере:

  • контейнером является элемент g
  • тип элемента — circle
  • массив, который мы добавляем, — это myData Запуск этого кода создаст 5 кругов:
<svg>
  <g class="chart">
    <circle></circle>
    <circle></circle>
    <circle></circle>
    <circle></circle>
    <circle></circle>
  </g>
</svg>
```**Однако при открытии интерфейса ничего не будет видно (пустое поле)**, так как радиус каждого круга равен нулю. Однако, если вы раскроете SVG-элемент, вы увидите, что добавлено пять элементов `circle`:
![](https://www.d3indepth.com/img/datajoins/5circles.png)
### Обновление связанных элементов
`.join` возвращает выборку, содержащую все связанные элементы, которые можно обновить с помощью методов, таких как `.attr`, `.style`, и т. д.
Например, можно установить центр, радиус и цвет каждого круга следующим образом:

var myData = [40, 10, 20, 60, 30]; d3.select('.chart') .selectAll('circle') .data(myData) .join('circle') .attr('cx', 200) .attr('cy', 50) .attr('r', 40) .style('fill', 'orange');

![](./image/image-20220816113151384.png)
Вы увидите только один круг, так как все пять кругов имеют одинаковые размеры и положение.
> [Попробуйте редактировать этот пример на Codepen](https://codepen.io/wantnocode/pen/xxWQOEw)
### Данные-ориентированные обновления
Если передать функцию в `.attr`, или можно обновить HTML/SVG-элементы в **данных-ориентированном** стиле с помощью `.style`.
Функция вызывается для каждого элемента в выборке. Она принимает два параметра, обычно называемых `d` и `i`.
Первый параметр (`d`) представляет соответствующий элемент массива (или "соединительное значение"). Второй параметр `i` представляет индекс элемента в выборке.
Значение, возвращенное функцией, используется для установки значения атрибута или стиля.
Давайте передадим функцию в первый `.attr`.attr`:

var myData = [40, 10, 20, 60, 30]; d3.select('.chart') .selectAll('circle') .data(myData) .join('circle') .attr('cx', function(d, i) { return i * 100; }) .attr('cy', 50) .attr('r', 40) .style('fill', 'blue');

D3 установит атрибут `cx` каждого круга в значение `i * 100`. `i` — это индекс в выборке, поэтому первый круг будет расположен в `0`, следующий в `100`, и так далее:
![](./image/image-20220816112622993.png)
> [Попробуйте редактировать пример выше на Codepen](https://codepen.io/wantnocode/pen/oNqQxrj)
Теперь давайте установим `r` в зависимости от значений соединения:

var myData = [40, 10, 20, 60, 30]; d3.select('.chart') .selectAll('circle') .data(myData) .join('circle') .attr('cx', function(d, i) { return i * 100; }) .attr('cy', 50) .attr('r', function(d) { return d / 2; }) .style('fill', 'blue');

![](./image/image-20220816112826890.png)
> [Попробуйте редактировать пример выше на Codepen](https://codepen.io/wantnocode/pen/MWVzeKx)
Вы можете вставить сколько угодно логики в функции, переданные в `.attr` и `.style`. Например, если значение соединения больше 30, давайте закрасим круги:

var myData = [40, 10, 20, 60, 30]; d3.select('.chart') .selectAll('circle') .data(myData) .join('circle') .attr('cx', function(d, i) { return i * 100; }) .attr('cy', 50) .attr('r', function(d) { return d / 2; }) .style('fill', function(d) { return d > 30 ? 'orange' : 'blue'; });

![](./image/image-20220816113027753.png)
> [Попробуйте редактировать пример выше на Codepen](https://codepen.io/wantnocode/pen/LYdXZZN)
### Добавление массива объектов со связями
При построении данных с использованием D3 вы обычно связываете массив объектов (а не массив чисел).Например:

var persons = [ { name: 'A', score: 10}, { name: 'B', score: 20}, { name: 'C', score: 30}, { name: 'D', score: 40}, { name: 'E', score: 50} ];

Вы можете добавить массив объектов так же, как и раньше. Однако, когда вы передаете функцию в `. attr` или `. style`, параметр `d` является объектом. Это означает, что вы обычно обращаетесь к его **свойствам**.
Например:

. attr('r', function(d) { return d. score; })

Полный пример:

var persons = [ { name: 'A', score: 10}, { name: 'B', score: 20}, { name: 'C', score: 30}, { name: 'D', score: 40}, { name: 'E', score: 50} ]; d3. select('. chart') . selectAll('circle') . data(persons) . join('circle') . attr('cx', function(d, i) { return (i+1) * 100; }) . attr('cy', 50) . attr('r', function(d) { return d. score; }) . style('fill', 'blue');

!  [image-20220816113925241](. /image/image-20220816113925241. png)
> [Попробуйте редактировать пример выше на Codepen](https://codepen. io/wantnocode/pen/)io/wantnocode/pen/jOzQrMQ)
Создайте простой столбчатый график. Установите `circle` как элемент `rect`, а не добавляйте элемент `text`:

var persons = [ { name: 'A', score: 10}, { name: 'B', score: 20}, { name: 'C', score: 30}, { name: 'D', score: 40}, { name: 'E', score: 50} ]; // Добавьте rect d3. select('. bars') . selectAll('rect') . data(persons) . join('rect') . attr('height', 19) . attr('width', function(d) { return d. score * 10; }) . attr('y', function(d, i) { return i * 20; });

! [](. /image/image-20220816114355759. png)
График также можно дополнить элементом `text` для описания:

d3. select('. labels') . selectAll('text') . data(persons) . join('text') . attr('y', function(d, i) { return i * 20 + 13; }) . text(function(d) { return d. name; });

! [](. /image/image-20220816114504454. png)
Ух ты!Здесь мы можем использовать D3 для создания простого столбчатого графика. Поздравляем!
> [Попробуйте редактировать пример на Codepen](https://codepen.io/wantnocode/pen/JjLeRmZ)
**Пример, предположим, у вас есть двумерный массив, который вы хотите добавить в таблицу `table`:**

[ [1, 2, 3, 5], [11, 22, 33, 55], [111, 222, 333, 555], [1111, 2322, 3333, 5555] ];

Выберите элемент `body`, добавьте элемент `table`, последовательно выберите элементы `data join`, затем снова `data join`:

d3.select("body") .append("table") .selectAll("tr") .data(matrix) .join("tr") .selectAll("td") .data(d => d) .join("td") .text(d => d);

![](./image/image-20220816142744677.png)
> [Попробуйте редактировать пример на Codepen](https://codepen.io/wantnocode/pen/KKorzoQ)
## Обновление данных, обновление графика
Если массив данных изменится, вам потребуется снова выполнить соединение (data join).
Поэтому мы обычно помещаем код соединения в функцию. Каждый раз, когда данные изменяются, мы вызываем эту функцию.
Обычно функция называется `update`. Например:

var myData = [40, 10, 20, 60, 30]; function update(data) { d3.select('.chart') .selectAll('circle') .data(data) .join('circle') .attr('cx', function(d, i) { return (i + 1) * 100; }) .attr('cy', 50) .attr('r', function(d) { return 0.5 * d; }) .style('fill', function(d) { return d > 30 ? 'orange' : 'blue'; }); } update(myData);

![](./image/image-20220816135540864.png)
В предыдущем примере данные никогда не изменяются, поэтому добавим кнопку, нажатие на которую получает случайные данные и вызывает `update`:

function getData() { let data = []; for (let i = 0; i < 5; i++) { data.push(Math.random() * 100); } update(data); }

random() * 60);
    }
    return data;
  }
  function update(data) {
    d3.select('.chart')
      .selectAll('circle')
      .data(data)
      .join('circle')
      .attr('cx', function(d, i) {
        return i * 100;
      })
      .attr('cy', 50)
      .attr('r', function(d) {
        return 0.5 * d;
      })
      .style('fill', function(d) {
        return d > 30 ? 'orange' : 'blue';
      });
  }
  function updateAll() {
    let myData = getData();
    update(myData);
  }
  updateAll();
  d3.select("button")
    .on("click", updateAll);
  ```
  ![](./image/image-20220816140559639.png)
  Функция `getData` возвращает массив случайных чисел. Таким образом, каждый раз при нажатии на кнопку данные и круги обновляются.
  > [Попробуйте редактировать пример на CodePen](https://codepen.io/wantnocode/pen/RwMqGyd)
  ### Отладка
  Когда D3 выполняет соединение данных, он добавляет свойство `__data__` для каждого элемента DOM в выборке и присваивает ему соединенные данные.
  Мы можем щелкнуть элемент в Google Chrome, выбрать "Проверить" и ввести в консоль: (`$0` представляет элемент, который мы проверяем. )
  ```javascript
  $0.__data__
  ```
  ![](C:\Users\Administrator\Desktop\d3-debug.gif)
  Такой способ проверки соединенных данных особенно полезен при отладке, так как он позволяет проверить, работает ли соединение данных так, как мы ожидаем.
```

Опубликовать ( 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