d3-selection
Выборки позволяют мощно преобразовывать модель объекта документа (DOM) на основе данных: устанавливать атрибуты, стили, свойства, HTML или текстовое содержимое, и многое другое. Используя объединение данных с enter и exit выборками, вы также можете добавлять или удалять элементы, соответствующие данным.
Методы выбора обычно возвращают текущую выборку или новую выборку, что позволяет компактно применять несколько операций к заданной выборке через цепочку методов. Например, чтобы установить класс и цвет стиля всех абзацев в текущем документе:
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. В противном случае скачайте последнюю версию. Вы также можете загрузить d3-selection как автономную библиотеку или как часть D3. Поддерживаются ES модули, AMD, CommonJS и обычные среды. В обычной среде экспортируется глобальная переменная d3:
<script src="https://cdn.jsdelivr.net/npm/d3-selection@2"></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(селектор) · Исходный код
Выбирает первый элемент, который соответствует указанной строке селектора. Если ни один элемент не соответствует селектору, возвращает пустую выборку. Если несколько элементов соответствуют селектору, будет выбран только первый соответствующий элемент (в порядке документа). Например, для выбора первого элемента якоря:
const anchor = d3.select("a"); Если селектор не является строкой, вместо этого выбирается указанный узел; это полезно, если у вас уже есть ссылка на узел, такой как this в обработчике событий или глобальной переменной, такой как document.body. Например, чтобы сделать нажатый абзац красным:
d3.selectAll("p").on("click", function(event) {
d3.select(this).style("color", "red");
}); d3.selectAll(селектор) · Исходный код
Выбирает все элементы, которые соответствуют указанной строке селектора. Элементы будут выбраны в порядке документа (сверху вниз). Если ни один элемент в документе не соответствует селектору, или если селектор равен null или undefined, возвращается пустая выборка. Например, чтобы выбрать все абзацы:
const paragraph = d3.selectAll("p"); Если селектор не является строкой, вместо этого выбирается указанный массив узлов; это полезно, если у вас уже есть ссылка на узлы, такие как this.childNodes в обработчике событий или глобальной переменной, такой как document.links. Узлы могут быть вместо этого итерируемым объектом или псевдомассивом, например, NodeList. Например, чтобы сделать все ссылки красными:
d3.selectAll(document.links).style("color", "red"); выборка.select(селектор) · Исходный код
Для каждого выбранного элемента выбирается первый дочерний элемент, который соответствует указанной строке селектора. Если ни один элемент не соответствует заданному селектору для текущего элемента, элемент в текущем индексе будет равен null в возвращаемой выборке. (Если селектор равен null, каждый элемент в возвращаемой выборке будет равен null, что приведет к пустой выборке.) Если текущему элементу присвоены данные, эти данные передаются соответствующему выбранному элементу. Если несколько элементов соответствуют селектору, выбирается только первый соответствующий элемент в порядке документа. Например, чтобы выбрать первый жирный элемент в каждом абзаце:
const b = d3.selectAll("p").select("b"); Если селектор является функцией, она вычисляется для каждого выбранного элемента в порядке, получая текущее данное (d), текущий индекс (i) и текущую группу (nodes), с this как текущим DOM-элементом (nodes[i]). Она должна возвращать элемент или null, если соответствующего элемента нет. Например, чтобы выбрать предыдущего брата каждого абзаца:
const previous = d3.selectAll("p").select(function() {
return this.previousElementSibling;
}); В отличие от выборка.selectAll, выборка.select не влияет на группировку: она сохраняет существующую структуру и индексы групп и передает данные (если таковые имеются) выбранным дочерним элементам. Группировка играет важную роль в объединении данных. См. Вложенные выборки и Как работают выборки для получения дополнительной информации по этой теме.
выборка.selectAll(селектор) · Исходный код
Для каждого выбранного элемента выбираются дочерние элементы, которые соответствуют указанной строке селектора. Элементы в возвращаемой выборке сгруппированы по соответствующему родительскому узлу в этой выборке. Если ни один элемент не соответствует заданному селектору для текущего элемента, или если селектор равен null, группа в текущем индексе будет пустой. Выбранные элементы не наследуют данные из этой выборки; используйте выборка.data, чтобы передать данные дочерним элементам. Например, чтобы выбрать жирный текст в каждом абзаце:
const b = d3.selectAll("p").selectAll("b"); Если селектор является функцией, она вычисляется для каждого выбранного элемента в порядке, получая текущее данное (d), текущий индекс (i) и текущую группу (nodes), с this как текущим DOM-элементом (nodes[i]). Она должна возвращать массив элементов (или итерируемый объект, или псевдомассив, например, NodeList), или пустой массив, если соответствующих элементов нет. Например, чтобы выбрать предыдущего и следующего братьев каждого абзаца:
const sibling = d3.selectAll("p").selectAll(function() {
return [
this.previousElementSibling,
this.nextElementSibling
];
}); В отличие от выборка.select, выборка.selectAll влияет на группировку: каждый выбранный потомок группируется по родительскому элементу в исходной выборке. Группировка играет важную роль в объединении данных. См. Вложенные выборки и Как работают выборки для получения дополнительной информации по этой теме.
выборка.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, чтобы сохранить индекс, если это необходимо.
выборка.merge(другая) · Исходный код
Возвращает новую выборку, объединяющую эту выборку с указанной выборкой другая. Возвращаемая выборка имеет такое же количество групп и такие же родителей, как эта выборка. Любые отсутствующие (null) элементы в этой выборке заполняются соответствующим элементом, если он присутствует (не null), из указанной выборки. (Если другая выборка имеет дополнительные группы или родителей, они игнорируются.)
Этот метод используется внутри 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 — функция, она вычисляется для каждого выбранного элемента в порядке следования, получая на вход текущие данные (d), текущий индекс (i) и текущую группу (nodes), при этом this — текущий элемент DOM (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), при этом this — текущий элемент DOM (nodes[i]). Значение возвращаемой функции используется для назначения или отмены назначения классов каждому элементу. Например, чтобы случайным образом связать класс foo в среднем с половиной выбранных элементов:
selection.classed("foo", () => Math.random() > 0.5); Если value не указан, возвращает true тогда и только тогда, когда у первого (не null) выбранного элемента есть указанные classes. Это обычно полезно только если известно, что выделение содержит ровно один элемент.
selection.style(name[, value[, priority]]) · Source
Если указано value, устанавливает свойство стиля со значением name для указанного значения на выбранных элементах и возвращает это выделение. Если value является константой, всем элементам присваивается одинаковое значение свойства стиля; в противном случае, если value — функция, она вычисляется для каждого выбранного элемента в порядке следования, получая на вход текущие данные (d), текущий индекс (i) и текущую группу (nodes), при этом this — текущий элемент DOM (nodes[i]). Возвращаемое значение функции используется для установки свойства стиля каждого элемента. Значение null удалит свойство стиля. Также можно указать необязательный priority, как null или строку important (без восклицательного знака).
Если value не указан, возвращает текущее значение указанного свойства стиля для первого (не null) элемента в выделении. Текущее значение определяется как значение элемента, если оно присутствует, и в противном случае как его вычисленное значение. Доступ к текущему значению стиля обычно полезен только если известно, что выделение содержит ровно один элемент.
Предупреждение: в отличие от многих атрибутов SVG, CSS-стили обычно имеют связанные единицы. Например, 3px — это допустимое значение свойства stroke-width, а 3 — нет. Некоторые браузеры неявно присваивают единицу px (пиксель) числовым значениям, но не все браузеры это делают: например, IE генерирует ошибку «недействительные аргументы»!
selection.property(name[, value]) · Source
У некоторых HTML-элементов есть специальные свойства, которые недоступны с помощью атрибутов или стилей, например, текстовое значение поля формы value и булевое значение флажка checked. Используйте этот метод для получения или установки этих свойств.
Если указано значение, устанавливает свойство со значением имя на выбранные элементы. Если значение является константой, то всем элементам присваивается одинаковое значение свойства; в противном случае, если значение является функцией, она вычисляется для каждого выбранного элемента в порядке, передавая текущее данное (d), текущий индекс (i) и текущую группу (nodes), при этом this представляет собой текущий элемент DOM (nodes[i]). Возвращаемое значение функции затем используется для установки свойства каждого элемента. Значение null удалит указанное свойство.
Если значение не указано, возвращает значение указанного свойства для первого (не нулевого) элемента в выборке. Это обычно полезно только в том случае, если известно, что выборка содержит ровно один элемент.
selection.text([значение]) · Исходный код
Если указано значение, устанавливает текстовое содержимое на все выбранные элементы, заменяя любые существующие дочерние элементы. Если значение является константой, то всем элементам присваивается одинаковое текстовое содержимое; в противном случае, если значение является функцией, она вычисляется для каждого выбранного элемента в порядке, передавая текущее данное (d), текущий индекс (i) и текущую группу (nodes), при этом this представляет собой текущий элемент DOM (nodes[i]). Возвращаемое значение функции затем используется для установки текстового содержимого каждого элемента. Значение null очистит содержимое.
Если значение не указано, возвращает текстовое содержимое для первого (не нулевого) элемента в выборке. Это обычно полезно только в том случае, если известно, что выборка содержит ровно один элемент.
selection.html([значение]) · Исходный код
Если указано значение, устанавливает внутренний 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 polyfill, который предоставляет плагин для поддержки свойства innerHTML для элементов SVG.
selection.append(тип) · Исходный код
Если указанный тип является строкой, добавляет новый элемент этого типа (имя тега) в качестве последнего дочернего элемента каждого выбранного элемента или перед следующим следующим элементом в выборке обновления, если это выборка ввода. Подобное поведение для выборок ввода позволяет вставлять элементы в 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(тип[, перед]) · Исходный код
Если указанный тип является строкой, вставляет новый элемент этого типа (имя тега) перед первым элементом, соответствующим указанному селектору перед, для каждого выбранного элемента. Например, селектор перед :first-child вставит узлы перед первым дочерним элементом. Если перед не указан, он по умолчанию равен null. (Чтобы добавлять элементы в порядке, согласованном с связанными данными, используйте selection.append.)
И тип, и перед могут быть указаны как функции, которые вычисляются для каждого выбранного элемента в порядке, передавая текущее данное (d), текущий индекс (i) и текущую группу (nodes), при этом this представляет собой текущий элемент DOM (nodes[i]). Функция тип должна возвращать вставляемый элемент; функция перед должна возвращать дочерний элемент, перед которым следует вставить элемент. Например, чтобы добавить абзац к каждому элементу 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([глубоко]) · Исходный код
Вставляет копии выбранных элементов непосредственно после выбранных элементов и возвращает выборку вновь добавленных копий. Если глубоко имеет истинное значение, дочерние узлы выбранных элементов также будут клонированы. В противном случае будут клонированы только сами элементы. Эквивалентно:
selection.select(function() {
return this.parentNode.insertBefore(this.cloneNode(deep), this.nextSibling);
}); selection.sort(compare) · Исходный код
Возвращает новую выборку, содержащую копию каждой группы в этой выборке, отсортированной в соответствии с функцией compare. После сортировки, повторно вставляет элементы для соответствия полученному порядку (в соответствии с selection.order).
Функция сравнения, которая по умолчанию равна возрастанию, получает данные двух элементов 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 возвращает выборку из одного элемента, содержащую откреплённый элемент с данным именем в текущем документе. Этот метод предполагает пространство имён 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) · Source
При заданном элементе 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]]) · Source, Примеры
Связывает указанный массив 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 группы; возвращаемая строка — ключ значения. Значение для данного ключа присваивается элементу с соответствующим ключом. Если несколько элементов имеют один и тот же ключ, дублируемые элементы помещаются в выборку exit; если несколько значений имеют один и тот же ключ, дублируемые значения помещаются в выборку enter.
Например, для данного документа:
<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]) · Source
Добавляет, удаляет и переупорядочивает элементы по мере необходимости, чтобы соответствовать данным, которые были ранее связаны с помощью 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. Чтобы избежать разрыва цепочки методов, используйте selection.call для создания переходов или возвращайте неопределённую выборку enter или update, чтобы предотвратить объединение: возвращаемое значение функций enter и update определяет две выборки для объединения и возврата функцией selection.join.
Для получения дополнительной информации см. selection.join тетрадь.
selection.enter() · Source
Возвращает выборку enter: условные узлы для каждого значения данных, для которого не было соответствующего элемента 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>
Концептуально, условные узлы выборки enter являются указателями на родительский элемент (в этом примере — тело документа). Выборка enter обычно используется только временно для добавления элементов и часто объединяется с выборкой update после добавления, так что изменения могут быть применены как к входящим, так и к обновляемым элементам.
selection.exit() · Source
Возвращает выборку exit: существующие элементы DOM в выборке, для которых не было найдено нового значения данных. (Выборка exit пуста для выборок, не возвращаемых selection.data.)
Выборка exit обычно используется для удаления «лишних» элементов, соответствующих старым данным. Например, для обновления элементов DIV, созданных ранее, с новым массивом чисел:
div = div.data([1, 2, 4, 8, 16, 32], d => d);
Поскольку была задана функция ключа (как тождественная функция), и новые данные содержат числа [4, 8, 16], которые соответствуют существующим элементам в документе, выборка update содержит три элемента DIV. Оставив эти элементы такими, как есть, мы можем добавить новые элементы для [1, 2, 32] с помощью выборки enter:
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. См. пример General Update Pattern для получения дополнительной информации об объединении данных.
selection.datum([value]) · Source
Получает или устанавливает привязанные данные для каждого выбранного элемента. В отличие от selection.data, этот метод не вычисляет объединение и не влияет на индексы или выборки enter и exit.
Если указано значение value, устанавливает привязанные данные элемента к указанному значению для всех выбранных элементов. Если value является константой, всем элементам задаётся одинаковое значение; в противном случае, если value является функцией, она вычисляется для каждого выбранного элемента, в порядке следования, принимая текущие данные (d), текущий индекс (i) и текущую группу (nodes), с this в качестве текущего элемента DOM (nodes[i]). Функция затем используется для установки новых данных каждого элемента. Значение null удалит привязанные данные.
Если value не указано, возвращает привязанные данные для первого (не пустого) элемента в выборке. Это обычно полезно только если вы знаете, что выборка содержит ровно один элемент.
Этот метод полезен для доступа к настраиваемым атрибутам 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
Добавляет или удаляет listener для каждого выбранного элемента для указанного события typenames. typenames — это строка типа события, например click, mouseover, или submit; может использоваться любой тип события DOM, поддерживаемый вашим браузером. Тип может быть необязательно после точки (.) и имени; необязательное имя позволяет регистрировать несколько обратных вызовов для получения событий одного типа, таких как click.foo и click.bar. Для указания нескольких имён типов, разделяйте их пробелами, например, input change или click.foo click.bar.
Когда указанное событие отправляется на выбранный элемент, указанный listener оценивается для элемента, принимая текущее событие (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 на первом (не пустом) выбранном элементе, если таковой имеется. Если указано несколько имён типов, возвращается первый соответствующий обработчик.
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, координаты события переводятся относительно верхнего левого угла прямоугольника отображения элемента. (Таким образом, система координат может быть преобразована только относительно координат клиента. См. также GeometryUtils.) В противном случае возвращается [event.pageX, event.pageY].
d3.pointers(event[, target]) · Source
Возвращает массив [[x0, y0], [x1, y1]…] координат указанных позиций указателя события event относительно указанного target. Для событий touch, возвращаемый массив позиций соответствует массиву event.touches; для других событий возвращается массив с одним элементом.
Если target не указан, он по умолчанию равен свойству currentTarget источника события, если оно доступно.
Управление потоком
Для расширенного использования, выборки предоставляют методы для пользовательского управления потоком.
selection.each(function) · Source
Вызывает указанную function для каждого выбранного элемента, в порядке следования, передавая текущие данные (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}`);
}); См. Sized Donut Multiples для примера.
selection.call(function[, arguments…]) · Source
Вызывает указанную function ровно один раз, передавая в неё эту выборку вместе с любыми необязательными arguments. Возвращает эту выборку. Это эквивалентно вызову функции вручную, но облегчает цепочку методов. Например, для установки нескольких стилей в многократно используемой функции:
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, а не возвращаемое значение вызываемой function, name.
selection.empty() · Source
Возвращает true, если эта выборка не содержит элементов (не пустых).
selection.nodes() · Source
Возвращает массив всех элементов в этой выборке. Эквивалентно:
const elements = Array.from(selection);
См. также selection[Symbol.iterator].
selection.node() · Source
Возвращает первый (не пустой) элемент в этой выборке. Если выборка пустая, возвращает null.
selection.size() · Source
Возвращает общее количество элементов в этой выборке.
selection[Symbol.iterator]() · Source
Возвращает итератор по выбранным элементам. Например, чтобы перебрать выбранные элементы:
for (const element of selection) {
console.log(element);
} Для преобразования выборки в массив:
const elements = [...selection];
Локальные переменные
Локальные переменные D3 позволяют определить локальное состояние, независимое от данных. Например, при отображении небольших множеств данных временных рядов, вам может потребоваться один и тот же масштаб x для всех диаграмм, но разные масштабы y для сравнения относительной производительности каждого показателя. Локальные переменные D3 ограничены элементами DOM: при установке значение сохраняется на указанном элементе; при получении значение извлекается из данного элемента или ближайшего предка, который его определяет.
d3.local() · Source
Объявляет новую локальную переменную. Например:
const foo = d3.local();
Как и var, каждый локальный объект является уникальной символической ссылкой; в отличие от var, значение каждого локального объекта также ограничено областью DOM.
local.set(node, value) · Источник
Устанавливает значение данного локального объекта для указанного узла со значением value и возвращает указанное 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–2020 Michael Bostock
Licensed under the BSD License.
https://github.com/d3/d3-selection