Spec-Zone.ru › D3.js 4

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 для всех выбранных элементов на указанное значение, заменяя любые существующие дочерние элементы. Если 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.

Указанное name может иметь префикс пространства имен, например 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.

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

selection.remove() Source

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

selection.sort(compare) Source

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

Функция сравнения, которая по умолчанию соответствует возрастающему порядку, получает два значения данных элементов 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.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 с выбранными элементами, возвращая новую выборку, которая представляет выборку update: элементы, успешно связанные с данными. Также определяет выборки enter и exit в возвращаемой выборке, которые могут быть использованы для добавления или удаления элементов для соответствия новым данным. Указанные data — это массив произвольных значений (например, чисел или объектов), или функция, которая возвращает массив значений для каждой группы. Когда данные присваиваются элементу, они хранятся в свойстве __data__, что делает данные «прилипающими» и доступными при повторном выборе.

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

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

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

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

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 сохраняет порядок выбора до присоединения. Если функция ключа указана, порядок элементов в выборке может не соответствовать их порядку в документе; используйте selection.order или selection.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 не указано, этот метод возвращает массив данных для выбранных элементов.

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

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

Возвращает выборку входа: заполнитель узлов для каждого значения, у которого не было соответствующего элемента DOM в выборке. (Выбор ввода пуст для выборок, не возвращаемых selection.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>

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

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

Возвращает выборку выхода: существующие элементы DOM в выборке, для которых не было найдено нового значения. (Выбор выхода пуст для выборок, не возвращаемых selection.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 соответствует порядку данных, потому что порядок старых данных и порядок новых данных были согласованными. Если порядок новых данных отличается, используйте selection.order, чтобы переупорядочить элементы в DOM. См. примерную нить Паттерна общего обновления для получения дополнительной информации о присоединении данных.

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

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

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

Если value не указано, возвращает привязанное значение для первого (не-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; })

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

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

selection.on(typenames[, listener[, capture]]) Источник

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

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

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

Дополнительный флаг capture может быть указан, который соответствует W3C флагу useCapture: «После инициализации захвата все события указанного типа будут отправляться зарегистрированному EventListener до отправки их любым EventTargets ниже по дереву. События, которые поднимаются вверх по дереву, не будут вызывать EventListener, назначенный для использования захвата».

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

selection.dispatch(type[, parameters]) Source

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

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

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

d3.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 касания с указанным идентификатором, связанным с текущим событием, относительно указанного 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 также может быть событием касания.) Контейнер может быть 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.

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

Spec-Zone.ru

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