Поиск…


Синтаксис

  • d3. выбрать (селектор)
  • d3. selectAll (селектор)
  • выбор . выбрать (селектор)
  • выбор . selectAll (селектор)
  • выбор . фильтр (фильтр)
  • выбор . слияние (другое)

замечания

Связанные чтения:

Основной выбор и модификации

Если вы знакомы с синтаксисом jQuery и Sizzle, выбор d3 не должен сильно отличаться. d3 имитирует API-переключатели W3C, чтобы упростить взаимодействие с элементами.

В базовом примере выберите все <p> и добавьте изменения для каждого из них:

d3.selectAll('p')
  .attr('class','textClass') 
  .style('color', 'white');

В двух словах это относительно то же самое, что и в jQuery

$('p')
  .attr('class','textClass') 
  .css('color, 'white')

Как правило, вы начинаете с одного выбора в вашем контейнере div, чтобы добавить элемент SVG, который будет назначен переменной (обычно называемой svg).

var svg = d3.select('#divID').append('svg');

Отсюда мы можем вызвать svg для выполнения наших подселекций нескольких объектов (даже если они еще не существуют).

svg.selectAll('path')

Различные селекторы

Вы можете выбирать элементы с разными селекторами:

  • по тегу: "div"
  • по классу: ".class"
  • по id: "#id"
  • по атрибуту: "[color=blue]"
  • множественные селекторы (OR): "div1, div2, class1"
  • множественные селекторы (AND): "div1 div2 class1"

Простой ограниченный выбор данных

var myData = [
    { name: "test1", value: "ok" },
    { name: "test2", value: "nok" }
]

// We have to select elements (here div.samples)
// and assign data. The second parameter of data() is really important,
// it will determine the "key" to identify part of data (datum) attached to an 
// element.
var mySelection = d3.select(document.body).selectAll("div.samples") // <- a selection
                   .data(myData, function(d){ return d.name; }); // <- data binding

// The "update" state is when a datum of data array has already
// an existing element associated.
mySelection.attr("class", "samples update")

// A datum is in the "enter" state when it's not assigned
// to an existing element (based on the key param of data())
// i.e. new elements in data array with a new key (here "name")
mySelection.enter().append("div")
    .attr("class", "samples enter")
    .text(function(d){ return d.name; });

// The "exit" state is when the bounded datum of an element
// is not in the data array
// i.e. removal of a row (or modifying "name" attribute)
// if we change "test1" to "test3", "test1" bounded
//          element will figure in exit() selection
// "test3" bounded element will be created in the enter() selection
mySelection.exit().attr("class", "samples remove");

Роль заполнителей в настройках «ввода»

Что такое выбор ввода?

В D3.js, когда один связывает данные с элементами DOM, возможны три ситуации:

  1. Количество элементов и количество точек данных одинаковы;
  2. Есть больше элементов, чем точек данных;
  3. Есть больше точек данных, чем элементов;

В ситуации № 3 все точки данных без соответствующего элемента DOM относятся к выбору ввода . Таким образом, в D3.js введите выбор - это выбор, который после присоединения элементов к данным содержит все данные, которые не соответствуют ни одному элементу DOM. Если мы будем использовать функцию append в выборе ввода , D3 создаст новые элементы, связывающие эти данные для нас.

Это диаграмма Венна, объясняющая возможные ситуации относительно количества точек данных / количества элементов DOM:

введите описание изображения здесь

Как видим, выбор ввода - это синяя область слева: точки данных без соответствующих элементов DOM.

Структура выбора ввода

Как правило, для ввода введите следующие 4 шага:

  1. selectAll : выбор элементов в DOM;
  2. data : подсчитывает и анализирует данные;
  3. enter : сравнивая выбор с данными, создайте новые элементы;
  4. append : добавьте фактические элементы в DOM;

Это очень простой пример (посмотрите на 4 шага в var divs ):

var data = [40, 80, 150, 160, 230, 260];

var body = d3.select("body");

var divs = body.selectAll("div")
    .data(data)
    .enter()
    .append("div");

divs.style("width", function(d) { return d + "px"; })
    .attr("class", "divchart")
    .text(function(d) { return d; });

И это результат ( jsfiddle здесь ):

введите описание изображения здесь

Обратите внимание, что в этом случае мы использовали selectAll("div") в качестве первой строки в нашей переменной выбора «enter». У нас есть набор данных с 6 значениями, а D3 создал для нас 6 разделов.

Роль заполнителей

Но предположим, что у нас уже есть div в нашем документе, что-то вроде <div>This is my chart</div> вверху. В этом случае, когда мы пишем:

body.selectAll("div")

мы выбираем существующий div. Таким образом, наш выбор ввода будет иметь только 5 опорных точек без соответствующих элементов. Например, в этом jsfiddle , где уже есть div в HTML («Это моя диаграмма»), это будет результат:

введите описание изображения здесь

Мы больше не видим значения «40»: наш первый «бар» исчез, и причина в том, что наш «вводный» выбор теперь имеет всего 5 элементов.

Здесь мы должны понимать, что в первой строке нашей переменной выбора ввода selectAll("div") эти divs являются просто заполнителями . Нам не нужно выбирать все divs если мы добавляем divs или весь circle если мы добавляем circle . Мы можем выбрать разные вещи. И, если мы не планируем иметь «обновление» или «выход», мы можем выбрать что угодно :

var divs = body.selectAll(".foo")//this class doesn't exist, and never will!
    .data(data)
    .enter()
    .append("div");

Таким образом, мы выбираем все «.foo». Здесь «foo» - это класс, который не только не существует, но и никогда не создается нигде в коде! Но это не имеет значения, это только местозаполнитель. Логика такова:

Если в вашем «вводном» выборе вы выбираете то, что не существует, ваш выбор «войти» всегда будет содержать все ваши данные.

Теперь, выбрав .foo , наш «ввод» выбор имеет 6 элементов, даже если у нас уже есть div в документе:

введите описание изображения здесь

И вот соответствующий jsfiddle .

Выбор null

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

Таким образом, для выбора ввода просто выполните:

selection.selectAll(null)
    .data(data)
    .enter()
    .append(element);

Вот демонстрационная скрипта: https://jsfiddle.net/gerardofurtado/th6s160p/

Заключение

Когда вы занимаетесь выбором «войти», проявляйте особую осторожность, чтобы не выбирать то, что уже существует. Вы можете использовать что-либо в своем selectAll , даже вещи, которые не существуют и никогда не будут существовать (если вы не планируете иметь «обновление» или «выход»).

Код в примерах основан на этом коде Mike Bostock: https://bl.ocks.org/mbostock/7322386

Использование «this» со стрелкой

Большинство функций в D3.js принимают анонимную функцию в качестве аргумента. .attr примерами являются .attr , .style , .text , .on и .data , но список намного больше.

В таких случаях анонимная функция оценивается для каждого выбранного элемента, чтобы:

  1. Текущая дата ( d )
  2. Текущий индекс ( i )
  3. Текущая группа ( nodes )
  4. this как текущий элемент DOM.

В качестве аргументов передаются данные, индекс и текущая группа, известный первый, второй и третий аргументы в D3.js (параметры которого традиционно называются d , i и p в D3 v3.x). Однако для использования this не нужно использовать никаких аргументов:

.on("mouseover", function(){
    d3.select(this);
});

Вышеприведенный код выберет this когда мышь над элементом. Проверьте, работает ли эта скрипта: https://jsfiddle.net/y5fwgopx/

Функция стрелки

В качестве нового синтаксиса ES6 функция стрелки имеет более короткий синтаксис по сравнению с выражением функции. Тем не менее, для программиста D3, который использует this постоянно, есть ловушка: функция стрелки не создает свой собственный this контекст. Это означает, что в функции стрелки this имеет свое первоначальное значение из охватывающего контекста.

Это может быть полезно при нескольких обстоятельствах, но это проблема для кодера, привыкшего использовать this в D3. Например, используя тот же пример в приведенной выше скрипте, это не сработает:

.on("mouseover", ()=>{
    d3.select(this);
});

Если вы сомневаетесь в этом, вот скрипка: https://jsfiddle.net/tfxLsv9u/

Ну, это не большая проблема: при необходимости можно просто использовать регулярное, старомодное выражение функции. Но что, если вы хотите написать весь свой код с помощью функций стрелок? Возможно ли иметь код со стрелками и по- прежнему использовать this в D3?

Второй и третий аргументы

Ответ - да , потому что this то же самое из nodes[i] . Подсказка действительно присутствует во всем D3 API, когда она описывает это:

... с this в качестве текущего элемента DOM ( nodes[i] )

Объяснение простое: поскольку nodes представляют собой текущую группу элементов в DOM, а i - индекс каждого элемента, nodes[i] относятся к текущему самому элементу DOM. То есть, this .

Поэтому можно использовать:

.on("mouseover", (d, i, nodes) => {
    d3.select(nodes[i]);
});

И вот соответствующая скрипка: https://jsfiddle.net/2p2ux38s/



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow