Spec-Zone.ru › D3.js 7

d3-selection

Выборки позволяют мощно преобразовывать модель объекта документа (DOM) на основе данных: устанавливать атрибуты, стили, свойства, HTML или текстовое содержимое и многое другое. Используя присоединение данных со вхождением и выходом выборок, вы также можете добавлять или удалять элементы в соответствии с данными.

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

d3.selectAll("p")
    .attr("class", "graf")
    .style("color", "red");

Это эквивалентно:

const p = d3.selectAll("p");
p.attr("class", "graf");
p.style("color", "red");

По соглашению, методы выбора, которые возвращают текущую выборку, используют четыре пробела отступа, в то время как методы, которые возвращают новую выборку, используют только два. Это помогает выявить изменения контекста, сделав их выделенными в цепочке:

d3.select("body")
  .append("svg")
    .attr("width", 960)
    .attr("height", 500)
  .append("g")
    .attr("transform", "translate(20,20)")
  .append("rect")
    .attr("width", 920)
    .attr("height", 460);

Выборки являются неизменяемыми. Все методы выбора, которые влияют на то, какие элементы выбраны (или их порядок), возвращают новую выборку, а не изменяют текущую. Однако обратите внимание, что элементы обязательно изменяемы, так как выборки управляют преобразованиями документа!

Для получения дополнительной информации см. коллекцию d3-selection на Observable.

Установка

Если вы используете npm, npm install d3-selection. Вы также можете загрузить последнюю версию на GitHub. Для обычного HTML в современных браузерах импортируйте d3-selection из Skypack:

<script type="module">

import {selectAll} from "https://cdn.skypack.dev/d3-selection@3";

const div = selectAll("div");

</script>

Для устаревших сред вы можете загрузить пакет UMD d3-selection с CDN на основе npm, такого как jsDelivr; экспортируется глобальная переменная d3:

<script src="https://cdn.jsdelivr.net/npm/d3-selection@3"></script>
<script>

const div = d3.selectAll("div");

</script>

Попробуйте d3-selection в вашем браузере.

Справочник API

  • Выбор элементов
  • Изменение элементов
  • Присоединение данных
  • Обработка событий
  • Управление потоком
  • Локальные переменные
  • Пространства имён

Выбор элементов

Методы выбора принимают строки селекторов W3C, такие как .fancy для выбора элементов с классом fancy или div для выбора элементов DIV. Методы выбора бывают двух типов: select и selectAll: первый выбирает только первый соответствующий элемент, а второй выбирает все соответствующие элементы в порядке документа. Методы выбора верхнего уровня, d3.select и d3.selectAll, выполняют запрос ко всему документу; методы выбора подвыборок, выборка.select и выборка.selectAll, ограничивают выбор потомками выбранных элементов.

d3.selection() · Исходный код

Выбирает корневой элемент, document.documentElement. Эта функция также может использоваться для проверки выборок (instanceof d3.selection) или для расширения прототипа выбора. Например, чтобы добавить метод для проверки флажков:

d3.selection.prototype.checked = function(value) {
  return arguments.length < 1
      ? this.property("checked")
      : this.property("checked", !!value);
};

А затем для использования:

d3.selectAll("input[type=checkbox]").checked(true);
d3.select(selector) · Исходный код

Выбирает первый элемент, который соответствует заданной строке selector. Если ни один элемент не соответствует selector, возвращает пустую выборку. Если нескольким элементам соответствует selector, будет выбран только первый соответствующий элемент (в порядке документа). Например, чтобы выбрать первый элемент якоря:

const anchor = d3.select("a");

Если selector не является строкой, выбирает указанный узел; это полезно, если у вас уже есть ссылка на узел, например, this внутри обработчика событий или глобальной переменной, например, document.body. Например, чтобы сделать нажатый абзац красным:

d3.selectAll("p").on("click", function(event) {
  d3.select(this).style("color", "red");
});
d3.selectAll(selector) · Исходный код

Выбирает все элементы, которые соответствуют заданной строке selector. Элементы будут выбраны в порядке документа (сверху вниз). Если ни один элемент в документе не соответствует selector или selector имеет значение null или undefined, возвращается пустая выборка. Например, чтобы выбрать все абзацы:

const paragraph = d3.selectAll("p");

Если selector не является строкой, вместо этого выбирает указанный массив узлов; это полезно, если у вас уже есть ссылка на узлы, например, this.childNodes внутри обработчика событий или глобальной переменной, например, document.links. Узлы могут быть итератором или псевдомассивом, таким как NodeList. Например, чтобы сделать все ссылки красными:

d3.selectAll(document.links).style("color", "red");
выборка.select(selector) · Исходный код

Для каждого выбранного элемента выбирает первый дочерний элемент, который соответствует заданной строке selector. Если ни один элемент не соответствует заданному селектору для текущего элемента, элемент в текущем индексе будет null в возвращенной выборке. (Если selector равен null, каждый элемент в возвращенной выборке будет null, что приведет к пустой выборке.) Если текущий элемент имеет связанные данные, эти данные передаются соответствующему выбранному элементу. Если нескольким элементам соответствует селектор, выбирается только первый соответствующий элемент в порядке документа. Например, чтобы выбрать первый жирный элемент в каждом абзаце:

const b = d3.selectAll("p").select("b");

Если selector является функцией, она вычисляется для каждого выбранного элемента в порядке, принимая текущие данные (d), текущий индекс (i) и текущую группу (nodes), где this — текущий DOM-элемент (nodes[i]). Она должна возвращать элемент или null, если соответствующего элемента нет. Например, чтобы выбрать предыдущего брата каждого абзаца:

const previous = d3.selectAll("p").select(function() {
  return this.previousElementSibling;
});

В отличие от выборка.selectAll, выборка.select не влияет на группировку: сохраняет существующую структуру и индексы группы и передает данные (если таковые имеются) выбранным дочерним элементам. Группировка играет важную роль в соединении данных. См. Вложенные выборки и Как работают выборки для получения дополнительной информации по этому вопросу.

выборка.selectAll(selector) · Исходный код

Для каждого выбранного элемента выбирает дочерние элементы, которые соответствуют заданной строке selector. Элементы в возвращенной выборке сгруппированы по соответствующему родительскому узлу в этой выборке. Если ни один элемент не соответствует указанному селектору для текущего элемента или если selector равен null, группа в текущем индексе будет пустой. Выбранные элементы не наследуют данные из этой выборки; используйте выборка.data для передачи данных дочерним элементам. Например, чтобы выбрать жирный элемент в каждом абзаце:

const b = d3.selectAll("p").selectAll("b");

Если selector является функцией, она вычисляется для каждого выбранного элемента в порядке, принимая текущие данные (d), текущий индекс (i) и текущую группу (nodes), где this — текущий DOM-элемент (nodes[i]). Она должна возвращать массив элементов (или итератор или псевдомассив, например, NodeList) или пустой массив, если соответствующих элементов нет. Например, чтобы выбрать предыдущих и следующих братьев каждого абзаца:

const sibling = d3.selectAll("p").selectAll(function() {
  return [
    this.previousElementSibling,
    this.nextElementSibling
  ];
});

В отличие от выборка.select, выборка.selectAll влияет на группировку: каждый выбранный потомок группируется по родительскому элементу в исходной выборке. Группировка играет важную роль в соединении данных. См. Вложенные выборки и Как работают выборки для получения дополнительной информации по этому вопросу.

выборка.filter(filter) · Исходный код

Фильтрует выборку, возвращая новую выборку, которая содержит только те элементы, для которых указанный filter является истинным. Filter может быть задан либо как строка селектора, либо как функция. Если filter является функцией, она вычисляется для каждого выбранного элемента в порядке, принимая текущие данные (d), текущий индекс (i) и текущую группу (nodes), где this — текущий DOM-элемент (nodes[i]).

Например, чтобы отфильтровать выборку строк таблицы, содержащую только чётные строки:

const even = d3.selectAll("tr").filter(":nth-child(even)");

Это приблизительно эквивалентно прямому использованию d3.selectAll, хотя индексы могут отличаться:

const even = d3.selectAll("tr:nth-child(even)");

Аналогично, с использованием функции:

const even = d3.selectAll("tr").filter((d, i) => i & 1);

Или с использованием выборка.select (и избегая стрелочных функций, поскольку this необходимо для ссылки на текущий элемент):

const even = d3.selectAll("tr").select(function(d, i) { return i & 1 ? this : null; });

Обратите внимание, что :nth-child псевдокласс использует индекс с основанием 1, а не с основанием 0. Кроме того, описанные выше функции фильтрации не имеют точно такого же значения, как :nth-child; они полагаются на индекс выборки, а не на количество предшествующих элементов-братьев в DOM.

Возвращенная отфильтрованная выборка сохраняет родителей этой выборки, но, как и array.filter, не сохраняет индексы, так как некоторые элементы могут быть удалены; используйте выборка.select для сохранения индекса, если это необходимо.

END_OF_DOCUMENT_MARKER
selection.merge(other) · Source

Возвращает новую выборку, объединяющую текущую выборку с указанной выборкой или переходом other. Возвращаемая выборка имеет такое же количество групп и таких же родителей, как и текущая выборка. Любые отсутствующие (null) элементы в текущей выборке заполняются соответствующим элементом, если он присутствует (не null), из указанной выборки other. (Если у выборки other есть дополнительные группы или родители, они игнорируются.)

Этот метод используется внутренне методом selection.join для объединения выборок enter и update после связывания данных. Вы также можете выполнить объединение явно, хотя имейте в виду, что поскольку объединение основано на индексе элемента, вы должны использовать операции, сохраняющие индекс, такие как selection.select, вместо selection.filter. Например:

const odd = selection.select(function(d, i) { return i & 1 ? this : null; ));
const even = selection.select(function(d, i) { return i & 1 ? null : this; ));
const merged = odd.merge(even);

См. selection.data для получения дополнительной информации.

Этот метод не предназначен для конкатенации произвольных выборок, однако: если у текущей выборки и указанной выборки other есть элементы (не null) с одинаковым индексом, элемент текущей выборки возвращается в объединении, а элемент выборки other игнорируется.

selection.selectChild([selector]) · Source

Возвращает новую выборку с (первым) дочерним элементом каждого элемента текущей выборки, соответствующим selector. Если selector не указан, выбирается первый дочерний элемент (если есть). Если selector задан как строка, выбирается первый дочерний элемент, который соответствует (если есть). Если selector — функция, она вычисляется для каждого дочернего узла в порядке, передавая дочерний элемент (child), индекс дочернего элемента (i) и список дочерних элементов (children); метод выбирает первый дочерний элемент, для которого селектор возвращает истинное значение (если есть).

selection.selectChildren([selector]) · Source

Возвращает новую выборку с дочерними элементами каждого элемента текущей выборки, соответствующими selector. Если selector не указан, выбираются все дочерние элементы. Если selector задан как строка, выбираются соответствующие дочерние элементы (если есть). Если selector — функция, она вычисляется для каждого дочернего узла в порядке, передавая дочерний элемент (child), индекс дочернего элемента (i) и список дочерних элементов (children); метод выбирает все дочерние элементы, для которых селектор возвращает истинное значение.

selection.selection() · Source

Возвращает выборку (для симметрии с transition.selection).

d3.matcher(selector) · Source

Принимая указанный selector, возвращает функцию, которая возвращает true, если this элемент соответствует указанному селектору. Этот метод используется внутренне методом selection.filter. Например, это:

const div = selection.filter("div");

Эквивалентно:

const div = selection.filter(d3.matcher("div"));

(Хотя D3 не является слоем совместимости, эта реализация поддерживает реализации с префиксом поставщика из-за недавней стандартизации element.matches.)

d3.selector(selector) · Source

Принимая указанный selector, возвращает функцию, которая возвращает первого потомка this элемента, соответствующего указанному селектору. Этот метод используется внутренне методом selection.select. Например, это:

const div = selection.select("div");

Эквивалентно:

const div = selection.select(d3.selector("div"));
d3.selectorAll(selector) · Source

Принимая указанный selector, возвращает функцию, которая возвращает все потомки this элемента, соответствующие указанному селектору. Этот метод используется внутренне методом selection.selectAll. Например, это:

const div = selection.selectAll("div");

Эквивалентно:

const div = selection.selectAll(d3.selectorAll("div"));
d3.window(node) · Source

Возвращает окно владельца для указанного node. Если node — узел, возвращает стандартное представление владельца документа; если node — документ, возвращает его стандартное представление; в противном случае возвращает node.

d3.style(node, name) · Source

Возвращает значение свойства стиля с указанным name для указанного node. Если node имеет встроенный стиль с указанным name, возвращается его значение; в противном случае возвращается вычисленное значение свойства. См. также selection.style.

Изменение элементов

После выбора элементов используйте методы преобразования выборки для воздействия на содержимое документа. Например, чтобы установить атрибут name и стиль цвета элемента якоря:

d3.select("a")
    .attr("name", "fred")
    .style("color", "red");

Чтобы поэкспериментировать с выборками, посетите d3js.org и откройте консоль разработчика вашего браузера! (В Chrome откройте консоль с помощью ⌥⌘J.) Выберите элементы, а затем проверьте возвращаемую выборку, чтобы увидеть, какие элементы выбраны и как они сгруппированы. Вызывайте методы выбора и наблюдайте, как меняется содержимое страницы.

selection.attr(name[, value]) · Source

Если указано value, устанавливает атрибут с указанным name на указанное value для выбранных элементов и возвращает эту выборку. Если value — константа, всем элементам присваивается одинаковое значение атрибута; в противном случае, если value — функция, она вычисляется для каждого выбранного элемента в порядке, передавая текущее значение данных (d), текущий индекс (i) и текущую группу (nodes), а текущим элементом DOM является this (nodes[i]). Возвращаемое значение функции затем используется для установки атрибута каждого элемента. Значение null удалит указанный атрибут.

Если value не указан, возвращает текущее значение указанного атрибута для первого (не null) элемента в выборке. Это обычно полезно только если вы знаете, что выборка содержит ровно один элемент.

Указанный name может иметь префикс пространства имен, например xlink:href для указания атрибута href в пространстве имен XLink. См. пространства имен для отображения поддерживаемых пространств имен; дополнительные пространства имен можно зарегистрировать, добавив их в отображение.

selection.classed(names[, value]) · Source

Если value указан, присваивает или отменяет присвоение указанных CSS-классов names выбранным элементам, устанавливая атрибут class или изменяя свойство classList и возвращает эту выборку. Указанные names — строка с разделенными пробелами именами классов. Например, чтобы присвоить классы foo и bar выбранным элементам:

selection.classed("foo bar", true);

Если value имеет истинное значение, все элементы получают указанные классы; в противном случае классы отменяются. Если value — функция, она вычисляется для каждого выбранного элемента в порядке, передавая текущее значение данных (d), текущий индекс (i) и текущую группу (nodes), а текущим элементом DOM является this (nodes[i]). Возвращаемое значение функции затем используется для присвоения или отмены присвоения классов каждому элементу. Например, чтобы случайным образом назначить класс foo примерно половине выбранных элементов:

selection.classed("foo", () => Math.random() > 0.5);

Если value не указан, возвращает true тогда и только тогда, когда у первого (не null) выбранного элемента есть указанные классы. Это обычно полезно только если вы знаете, что выборка содержит ровно один элемент.

selection.style(name[, value[, priority]]) · Source

Если value указан, устанавливает свойство стиля с указанным name на указанное value для выбранных элементов и возвращает эту выборку. Если value — константа, всем элементам присваивается одинаковое значение свойства стиля; в противном случае, если value — функция, она вычисляется для каждого выбранного элемента в порядке, передавая текущее значение данных (d), текущий индекс (i) и текущую группу (nodes), а текущим элементом DOM является this (nodes[i]). Возвращаемое значение функции затем используется для установки свойства стиля каждого элемента. Значение null удалит свойство стиля. Также может быть указан необязательный priority, либо как null, либо как строка important (без восклицательного знака).

Если value не указан, возвращает текущее значение указанного свойства стиля для первого (не null) элемента в выборке. Текущее значение определяется как значение встроенного стиля элемента, если оно присутствует, а в противном случае — его вычисленное значение. Доступ к текущему значению стиля обычно полезен только если вы знаете, что выборка содержит ровно один элемент.

Предупреждение: в отличие от многих атрибутов SVG, стили CSS обычно имеют связанные единицы. Например, 3px — это допустимое значение свойства stroke-width, а 3 — нет. Некоторые браузеры неявно присваивают единицу px (пиксель) числовым значениям, но не все браузеры это делают: например, IE генерирует ошибку «неверные аргументы»!

selection.property(name[, value]) · Источник

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

Если указано значение, устанавливает свойство с указанным именем на заданное значение для выбранных элементов. Если значение является константой, то всем элементам присваивается одно и то же значение свойства; в противном случае, если значение является функцией, она вычисляется для каждого выбранного элемента в порядке следования, принимая текущее данное (d), текущий индекс (i) и текущую группу (nodes), а this — текущий DOM-элемент (nodes[i]). Значение, возвращённое функцией, затем используется для установки свойства каждого элемента. Значение null удалит указанное свойство.

Если значение не указано, возвращает значение указанного свойства для первого (не нулевого) элемента в выборе. Это полезно только если известно, что выбор содержит ровно один элемент.

selection.text([value]) · Источник

Если указано значение, устанавливает текстовое содержимое на указанное значение для всех выбранных элементов, заменяя любые существующие дочерние элементы. Если значение — константа, то всем элементам задаётся одинаковое текстовое содержимое; в противном случае, если значение — функция, она вычисляется для каждого выбранного элемента по порядку, принимая текущее данное (d), текущий индекс (i) и текущую группу (nodes), а this — текущий DOM-элемент (nodes[i]). Возвращаемое значение функции используется для установки текстового содержимого каждого элемента. Значение null очистит содержимое.

Если значение не указано, возвращает текстовое содержимое первого (не нулевого) элемента в выборе. Это полезно только если известно, что выбор содержит ровно один элемент.

selection.html([value]) · Источник

Если указано значение, устанавливает внутренний HTML на указанное значение для всех выбранных элементов, заменяя любые существующие дочерние элементы. Если значение — константа, то всем элементам задаётся одинаковый внутренний HTML; в противном случае, если значение — функция, она вычисляется для каждого выбранного элемента по порядку, принимая текущее данное (d), текущий индекс (i) и текущую группу (nodes), а this — текущий DOM-элемент (nodes[i]). Возвращаемое значение функции используется для установки внутреннего HTML каждого элемента. Значение null очистит содержимое.

Если значение не указано, возвращает внутренний HTML первого (не нулевого) элемента в выборе. Это полезно только если известно, что выбор содержит ровно один элемент.

Используйте selection.append или selection.insert для создания данных-управляемого содержимого; этот метод предназначен для ситуаций, когда вам требуется немного HTML, например, для форматирования. Кроме того, selection.html поддерживается только для HTML-элементов. SVG-элементы и другие не-HTML-элементы не поддерживают свойство innerHTML и, следовательно, несовместимы с selection.html. Рассмотрите использование XMLSerializer для преобразования поддерева DOM в текст. См. также innersvg полифил, который предоставляет заглушку для поддержки свойства innerHTML в SVG-элементах.

selection.append(type) · Источник

Если указанный тип — строка, добавляет новый элемент этого типа (имя тега) как последнего потомка каждого выбранного элемента или перед следующим следующим элементом в выборе обновления, если это выбор ввода. Последнее поведение для выборов ввода позволяет вставлять элементы в DOM в порядке, соответствующем новым связанным данным; однако обратите внимание, что selection.order может всё ещё потребоваться, если обновление элементов меняет порядок (т.е., если порядок новых данных не соответствует старым данным).

Если указанный тип — функция, она вычисляется для каждого выбранного элемента в порядке следования, принимая текущее данное (d), текущий индекс (i) и текущую группу (nodes), а this — текущий DOM-элемент (nodes[i]). Эта функция должна возвращать элемент для добавления. (Функция обычно создаёт новый элемент, но может вместо этого вернуть существующий элемент.) Например, чтобы добавить абзац к каждому элементу DIV:

d3.selectAll("div").append("p");

Это эквивалентно:

d3.selectAll("div").append(() => document.createElement("p"));

Что эквивалентно:

d3.selectAll("div").select(function() {
  return this.appendChild(document.createElement("p"));
});

В обоих случаях этот метод возвращает новый выбор, содержащий добавленные элементы. Каждый новый элемент наследует данные текущих элементов, если таковые имеются, аналогично selection.select.

Указанное имя может иметь префикс пространства имён, такой как svg:text для указания атрибута text в пространстве имён SVG. См. пространства имён для карты поддерживаемых пространств имён; дополнительные пространства имён могут быть зарегистрированы путём добавления в карту. Если пространство имён не указано, оно будет унаследовано от родительского элемента; или, если имя — один из известных префиксов, будет использовано соответствующее пространство имён (например, svg подразумевает svg:svg).

selection.insert(type[, before]) · Источник

Если указанный тип — строка, вставляет новый элемент этого типа (имя тега) перед первым элементом, соответствующим указанному селектору before, для каждого выбранного элемента. Например, селектор before :first-child вставит узлы перед первым потомком. Если before не указан, он по умолчанию равен null. (Чтобы добавлять элементы в порядке, соответствующем связанным данным, используйте selection.append.)

И тип, и before могут быть указаны как функции, которые вычисляются для каждого выбранного элемента в порядке следования, принимая текущее данное (d), текущий индекс (i) и текущую группу (nodes), а this — текущий DOM-элемент (nodes[i]). Функция type должна возвращать элемент для вставки; функция before должна возвращать дочерний элемент, перед которым должен быть вставлен элемент. Например, чтобы добавить абзац к каждому элементу DIV:

d3.selectAll("div").insert("p");

Это эквивалентно:

d3.selectAll("div").insert(() => document.createElement("p"));

Что эквивалентно:

d3.selectAll("div").select(function() {
  return this.insertBefore(document.createElement("p"), null);
});

В обоих случаях этот метод возвращает новый выбор, содержащий добавленные элементы. Каждый новый элемент наследует данные текущих элементов, если таковые имеются, аналогично selection.select.

Указанное имя может иметь префикс пространства имён, такой как svg:text для указания атрибута text в пространстве имён SVG. См. пространства имён для карты поддерживаемых пространств имён; дополнительные пространства имён могут быть зарегистрированы путём добавления в карту. Если пространство имён не указано, оно будет унаследовано от родительского элемента; или, если имя — один из известных префиксов, будет использовано соответствующее пространство имён (например, svg подразумевает svg:svg).

selection.remove() · Источник

Удаляет выбранные элементы из документа. Возвращает этот выбор (удалённые элементы), которые теперь отсоединены от DOM. В настоящее время нет специального API для добавления удалённых элементов обратно в документ; однако вы можете передать функцию в selection.append или selection.insert для повторного добавления элементов.

selection.clone([deep]) · Источник

Вставляет копии выбранных элементов сразу после выбранных элементов и возвращает выбор вновь добавленных копий. Если deep имеет истинное значение, дочерние узлы выбранных элементов также будут клонированы. В противном случае будут клонированы только сами элементы. Эквивалентно:

selection.select(function() {
  return this.parentNode.insertBefore(this.cloneNode(deep), this.nextSibling);
});
selection.sort(compare) · Источник

Возвращает новый выбор, содержащий копию каждой группы в этом выборе, отсортированную в соответствии с функцией compare. После сортировки элементы повторно вставляются в соответствии с полученным порядком (согласно selection.order).

Функция compare, которая по умолчанию — ascending, получает два элемента данных a и b для сравнения. Она должна возвращать отрицательное, положительное или нулевое значение. Если отрицательное, то a должен быть перед b; если положительное, то a должен быть после b; в противном случае a и b считаются равными, и порядок произвольный.

Обратите внимание, что сортировка не гарантирует стабильность; однако она гарантирует такое же поведение, как встроенный в ваш браузер метод sort для массивов.

selection.order() · Источник

Перевставляет элементы в документ таким образом, что порядок элементов в каждой группе соответствует порядку выбора. Это эквивалентно вызову selection.sort, если данные уже отсортированы, но намного быстрее.

selection.raise() · Исходный код

Перевставляет каждый выбранный элемент в порядке следования в качестве последнего дочернего элемента его родителя. Эквивалентно:

selection.each(function() {
  this.parentNode.appendChild(this);
});
selection.lower() · Исходный код

Перевставляет каждый выбранный элемент в порядке следования в качестве первого дочернего элемента его родителя. Эквивалентно:

selection.each(function() {
  this.parentNode.insertBefore(this, this.parentNode.firstChild);
});
d3.create(name) · Исходный код

Учитывая указанное имя элемента name, возвращает выборку из одного элемента, содержащую открепленный элемент заданного имени в текущем документе. Этот метод предполагает использование HTML-пространства имен, поэтому при создании SVG или других элементов, отличных от HTML, необходимо явно указать пространство имен; см. namespace для получения подробной информации о поддерживаемых префиксах пространства имен.

d3.create("svg") // equivalent to svg:svg
d3.create("svg:svg") // more explicitly
d3.create("svg:g") // an SVG G element
d3.create("g") // an HTML G (unknown) element
d3.creator(name) · Исходный код

Учитывая указанное имя элемента name, возвращает функцию, которая создаёт элемент заданного имени, предполагая, что this является родительским элементом. Этот метод используется внутри selection.append и selection.insert для создания новых элементов. Например, это:

selection.append("div");

Эквивалентно:

selection.append(d3.creator("div"));

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

Объединение данных

Для знакомства с объединением данных в D3 см. блокнот selection.join. Также см. Thinking With Joins.

selection.data([data[, key]]) · Исходный код, Примеры

Связывает указанный массив data с выбранными элементами, возвращая новую выборку, представляющую выборку update: элементы, успешно связанные с данными. Также определяет выборки enter и exit в возвращаемой выборке, которые можно использовать для добавления или удаления элементов в соответствии с новыми данными. Указанные data — массив произвольных значений (например, чисел или объектов), или функция, возвращающая массив значений для каждой группы. При назначении данных элементу они хранятся в свойстве __data__, делая данные «прилипающими» и доступными при повторном выборе.

Data указывается для каждой группы в выборке. Если у выборки есть несколько групп (например, d3.selectAll, за которым следует selection.selectAll), то data обычно нужно указывать как функцию. Эта функция будет вычисляться для каждой группы в порядке следования, получая родительский фрагмент данных группы (d, который может быть неопределённым), индекс группы (i) и родительские узлы выборки (nodes), при этом this — родительский элемент группы.

В сочетании с selection.join (или более явно с selection.enter, selection.exit, selection.append и selection.remove), selection.data может использоваться для ввода, обновления и выхода элементов для соответствия данным. Например, для создания HTML-таблицы из матрицы чисел:

const matrix = [
  [11975,  5871, 8916, 2868],
  [ 1951, 10048, 2060, 6171],
  [ 8010, 16145, 8090, 8045],
  [ 1013,   990,  940, 6907]
];

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

В этом примере функция data — это функция тождества: для каждой строки таблицы она возвращает соответствующую строку из матрицы данных.

Если функция key не указана, то первый фрагмент данных в data назначается первому выбранному элементу, второй фрагмент данных — второму выбранному элементу и так далее. Функция key может быть указана для управления тем, какой фрагмент данных назначается какому элементу, заменяя стандартное объединение по индексу, вычисляя строковый идентификатор для каждого фрагмента данных и элемента. Эта функция key вычисляется для каждого выбранного элемента в порядке следования, получая текущий фрагмент данных (d), текущий индекс (i) и текущую группу (nodes), при этом this — текущий элемент DOM (nodes[i]); возвращаемая строка — ключ элемента. Затем функция key также вычисляется для каждого нового фрагмента данных в data, получая текущий фрагмент данных (d), текущий индекс (i) и новые data группы, при этом this — родительский элемент DOM группы; возвращаемая строка — ключ фрагмента данных. Фрагмент данных для заданного ключа назначается элементу с соответствующим ключом. Если у нескольких элементов одинаковый ключ, дублируемые элементы помещаются в выборку выхода; если у нескольких фрагментов данных одинаковый ключ, дублируемые фрагменты данных помещаются в выборку входа.

Например, для данного документа:

<div id="Ford"></div>
<div id="Jarrah"></div>
<div id="Kwon"></div>
<div id="Locke"></div>
<div id="Reyes"></div>
<div id="Shephard"></div>

Можно объединить данные по ключу следующим образом:

const data = [
  {name: "Locke", number: 4},
  {name: "Reyes", number: 8},
  {name: "Ford", number: 15},
  {name: "Jarrah", number: 16},
  {name: "Shephard", number: 23},
  {name: "Kwon", number: 42}
];

d3.selectAll("div")
  .data(data, function(d) { return d ? d.name : this.id; })
    .text(d => d.number);

В этом примере функция key использует фрагмент данных d, если он есть, в противном случае возвращает свойство id элемента. Поскольку эти элементы ранее не были связаны с данными, фрагмент данных d равен null, когда функция key вычисляется для выбранных элементов, и не равен null, когда функция key вычисляется для новых данных.

Выборка update и enter возвращаются в порядке данных, а выборка exit сохраняет порядок выбора до объединения. Если указана функция key, порядок элементов в выборке может не совпадать с их порядком в документе; используйте selection.order или selection.sort по мере необходимости. Более подробную информацию о том, как функция key влияет на объединение, см. в A Bar Chart, Part 2 и Object Constancy.

Если data не указан, этот метод возвращает массив данных для выбранных элементов.

Этот метод нельзя использовать для очистки связанных данных; используйте selection.datum вместо этого.

selection.join(enter[, update][, exit]) · Исходный код

Добавляет, удаляет и переупорядочивает элементы по мере необходимости для соответствия данным, которые ранее были связаны с помощью selection.data, возвращая объединённую выборку merged enter и update. Этот метод — удобная альтернатива явным общим шаблонам обновления, заменяющим selection.enter, selection.exit, selection.append, selection.remove и selection.order. Например:

svg.selectAll("circle")
  .data(data)
  .join("circle")
    .attr("fill", "none")
    .attr("stroke", "black");

Функция enter может быть указана в виде сокращенной строки, как показано выше, что эквивалентно selection.append с заданным именем элемента. Аналогично, необязательные функции update и exit могут быть указаны, которые по умолчанию соответствуют функции тождества и вызову selection.remove соответственно. Сокращение выше, таким образом, эквивалентно:

svg.selectAll("circle")
  .data(data)
  .join(
    enter => enter.append("circle"),
    update => update,
    exit => exit.remove()
  )
    .attr("fill", "none")
    .attr("stroke", "black");

Передавая отдельные функции для enter, update и exit, вы получаете больший контроль над тем, что происходит. И, указав функцию ключа для selection.data, вы можете свести изменения в DOM к минимуму для оптимизации производительности. Например, чтобы установить разные цвета заливки для enter и update:

svg.selectAll("circle")
  .data(data)
  .join(
    enter => enter.append("circle").attr("fill", "green"),
    update => update.attr("fill", "blue")
  )
    .attr("stroke", "black");

Вызовы enter и update, возвращенные функциями, объединяются и затем возвращаются методом selection.join.

Можно анимировать enter, update и exit, создавая переходы внутри функций enter, update и exit. Если функции enter и update возвращают переходы, их основанные выборки объединяются и затем возвращаются методом selection.join. Возвращаемое значение функции exit не используется.

Для получения дополнительной информации см. блокнот selection.join.

selection.enter() · Исходный код

Возвращает выборку enter: placeholder-узлы для каждого фрагмента данных, для которых не было соответствующего элемента DOM в выборке. (Выборка enter пуста для выборок, не возвращаемых методом selection.data.)

Выборка enter обычно используется для создания «отсутствующих» элементов, соответствующих новым данным. Например, для создания элементов DIV из массива чисел:

const div = d3.select("body")
  .selectAll("div")
  .data([4, 8, 15, 16, 23, 42])
  .enter().append("div")
    .text(d => d);

Если тело изначально пусто, то приведенный код создаст шесть новых элементов DIV, добавит их в тело в порядке следования и назначит их текстовое содержимое как соответствующее (преобразованное в строку) число:

<div>4</div>
<div>8</div>
<div>15</div>
<div>16</div>
<div>23</div>
<div>42</div>

По сути, placeholder-узлы выборки enter являются указателями на родительский элемент (в этом примере — тело документа). Выборка enter обычно используется только временно для добавления элементов и часто объединяется с выборкой обновления после добавления таким образом, чтобы изменения можно было применять как к входящим, так и к обновляемым элементам.

selection.exit() · Исходный код

Возвращает выборку exit: существующие элементы DOM в выборке, для которых не был найден новый фрагмент данных. (Выборка exit пуста для выборок, не возвращаемых методом selection.data.)

Выборка exit обычно используется для удаления «лишних» элементов, соответствующих старым данным. Например, для обновления элементов DIV, созданных ранее, с помощью нового массива чисел:

div = div.data([1, 2, 4, 8, 16, 32], d => d);

Поскольку была указана ключевая функция (как функция тождества), и новые данные содержат числа [4, 8, 16], которые соответствуют существующим элементам в документе, выборка обновления содержит три элемента DIV. Оставив эти элементы как есть, мы можем добавить новые элементы для [1, 2, 32] с помощью выбора ввода:

div.enter().append("div").text(d => d);

Аналогично, чтобы удалить существующие элементы [15, 23, 42]:

div.exit().remove();

Теперь тело документа выглядит так:

<div>1</div>
<div>2</div>
<div>4</div>
<div>8</div>
<div>16</div>
<div>32</div>

Порядок элементов DOM соответствует порядку данных, потому что порядок старых данных и порядок новых данных были согласованы. Если порядок новых данных отличается, используйте selection.order, чтобы переупорядочить элементы в DOM. Смотрите пример Общие шаблоны обновления, чтобы узнать больше о соединениях данных.

selection.datum([value]) · Source

Получает или устанавливает привязанные данные для каждого выбранного элемента. В отличие от selection.data, этот метод не вычисляет соединение и не влияет на индексы или выборки ввода и выхода.

Если указано значение, устанавливает привязанные данные элемента на указанное значение для всех выбранных элементов. Если значение является константой, всем элементам присваивается одно и то же значение; в противном случае, если значение является функцией, она вычисляется для каждого выбранного элемента в порядке, получая текущие данные (d), текущий индекс (i) и текущую группу (nodes), при этом this является текущим элементом DOM (nodes[i]). Затем функция используется для установки новых данных каждого элемента. Значение null удалит привязанные данные.

Если значение не указано, возвращает привязанные данные для первого (не равного null) элемента в выборке. Это обычно полезно только если вы знаете, что выборка содержит ровно один элемент.

Этот метод полезен для доступа к настраиваемым атрибутам HTML5 custom data attributes. Например, заданы следующие элементы:

<ul id="list">
  <li data-username="shawnbot">Shawn Allen</li>
  <li data-username="mbostock">Mike Bostock</li>
</ul>

Вы можете получить доступ к настраиваемым атрибутам данных, установив данные каждого элемента в качестве встроенного свойства dataset:

selection.datum(function() { return this.dataset; })

Обработка событий

Для взаимодействия выборки позволяют прослушивать и передавать события.

selection.on(typenames[, listener[, options]]) · Source

Добавляет или удаляет слушатель для каждого выбранного элемента для указанных событий typenames. typenames — это строковый тип события, например, click, mouseover, или submit; любой тип события DOM, поддерживаемый вашим браузером, может быть использован. Тип может быть необязательно последан точкой (.) и именем; необязательное имя позволяет зарегистрировать несколько обратных вызовов для получения событий того же типа, таких как click.foo и click.bar. Для указания нескольких типов имен разделите типы имен пробелами, например, input change или click.foo click.bar.

Когда для выбранного элемента передается указанное событие, указанный слушатель будет вычислен для элемента, получив текущее событие (event) и текущие данные (d), при этом this является текущим элементом DOM (event.currentTarget). Слушатели всегда видят последние данные для своего элемента. Примечание: хотя вы можете напрямую использовать event.pageX и event.pageY, часто удобно преобразовать положение события в локальную систему координат элемента, получившего событие, используя d3.pointer.

Если для выбранного элемента ранее был зарегистрирован обработчик событий для того же typename, старый обработчик удаляется перед добавлением нового. Чтобы удалить слушателя, передайте null в качестве listener. Чтобы удалить все слушатели для данного имени, передайте null в качестве listener и .foo в качестве typename, где foo — это имя; чтобы удалить все слушатели без имени, укажите . в качестве typename.

Необязательный объект options может задавать характеристики обработчика событий, такие как захват или пассивность; см. element.addEventListener.

Если listener не указан, возвращает текущего назначенного слушателя для указанного события typename на первом (не равном null) выбранном элементе, если таковой имеется. Если указано несколько типов имен, возвращается первый соответствующий слушатель.

selection.dispatch(type[, parameters]) · Source

Отправляет событие пользовательского типа указанного типа type каждому выбранному элементу в порядке. Необязательный parameters-словарь может быть указан для установки дополнительных свойств события. Он может содержать следующие поля:

  • bubbles - если true, событие отправляется предкам в обратном порядке дерева.
  • cancelable - если true, разрешено event.preventDefault.
  • detail - любые настраиваемые данные, связанные с событием.

Если parameters — функция, она вычисляется для каждого выбранного элемента в порядке, получая текущие данные (d), текущий индекс (i) и текущую группу (nodes), при этом this — текущий элемент DOM (nodes[i]). Она должна вернуть параметры-словарь для текущего элемента.

d3.pointer(event[, target]) · Source

Возвращает массив из двух чисел [x, y], представляющий координаты указанного event относительно указанного target. event может быть MouseEvent, PointerEvent, Touch или пользовательское событие, содержащее UIEvent в качестве event.sourceEvent.

Если target не указан, по умолчанию он устанавливается в свойство currentTarget исходного события, если оно доступно. Если target является элементом SVG, координаты события преобразуются с помощью обратной обратной матрицы преобразования координат экрана. Если target является элементом HTML, координаты события перемещаются относительно верхнего левого угла прямоугольника ограничивающего клиента target. (Таким образом, система координат может быть преобразована только относительно координат клиента. См. также GeometryUtils.) В противном случае возвращается [event.pageX, event.pageY].

d3.pointers(event[, target]) · Source

Возвращает массив [[x0, y0], [x1, y1]…] координат указанного event’s указателей относительно указанного target. Для событий touch, возвращаемый массив позиций соответствует массиву event.touches; для других событий возвращается массив с одним элементом.

Если target не указан, по умолчанию он устанавливается в свойство currentTarget исходного события, если оно доступно.

Управление потоком

Для расширенного использования выборки предоставляют методы для пользовательского управления потоком.

selection.each(function) · Source

Вызывает указанную функцию для каждого выбранного элемента в порядке, передавая текущие данные (d), текущий индекс (i) и текущую группу (nodes), при этом this является текущим элементом DOM (nodes[i]). Этот метод может быть использован для вызова произвольного кода для каждого выбранного элемента и полезен для создания контекста доступа к родительским и дочерним данным одновременно, например:

parent.each(function(p, j) {
  d3.select(this)
    .selectAll(".child")
      .text(d => `child ${d.name} of ${p.name}`);
});

См. Пример с размерами многократных пончиков.

selection.call(function[, arguments…]) · Source

Вызывает указанную функцию ровно один раз, передавая в неё эту выборку вместе с любыми необязательными аргументами. Возвращает эту выборку. Это эквивалентно вызову функции вручную, но облегчает цепочку методов. Например, чтобы установить несколько стилей в многократно используемой функции:

function name(selection, first, last) {
  selection
      .attr("first-name", first)
      .attr("last-name", last);
}

Теперь предположим:

d3.selectAll("div").call(name, "John", "Snow");

Это примерно эквивалентно:

name(d3.selectAll("div"), "John", "Snow");

Единственное различие заключается в том, что selection.call всегда возвращает selection, а не возвращаемое значение вызываемой функции, name.

selection.empty() · Source

Возвращает true, если эта выборка не содержит элементов (не равных null).

selection.nodes() · Source

Возвращает массив всех элементов (не равных null) в этой выборке. Эквивалентно:

const elements = Array.from(selection);

См. также selection[Symbol.iterator].

selection.node() · Источник

Возвращает первый (не равный null) элемент в этом наборе. Если набор пустой, возвращает null.

selection.size() · Источник

Возвращает общее количество (не равных null) элементов в этом наборе.

selection[Symbol.iterator]() · Источник

Возвращает итератор по выбранным (не равным null) элементам. Например, чтобы итерироваться по выбранным элементам:

for (const element of selection) {
  console.log(element);
}

Чтобы преобразовать набор в массив:

const elements = [...selection];

Локальные переменные

Локальные переменные D3 позволяют определять локальное состояние, независимое от данных. Например, при отрисовке небольших множеств временных рядов данных, вам может потребоваться одна и та же шкала x для всех диаграмм, но разные шкалы y, чтобы сравнить относительную производительность каждого показателя. Локальные переменные D3 ограничены элементами DOM: при установке значение сохраняется в заданном элементе; при получении значение извлекается из заданного элемента или ближайшего предка, который его определяет.

d3.local() · Источник

Объявляет новую локальную переменную. Например:

const foo = d3.local();

Как var, каждая локальная переменная — это отдельная символическая ссылка; в отличие от var, значение каждой локальной переменной также ограничено DOM.

local.set(node, value) · Источник

Устанавливает значение этой локальной переменной для указанного узла на значение и возвращает указанное значение. Это часто выполняется с помощью selection.each:

selection.each(function(d) { foo.set(this, d.value); });

Если вы просто устанавливаете одну переменную, рассмотрите использование selection.property:

selection.property(foo, d => d.value);
local.get(node) · Источник

Возвращает значение этой локальной переменной для указанного узла. Если узел не определяет эту локальную переменную, возвращает значение от ближайшего предка, который ее определяет. Возвращает undefined, если ни один предок не определяет эту локальную переменную.

local.remove(node) · Источник

Удаляет значение этой локальной переменной из указанного узла. Возвращает true, если узел определял эту локальную переменную до удаления, и false в противном случае. Если предки также определяют эту локальную переменную, эти определения не затрагиваются, и поэтому local.get все равно вернёт унаследованное значение.

local.toString() · Источник

Возвращает автоматически сгенерированный идентификатор для этой локальной переменной. Это имя свойства, которое используется для хранения значения локальной переменной в элементах, и поэтому вы также можете установить или получить значение локальной переменной, используя element[local] или с помощью selection.property.

Пространства имён

XML пространства имён — интересно! Правда? К счастью, ими можно в основном пренебречь.

d3.namespace(name) · Источник

Квалифицирует указанное имя, которое может или не может иметь префикс пространства имён. Если имя содержит двоеточие (:), подстрока перед двоеточием интерпретируется как префикс пространства имён, который должен быть зарегистрирован в d3.namespaces. Возвращает объект space и local атрибуты, описывающие полную URL-адрес пространства имён и локальное имя. Например:

d3.namespace("svg:text"); // {space: "http://www.w3.org/2000/svg", local: "text"}

Если имя не содержит двоеточие, эта функция просто возвращает входное имя.

d3.namespaces · Источник

Карта зарегистрированных префиксов пространства имён. Начальное значение:

{
  svg: "http://www.w3.org/2000/svg",
  xhtml: "http://www.w3.org/1999/xhtml",
  xlink: "http://www.w3.org/1999/xlink",
  xml: "http://www.w3.org/XML/1998/namespace",
  xmlns: "http://www.w3.org/2000/xmlns/"
}

Дополнительные префиксы могут быть назначены по мере необходимости для создания элементов или атрибутов в других пространствах имён.

© 2010–2023 Michael Bostock
Licensed under the BSD License.
https://github.com/d3/d3-selection

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API