Spec-Zone.ru › D3.js 5

d3-selection

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

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

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

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

var 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);

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

Установка

Если вы используете NPM, npm install d3-selection. В противном случае скачайте последнюю версию. Вы также можете загрузить напрямую с d3js.org, как самостоятельную библиотеку или как часть D3 4.0. Поддерживаются среды AMD, CommonJS и обычная среда. В обычной среде экспортируется глобальная переменная d3:

<script src="https://d3js.org/d3-selection.v1.min.js"></script>
<script>

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

</script>

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

Справочник по API

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

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

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

d3.selection() Source

Выбирает корневой элемент, 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) Source

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

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

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

d3.selectAll("p").on("click", function() {
  d3.select(this).style("color", "red");
});
d3.selectAll(selector) Source

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

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

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

d3.selectAll(document.links).style("color", "red");
выделение.select(selector) Source

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

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

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

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

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

выделение.selectAll(selector) Source

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

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

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

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

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

выделение.filter(filter) Source

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

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

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

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

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

Аналогично, используя функцию:

var even = d3.selectAll("tr").filter(function(d, i) { return i & 1; });

Или используя выделение.select:

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

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

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

выделение.merge(other) Source

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

Этот метод обычно используется для объединения выделений enter и update после соединения данных. После отдельной модификации элементов ввода и обновления вы можете объединить два выделения и выполнить операции над ними без дублирования кода. Например:

var circle = svg.selectAll("circle").data(data) // UPDATE
    .style("fill", "blue");

circle.exit().remove(); // EXIT

circle = circle.enter().append("circle") // ENTER
    .style("fill", "green")
  .merge(circle) // ENTER + UPDATE
    .style("stroke", "black");

См. выделение.data для более подробного объяснения этого кода, известного как общий шаблон обновления.

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

d3.matcher(selector) Источник

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

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

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

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

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

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

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

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

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

var div = selection.select(d3.selector("div"));
d3.selectorAll(selector) Источник

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

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

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

var div = selection.selectAll(d3.selectorAll("div"));
d3.window(node) Источник

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

d3.style(node, name) Источник

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

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

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

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

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

выделение.attr(name[, value]) Источник

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

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

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

выделение.classed(names[, value]) Источник

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

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

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

selection.classed("foo", function() { return Math.random() > 0.5; });

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

выделение.style(name[, value[, priority]]) Источник

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

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

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

выделение.property(name[, value]) Источник

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

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

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

выделение.text([value]) Источник

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

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

выделение.html([value]) Источник

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

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

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

selection.append(type) Source

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

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

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

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

d3.selectAll("p").append(function() {
  return document.createElement("div");
});

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

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

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

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

selection.insert(type[, before]) Source

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

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

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

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

d3.selectAll("p").insert(function() {
  return document.createElement("div");
});

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

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

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

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

selection.remove() Source

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

selection.clone([deep]) Source

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

selection.select(function() {
  return this.parentNode.insertBefore(this.cloneNode(deep), this.nextSibling);
});
selection.sort(compare) Source

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

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

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

selection.order() Source

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

selection.raise() Source

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

selection.each(function() {
  this.parentNode.appendChild(this);
});
selection.lower() Source

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

selection.each(function() {
  this.parentNode.insertBefore(this, this.parentNode.firstChild);
});
d3.create(name) Source

При заданном элементе name возвращает выборку из одного элемента, содержащего открепленный элемент заданного имени в текущем документе.

d3.creator(name) Source

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

selection.append("div");

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

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

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

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

Для ознакомления с объединениями данных D3 см. Размышления об объединениях. Также см. примеры Общие шаблоны обновления.

selection.data([data[, key]]) Source

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

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

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

var tr = d3.select("body")
  .append("table")
  .selectAll("tr")
  .data(matrix)
  .enter().append("tr");

var td = tr.selectAll("td")
  .data(function(d) { return d; })
  .enter().append("td")
    .text(function(d) { return d; });

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

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

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

var data = [
  {name: "Locke", number: 4},
  {name: "Reyes", number: 8},
  {name: "Ford", number: 15},
  {name: "Jarrah", number: 16},
  {name: "Shephard", number: 31},
  {name: "Kwon", number: 34}
];

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

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

Выборка update и enter возвращаются в порядке данных, а выборка exit сохраняет порядок выборки до соединения. Если функция ключа задана, порядок элементов в выборке может не соответствовать их порядку в документе; используйте выборка.order или выборка.sort по мере необходимости. Более подробную информацию о том, как функция ключа влияет на соединение, см. в Диаграмма столбцов, часть 2 и Постоянство объектов.

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

var circle = svg.selectAll("circle") // 1
  .data(data) // 2
    .style("fill", "blue"); // 3

circle.exit().remove(); // 4

circle = circle.enter().append("circle") // 5, 9
    .style("fill", "green") // 6
  .merge(circle) // 7
    .style("stroke", "black"); // 8

Рассмотрим это по шагам:

  1. Любые существующие круги (которые являются потомками svg выборки) выбираются.
  2. Эти круги соединяются с новыми data, возвращая совпадающие круги: выборка update.
  3. У этих обновляемых кругов задаётся синий цвет заливки.
  4. Любые существующие круги, которые не соответствуют новым данным — выборка exit — удаляются.
  5. Новые круги добавляются для любых новых данных, которые не соответствуют существующим кругам: выборка enter.
  6. Этим входящим кругам задаётся зелёный цвет заливки.
  7. Создаётся новая выборка, представляющая объединение входящих и обновляемых кругов.
  8. Этим входящим и обновляемым кругам задаётся чёрный контур.
  9. Эти круги хранятся в переменной circle.

Как описано в предыдущих параграфах, «сопоставление» определяется функцией ключа, переданной в selection.data; поскольку в приведенном выше примере кода не используется функция ключа, элементы и данные соединяются по индексу.

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

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

выборка.enter() Source

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

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

var div = d3.select("body")
  .selectAll("div")
  .data([4, 8, 15, 16, 23, 42])
  .enter().append("div")
    .text(function(d) { return d; });

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

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

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

выборка.exit() Source

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

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

div = div.data([1, 2, 4, 8, 16, 32], function(d) { return d; });

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

div.enter().append("div").text(function(d) { return 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-элементов соответствует порядку данных, потому что порядок старых данных и порядок новых данных совпадали. Если порядок новых данных отличается, используйте выборка.order для переупорядочивания элементов в DOM. См. пример общего шаблона обновления для более подробной информации о соединениях данных.

выборка.datum([значение]) Source

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

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

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

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

<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; })

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

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

выборка.on(typenames[, listener[, options]]) Source

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

Когда заданное событие отправляется на выбранный элемент, заданный слушатель будет вычисляться для элемента, получая на вход текущий элемент данных (d), текущий индекс (i) и текущую группу (nodes), при этом this будет представлять текущий DOM-элемент (nodes[i]). Слушатели всегда видят последние данные для своего элемента, но индекс — свойство выборки и фиксируется при назначении слушателя; для обновления индекса переназначьте слушателя. Для доступа к текущему событию внутри слушателя используйте d3.event.

Если ранее для того же 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.event

Текущее событие, если таковое имеется. Оно устанавливается во время вызова обработчика событий и сбрасывается после завершения обработчика. Используйте его для доступа к стандартным полям события, таким как event.timeStamp, и к методам, таким как event.preventDefault. Хотя вы можете использовать родные event.pageX и event.pageY, зачастую удобнее преобразовать позицию события в локальную систему координат контейнера, который получил событие, используя d3.mouse, d3.touch или d3.touches.

Если вы используете Babel, Webpack или другой инструмент для преобразования ES6 в ES5, имейте в виду, что значение d3.event изменяется во время события! Импорт d3.event должен быть динамической ссылкой, поэтому вам может потребоваться настроить инструмент для импорта из ES6-модулей D3, а не из сгенерированного UMD-пакета; не все инструменты учитывают jsnext:main. Также будьте внимательны к конфликтам со значением window.event.

d3.customEvent(event, listener[, that[, arguments]]) Source

Вызывает указанный listener, используя указанное that this контекст и передавая указанные arguments, если таковые имеются. Во время вызова d3.event устанавливается в указанное event; после возврата обработчика (или выброса ошибки) d3.event восстанавливается до своего предыдущего значения. Кроме того, устанавливает event.sourceEvent в предыдущее значение d3.event, позволяя пользовательским событиям сохранять ссылку на исходное нативное событие. Возвращает значение, возвращенное listener.

d3.mouse(container) Source

Возвращает координаты x и y текущего события относительно указанного container. Контейнер может быть HTML- или SVG-элементом контейнера, таким как элемент G или SVG-элемент. Координаты возвращаются в виде двумерного массива чисел [x, y].

d3.touch(container[, touches], identifier) Source

Возвращает координаты x и y касания с указанным identifier, связанного с текущим событием, относительно указанного container. Контейнер может быть HTML- или SVG-элементом контейнера, таким как элемент G или SVG-элемент. Координаты возвращаются в виде двумерного массива чисел [x, y]. Если нет касания с указанным идентификатором в touches, возвращается null; это может быть полезно для игнорирования событий touchmove, когда только некоторые касания перемещаются. Если touches не указан, он по умолчанию устанавливается в свойство changedTouches текущего события.

d3.touches(container[, touches]) Source

Возвращает координаты x и y касаний, связанных с текущим событием, относительно указанного container. Контейнер может быть HTML- или SVG-элементом контейнера, таким как элемент G или SVG-элемент. Координаты возвращаются в виде массива двумерных массивов чисел [[x1, y1], [x2, y2], …]. Если touches не указан, он по умолчанию устанавливается в свойство touches текущего события.

d3.clientPoint(container, event) Source

Возвращает координаты x и y указанного event относительно указанного container. (event также может быть touch.) Контейнер может быть HTML- или SVG-элементом контейнера, таким как элемент G или SVG-элемент. Координаты возвращаются в виде двумерного массива чисел [x, y].

Поток управления

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

selection.each(function) Source

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

parent.each(function(p, j) {
  d3.select(this)
    .selectAll(".child")
      .text(function(d, i) { return "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

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

selection.node() Source

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

selection.size() Source

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

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

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

d3.local() Source

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

var foo = d3.local();

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

END_OF_DOCUMENT_MARKER
local.set(node, value) Source

Устанавливает значение данного локального хранилища на указанном узле node в значение value и возвращает указанное value. Часто используется с selection.each:

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

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

selection.property(foo, function(d) { return d.value; });
local.get(node) Source

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

local.remove(node) Source

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

local.toString() Source

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

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

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

d3.namespace(name) Source

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

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

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

d3.namespaces Source

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

{
  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–2018 Michael Bostock
Licensed under the BSD License.
https://github.com/d3/d3-selection

Spec-Zone.ru

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