Пример работы с d3.js
По мотивам статьи https://bost.ocks.org/mike/circles/
Пусть даны три круга
Фрагмент из html-кода страницы:
1 2 3 4 5 |
<svg width="720" height="120"> <circle cx="40" cy="60" r="10"></circle> <circle cx="80" cy="60" r="10"></circle> <circle cx="120" cy="60" r="10"></circle> </svg> |
Рассмотрим базовые методы работы с такими элементами.
Выборка элементов
Метод d3.selectAll по заданному селектору (например, "сircle") возвращает выборку из соответствующих элементов:
1 |
var circle = d3.selectAll("circle"); |
Посредством этой переменной мы можем изменять выбранные элементы. Например, изменить цвет заливки с помощью selection.style или радиус с помощью selection.attr:
1 2 |
circle.style("fill", "steelblue"); circle.attr("r", 30); |
Данный код изменит характеристики всех элементов выборки на одни и те же значения: 30 и "steelblue".
1 2 3 4 5 |
<svg width="720" height="120"> <circle cx="40" cy="60" r="30" style="fill:steelblue;"></circle> <circle cx="80" cy="60" r="30" style="fill:steelblue;"></circle> <circle cx="120" cy="60" r="30" style="fill:steelblue;"></circle> </svg> |
Изменять значения можно и с помощью анонимной функции, которая будет выполняться для каждого элемента выборки. Такой подход типичен для D3. Давайте зададим x-координату центра каждого круга случайным образом:
1 |
circle.attr("cx", function() { return Math.random() * 720; }); |
При каждом запуске данного кода круги будут оказываться в разных местах:
1 2 3 4 5 |
<svg width="720" height="120"> <circle cx="111.33201601633772" cy="60" r="30" style="fill:steelblue;"></circle> <circle cx="457.0499064474124" cy="60" r="30" style="fill:steelblue;"></circle> <circle cx="314.05858507835796" cy="60" r="30" style="fill:steelblue;"></circle> </svg> |
Привязка данных
Пусть есть числа 32, 57 и 112. Давайте представим эти данные с помощью наших кругов. Для этого применим метод selection.data, который привяжет числа к кругам:
1 |
circle.data([32, 57, 112]); |
Выборка элементов представляет собой массив, поэтому и числа мы поместили в массив как наиболее адекватную структуру для соответствия. Заметим, что в выборку элементы попадают в том порядке, в каком определены в DOM.
Установка соответствия происходит следующим образом: первое число (32) привязывается к первому кругу, второе число (57) - ко второму кругу и так далее. После этого в attr и style в анонимных функциях становится доступен первый аргумент (мы обычно называем его d), который ссылается на привязанные данные. Пример:
1 |
circle.attr("r", function(d) { return Math.sqrt(d); }); |
Результат:
1 2 3 4 5 |
<svg width="720" height="120"> <circle cx="40" cy="60" r="5.656854249492381" style="fill:steelblue;"></circle> <circle cx="80" cy="60" r="7.54983443527075" style="fill:steelblue;"></circle> <circle cx="120" cy="60" r="10.583005244258363" style="fill:steelblue;"></circle> </svg> |
Есть еще необязательный второй аргумент: индекс элемента в выборке (рекомендуем называть его i). Он часто используется при явной зависимости характеристик элемента от его номера. Пример:
1 |
circle.attr("cx", function(d, i) { return i * 100 + 30; }); |
1 2 3 4 5 |
<svg width="720" height="120"> <circle cx="30" cy="60" r="5.656854249492381" style="fill:steelblue;"></circle> <circle cx="130" cy="60" r="7.54983443527075" style="fill:steelblue;"></circle> <circle cx="230" cy="60" r="10.583005244258363" style="fill:steelblue;"></circle> </svg> |
Обратите внимание, что в SVG начало координат находится в левом верхнем углу.
Ввод элементов
А что если у нас не три числа, а четыре? Тогда кругов недостаточно и мы должны создать еще один. Это можно сделать вручную, но удобнее использовать метод enter.