RU Выборки - Mingun/d3 GitHub Wiki
Вики ▸ Справка по API ▸ Ядро ▸ Выборки
English | Русский
Выборка — это массив элементов, полученных из текущего документа. D3 использует селекторы CSS3 для выбора элементов. Например, вы можете выбирать то тегу ("div"
), классу (".awesome"
), уникальному идентификатору ("#foo"
), атрибуту ("[color=red]"
) или условию вложенности ("parent child"
). Селекторы могут пересекаться (".this.that"
для логического И) или объединяться (".this, .that"
для логического ИЛИ). Если ваш браузер не поддерживает селекторы нативно, вы можете подключить библиотеку Sizzle до подключения D3 для обратной совместимости.
После выбора элементов вы можете применить к ним операции для совершения некой полезной работы. Операции могут возвращать или устанавливать атрибуты, стили, свойства, HTML и текстовое содержимое. Значения атрибутов задаются константами или функциями; в последнем случае атрибут будет вычислен для каждого элемента. Так же вы можете привязать выборку к данным; эти данные доступны для операторов преобразования, управляемых данными. Кроме того, присоединение к данным производит вложенный выбор через вход и выход, так то вы можете добавлять или удалять элементы в ответ на изменение данных.
В общем случае вам не нужно использовать циклы или рекурсивные функции для изменения документа средствами D3. Всё потому, что вы оперируете целой выборкой вместо итерирования по каждому элементу. Однако, вы всё ещё можете итерироваться по элементам вручную: оператор each вызывает любую функцию, а выборка является массивом, так что доступ к элементам может быть прямым (например, selection[0][0]
). D3 поддерживает цепочечный вызов методов для краткости при применении нескольких операторов: возвращаемым значением оператора является выборка.
D3 предоставляет два высокоуровневых метода для выбора элементов: select и selectAll. Эти методы принимают строку селектора; первый выбирает только первый совпавший элемент, в то время как последний выбирает все совпавшие элементы в порядке обхода документа. Эти методы так же могут принимать узлы, что очень полезно при интеграции со сторонними библиотеками вроде jQuery или инструментов разработчика ($0
).
# d3.select(selector)
Выбирает первый элемент, удовлетворяющий указанной строке селектора, возвращает одноэлементную выборку. Если в текущем документе нет элементов, удовлетворяющих указанному селектору, возвращает пустую выборку. Если селектору удовлетворяет несколько элементов, в выборку попадёт только первый удовлетворяющий элемент (в порядке обхода документа).
# d3.select(node)
Выбирает указанный узел. Полезно, если вы уже имеете ссылку на узел, может использоваться как d3.select(this)
внутри слушателя событий, или с глобальными объектами, вроде document.body
.
# d3.selectAll(selector)
Выбирает все элементы, удовлетворяющие указанному селектору. Элементы будут выбраны в порядке обхода документа (сверху вниз). Если в текущем документе нет элементов, удовлетворяющих указанному селектору, возвращает пустую выборку.
# d3.selectAll(nodes)
Выбирает указанный массив элементов. Полезно, если вы уже имеете ссылку на узлы, может использоваться как d3.selectAll(this.childNodes)
внутри слушателя событий, или с глобальными объектами, вроде document.links
. Аргумент nodes не обязательно должен быть массивом; будет работать любой псевдомассив, приводимый к массиву (в частности, псевдомассивы NodeList
или arguments
).
Выборки являются буквально массивами элементов (ну, может быть не буквально...). D3 добавляет дополнительные методы к массиву, так что вы можете применять операторы к выбранным элементам, например, установить атрибут всем выбранным элементам. Есть один нюанс в том, что выборки сгруппированы: вместо одномерного массива, каждая выборка является массивом массивов элементов. Это позволяет сохранить иерархическую структуру дочерних выборок. В большинстве случаев вы можете игнорировать эту подробность, но именно поэтому выборка из одного элемента выглядит как [[node]]
, а не как [node]
. Для получения дополнительной информаци о вложенных выборках смотрите раздел Вложенные выборки.
Если вы хотите узнать, как работают выборки, попытайтесь выбрать элементы в интерактивном режиме через консоль браузера. Вы можете наблюдать возвращённый масив, чтобы увидеть, какие элементы выбрались и как они сгруппированы. Так же вы можете применить операторы к выбранным элементам и наблюдать, как изменяется содержимое страницы.
D3 имеет целый ряд операторов, которые влияют на содержимое документа. В большинстве случаев вы будете использовать их для отображения данных! При использовании для установки содержимого документа, операторы возвращают текущую выборку, так что вы можете объединить несколько операторов в цепочку в лаконичном выражении.
# selection.attr(name[, value])
Если параметр value указан, устанавливает атрибут с указанным именем в указанное значение для всех элементов, входящих в выборку. Если value — константа, все элементы получат одинаковое значение атрибута; в противном случае, если value — функция, она вычисляется для каждого элемента (в порядке следования элементов в выборке); параметрами передаются текущая привязка к данным d
и текущий индекс i
, контекст this
внутри функции привязывается к текущему элементу DOM. Возвращаемое значение функции используется для установки атрибута на элементе. Значение null
означает, что указанный атрибут необходимо удалить.
Если параметр value не указан, возвращает значение указанного атрибута первого ненулевого элемента в выборке. Этот метод в основном полезен, если вы знаете, что выборка содержит один элемент.
Параметр name может содержать префикс пространства имён, например xlink:href
определяет атрибут href
в пространстве имён XLink. По умолчанию, D3 поддерживает пространства имён svg
, xhtml
, xlink
, xml
и xmlns
. Дополнительные пространства имён могут быть зарегистрированы через функцию d3.ns.prefix.
Парамент name так же может быть объектом с атрибутами name и value.
# selection.classed(name[, value])
Этот оператор – удобная обёртка для установки атрибута class
; она понимает, что атрибут class
является строкой токенов, разделённых пробелами. Под капотом она использует classList, если он доступен, для удобного добавления, удаления и переключения классов CSS.
Если указан параметр value, определяет, нужно устанавить или снять указанный класс с выбранных элементов. Если value — константа и вычисляется в true
, указанный класс будет назначен всем элементам, если он ещё не назначен; если же она вычисляется в false
, класс будет убран со всех выбранных элементов. Если value — функция, она вычисляется для каждого элемента (в порядке следования элементов в выборке); параметрами передаются текущая привязка к данным d
и текущий индекс i
, контекст this
внутри функции привязывается к текущему элементу DOM. Возвращаемое значение функции используется для установки / снятия класса с каждого элемента.
Если вы хотите установить несколько классов за раз, используйте литерал объекта вот таким образом: selection.classed({'foo': true, 'bar': false})
.
Если параметр value не указан, возвращает true
только тогда, когда первый ненулевой элемент в выборке имеет указанный класс. Этот метод в основном полезен, если вы знаете, что выборка содержит один элемент.
# selection.style(name[, value[, priority]])
Если указан параметр value, устанавливает стилевой свойство CSS с указанным именем в указанное значение для всех выбранных элементов. Если value — константа, все элементы получат одинаковый стиль; в противном случае, если value — функция, она вычисляется для каждого элемента (в порядке следования элементов в выборке); параметрами передаются текущая привязка к данным d
и текущий индекс i
, контекст this
внутри функции привязывается к текущему элементу DOM. Возвращаемое значение функции используется для установки стилевого свойства на элементе. Значение null
означает, что указанный стиль необходимо удалить. Так же может быть указан необязательный параметр priority, который может быть либо null
, либо строкой "important"
(без восклицательного знака).
Если вы хотите установить несколько стилевых свойств за раз, используйте литерал объекта вот таким образом: selection.style({'stroke': 'black', 'stroke-width': 2})
.
Если параметр value не указан, возвращает текущее вычисленное значение указанного стилевого свойства для первого ненулевого элемента в выборке. Этот метод в основном полезен, если вы знаете, что выборка содержит один элемент. Обратите внимание, что вычисленное значение может отличаться от значения, которое было установлено ранее, например, если стилевое свойство было установлено через сокращённое свойство (например стиль "font"
является сокращением для "font-size"
, "font-face"
и т.д.).
# selection.property(name[, value])
Некоторые HTML-элементы имею особые свойства, которые недоступны через стандартные атрибуты или стили. Например, текстовые поля имеют строковое свойство value
, а флажки-переключатели имеют логическое свойство checked
. Вы можете использовать оператор property для получения или установки этих свойств, либо любых других адресуемых полей на текущем элемента, например className
.
Если указан параметр value, устанавливает свойство с указанным именем в указанное значение для всех выбранных элементов. Если value — константа, все элементы получат одинаковое значение свойства; в противном случае, если value — функция, она вычисляется для каждого элемента (в порядке следования элементов в выборке); параметрами передаются текущая привязка к данным d
и текущий индекс i
, контекст this
внутри функции привязывается к текущему элементу DOM. Возвращаемое значение функции используется для установки свойства на элементе. Значение null
означает, что указанное свойство необходимо удалить.
Если вы хотите установить несколько свойств за раз, используйте литерал объекта вот таким образом: selection.property({'foo': 'bar', 'baz': 'qux'})
.
Если параметр value не указан, возвращает значение указанного свойства первого ненулевого элемента в выборке. Этот метод в основном полезен, если вы знаете, что выборка содержит один элемент.
# selection.text([value])
Оператор text основывается на свойстве textContent; установка текстового содержимого заменит любые существующие дочерние элементы.
Если указан параметр value, устанавливает текстовое содержимое в указанное значение для всех выбранных элементов. Если value — константа, все элементы получат одинаковое текстовое содержимое; в противном случае, если value — функция, она вычисляется для каждого элемента (в порядке следования элементов в выборке); параметрами передаются текущая привязка к данным d
и текущий индекс i
, контекст this
внутри функции привязывается к текущему элементу DOM. Возвращаемое значение функции используется для установки текстового содержимого элемента. Значение null
означает, что содержимое нужно очистить.
Если параметр value не указан, возвращает текстовое содержимое первого ненулевого элемента в выборке. Этот метод в основном полезен, если вы знаете, что выборка содержит один элемент.
# selection.html([value])
Оператор html основывается на свойстве innerHTML; установка содержимого HTML заменит любые существующие дочерние элементы. Также вы можете предпочесть использовать операторы append или insert для создания HTML-содержимого; этот оператор нужен, если вы хотите вставить HTML-код, например, со сложным форматированием.
Если указан параметр value, устанавливает внутреннее HTML-содержимое в указанное значение для всех выбранных элементов. Если value — константа, все элементы получат одинаковое внутреннее HTML-содержимое; в противном случае, если value — функция, она вычисляется для каждого элемента (в порядке следования элементов в выборке); параметрами передаются текущая привязка к данным d
и текущий индекс i
, контекст this
внутри функции привязывается к текущему элементу DOM. Возвращаемое значение функции используется для установки внутреннего HTML-содержимого элемента. Значение null
означает, что содержимое нужно очистить.
Если параметр value не указан, возвращает HTML-содержимое первого ненулевого элемента в выборке. Этот метод в основном полезен, если вы знаете, что выборка содержит один элемент.
Обратите внимание: как и предполагает его название, оператор selection.html поддерживается только на HTML-элементах. SVG-элементы и другие не-HTML-элементы не поддерживают свойство innerHTML
и поэтому несовместимы с оператором selection.html. Подумайте об использовании XMLSerializer для преобразования поддерева DOM в текст. Также можете посмотреть полифилл innersvg, который предоставляет прослойку для поддержки свойства innerHTML
на SVG-элементах.
# selection.append(name)
Присоединяет новый элемент с указанным именем name в качестве последнего потомка каждого элемента в текущей выборке, возвращает новую выборку, содержащую присоединённые элементы. Каждый новый элемент наследует данные текущих элементов, если таковые имеются, в том же порядке, как и при использовании select для вложенного выбора.
Параметр name может быть либо строкой, либо функцией, возвращающей DOM-элемент для присоединения. Если name — строка, она может содержать префикс пространства имён в форме "namespace:tag"
. Например, "svg:text"
создаст элемент "text"
в пространстве имён SVG. По умолчанию, D3 поддерживает пространства имён svg
, xhtml
, xlink
, xml
и xmlns
. Дополнительные пространства имён могут быть зарегистрированы через функцию d3.ns.prefix. Если пространство имён не указано, оно будет унаследовано от охватывающего элемента; или, если имя является одним из известных префиксов, будет использоваться соответствующее пространство имён (например, "svg"
неявно подразумевает "svg:svg"
).
# selection.insert(name[, before])
Вставляет новый элемент с указанным именем name перед элементом, соответствующим указанному селектору before для каждого элемента в текущей выборке, возвращает новую выборку, содержащую вставленные элементы. Если селектор before не соответствует никакому элементу, новый элемент будет последним потомком, как и при использовании оператора append. Каждый новый элемент наследует данные текущих элементов, если таковые имеются, в том же порядке, как и при использовании select для вложенного выбора.
Параметр name может быть либо строкой, либо функцией, возвращающей DOM-элемент для присоединения. Если name — строка, она может содержать префикс пространства имён в форме "namespace:tag"
. Например, "svg:text"
создаст элемент "text"
в пространстве имён SVG. По умолчанию, D3 поддерживает пространства имён svg
, xhtml
, xlink
, xml
и xmlns
. Дополнительные пространства имён могут быть зарегистрированы через функцию d3.ns.prefix. Если пространство имён не указано, оно будет унаследовано от охватывающего элемента; или, если имя является одним из известных префиксов, будет использоваться соответствующее пространство имён (например, "svg"
неявно подразумевает "svg:svg"
).
Как и name, селектор before может быть строкой, либо функцией, возвращающей DOM-элемент. Например, вызов insert("div", ":first-child")
присоединит дочеркий узел div
перед текущей выборкой. Для вложенного выбора через вход, селектор before может быть опущен, в этом случае входящие элементы будут вставлены непосредствено перед следующим соседом в обновляемой выборке, если он есть. Это позволяет вам вставлять элементы в DOM в порядке, соответствующем привязанным данным. Однако, обратите внимание, что может потребоваться использование медленного оператора selection.order, если обновляемые элементы меняют порядок следования.
# selection.remove()
Удаляет элементы в текущей выборке из текущего документа. Возвращает текущую выборку (те же самые элементы, что были удалены), которая сейчас находится «за кадром», отсоединённая от DOM. Обратите внимание, что на текущий момент нет выделенного API для добавления удалённых элементов обратно в документ; однако, вы можете передать их в операторы selection.append или selection.insert для добавления элементов.
# selection.data([values[, key]])
Соединяет указанный массив данных с текущей выборкой. Параметр values представляет собой массив значений данных, как то массив чисел, объектов или функций, возвращающих массив значений. Если функция key не определена, то первый элемент данных в указанном массиве будет назначен первому элементу в текущей выборке, второй элемент данных – второму элементу выборки и т.д. Когда данные назначаются элементу, они сохраняются в свойстве __data__
, что делает данные «липкими», так что они доступны для повторного выбора.
Массив значений values определяет данные для каждой группы в выборке. Таким образом, если выборка содержит несколько групп (такое могло получиться после вызова d3.selectAll, за которым следовал selection.selectAll), то данные должны быть указаны как функция, возвращающая массив (при условии, что вы хотите назначить разные данные для каждой группы). Например, вы можете привязать двумерный массив к первоначальной выбрке, а затем привязать содаржищиеся в нём внутренние массивы к каждой подвыборке. В этом случае функция values будет единичной функцией: она будет вызвана для каждой группы дочерних элементов с переданными данными родительского элемента и возвратит этот массив данных.
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; });
Для контроля того, какие данные будут присоединяться к элементам, может быть указана функция ключа key. Она заменяет поведение по умолчанию, использующее индексацию; функция ключа вызывается один раз для каждого элемента в новом массиве данных и один раз для каждого существующего элемента в выборке. В обоих случаях параметрами в функцию передаются привязка к данным d
и индекс i
. Когда функция вычисляется над новыми элементами данных, контекст this
привязан к массиву данных; когда же она вычисляется над существующей выборкой, контекст this
привязан к связанному элементу DOM. Функция возвращает строку, которая используется для привязки к данным соответствующего элемента на основе ранее привязанных данных. Например, если привязанные данные имеют уникальное поле name
, привязка может быть определена как:
.data(data, function(d) { return d.name; })
Для более подробного примера, как функция ключа влияет на привязку данных, смотрите урок Гистограмма, часть 2.
Результат оператора data
обновляет выборку; он представляет выборку элементов DOM, которые успешно связались с указанными элементами данных. Обновлённая выборка так же содержит ссылку на входную и выходную выборки, для добавления и удаления узлов в соответствии с данными. Например, если по умолчанию используется ключ по индексу и существующая выборка содержит меньше элементов, чем предоставлено данных, то входная выборка будет содержать заполнители для новых данных. С другой стороны, если выборка содержит больше элементов, чем предоставлено данных, то выходная выборка будет содержать дополнительные элементы. И, если количество элементов в выборке и в данных одинаково, то обе выборки, входная и выходная, будут пустыми, а все узлы останутся в обновляемой выборке. За дополнительными сведениями смотрите краткий урок Мыслить соединениями.
Если функция ключа указана, оператор data
также применяется к индексам узлов; этот индекс передаётся как второй аргумент i
в любую функцию, оперирующую данными. однако, обратите внимание, что существующие элементы DOM автоматически не переупорядочиваются; используйте операторы sort или order для этого.
Если параметр values не указан, то данный метод возвращает массив даннных для первой группы в выборке. Длина возвращённого массива совпадает с длиной первой группы и индексы каждого элемента данных в возвращённом массиве совпадают с соответствующими индексами в выборке. Если некоторые элементы в выборке равны null
, либо не имеют связанных данных, то соответствующий элемент в массиве будет undefined
.
Обратите внимание: метод data
не используется для очистки ранее привязанных данных; для этого используйте метод selection.datum.
# selection.enter()
Возвращает входную выборку: заполняет узлы для каждого элемента данных, для которого в текущей выборке нет существующего элемента DOM. Этот метод определён только на выборке, возвращаемой оператором data. Кроме того, только для входной выборки определены операторы append, insert, select и call; вы должны использовать эти операторы для создания входных узлов до изменения содержимого. Входная выборка также поддерживает метод empty для проверки, что она пустая. Обратите внимание, что оператор enter просто возвращает ссылку на входную выборку, новые узлы вы должны добавить самостоятельно.
В качестве простого примера давайте рассмотрим случай, когда существующая выборка пустая и мы хотим создать новые узлы, соответствующие нашим данным:
d3.select("body").selectAll("div")
.data([4, 8, 15, 16, 23, 42])
.enter().append("div")
.text(function(d) { return d; });
Предположим, что тело документа изначально пустое; код выше создаст шесть новых элементов div
, по порядку добавит их к body
и назначит им текстовое содержимое, соответствующее связанному числу (преобразовав его в строку):
<div>4</div>
<div>8</div>
<div>15</div>
<div>16</div>
<div>23</div>
<div>42</div>
Можно думать о входных узлах-заменителях как об указателях на родительский узел (в данном примере, на тело документа); однако, только они поддерживают присоединение и вставку элементов.
Входная выборка сливается с обновляемой выборкой, когда вы присоединяете или вставляете элемент. Этот подход уменьшает количество дублирующего кода между входной и обновляемой выборками. Вместо того, чтобы применять операторы к входной и обновляемой выборкам по отдельности, вы можете применить их к обновляемой выборке после ввода узлов. В редких случаях, когда вам нужно запустить операторы только на обновляемых узлах, вы можете запустить их на обновляемой выборке до ввода новых узлов.
# selection.exit()
Возвращает выходную выборку: существующие элементы DOM в текущей выборке, для которых не было найдено элементов в массиве даных. Этот метод определён только на выборке, возвращаемой оператором data. Выходная выборка определяет все нормальные операторы, хотя, как правило, вы будете использовать только remove; остальные операторы существуют прежде всего для того, что бы вы могли определить выходной переход по своему желанию. Обратите внимание, что оператор exit просто возвращает ссылку на выходную выборку, новые узлы вы должны удалить самостоятельно.
В качестве простого примера давайте рассмотрим обновление шести элементов div
, созданных в примере выше для оператора enter. Вот таким образом мы привязываем эти элементы к новому массиву данных, в котором есть как старые элементы, так и новые:
var div = d3.select("body").selectAll("div")
.data([1, 2, 4, 8, 16, 32], function(d) { return d; });
Теперь div
– результат оператора data — относится к обновляемой выборке. Поскольку мы определили функцию ключа как единичную функцию, а новый массив данных содержит числа [4, 8, 16] которые так же существуют в старом массиве данных, эта обновляемая выборка содержит три элемента div
. Давайте оставим эти элементы как есть. Мы можем создать и добавить новые элементы [1, 2, 32] используя входную выборку:
div.enter().append("div")
.text(function(d) { return d; });
Кроме того, мы можем удалить выходные элементы [15, 23, 42]:
div.exit().remove();
Теперь тело документа выглядит так:
<div>4</div>
<div>8</div>
<div>16</div>
<div>1</div>
<div>2</div>
<div>32</div>
Обратите внимание, что элементы DOM не соответствуют порядку в данных. Однако, индекс выборки i
(второй аргумент в функции оператора), корректно соответствует новому массиву данных. Например, мы можем присвоить его атрибуту index
:
d3.selectAll("div").attr("index", function(d, i) { return i; });
Результат будет таким:
<div index="2">4</div>
<div index="3">8</div>
<div index="4">16</div>
<div index="0">1</div>
<div index="1">2</div>
<div index="5">32</div>
Если вы хотите, что бы порядок обхода документа совпадал с порядком данных в выборке, вы модете использовать операторы sort или order.
# selection.filter(selector)
Фильтрует выборку, возвращает новую выборку, содержащую только те элементы, что удовлетворяют указанному селектору selector. Параметр selector может быть либо функцией, либо строкой селектора, например ".foo"
. Как и другие операторы, функция принимает текущую привязку к данным d
и индекс i
, контекст this
привязывается к текущему элементу DOM. Подобно встроенному методу массива filter, возвращаемая выборка не сохраняет индексы оригальной выборки; она возвращает копию с удалёнными элементами. Если вы хотите сохранить индексы, используйте select вместо этого. Например, для выбора каждого нечётного элемента (нумерация начинается с нуля):
var odds = selection.select(function(d, i) { return i & 1 ? this : null; });
Эквивалентное использование функции filter:
var odds = selection.filter(function(d, i) { return i & 1; });
Или с использованием селектора (обратите внимание, что при использовании псевдо-класса :nth-child
нумерация начинается с единицы, а не с нуля, поэтому мы выбирает чётные элементы):
var odds = selection.filter(":nth-child(even)");
Таким образом, вы можете использовать либо select, либо filter для применения операторов к подмножеству элементов.
# selection.datum([value])
Возвращает / устанавливает привязанные данные для каждого выбранного элемента. В отличие от метода selection.data, этот метод не вычисляет связи (и поэтому не вычисляет входную и выходную выборки). Этот метод реализован поверх метода selection.property:
d3.selection.prototype.datum = function(value) {
return arguments.length < 1
? this.property("__data__")
: this.property("__data__", value);
};
Если указан параметр value, устанавливает привязанные к элементу данные в указанное значение для всех выбранных элементов. Если value — константа, все элементы получат одинаковые данные; в противном случае, если value — функция, она вычисляется для каждого элемента (в порядке следования элементов в выборке); параметрами передаются предыдущая привязка к данным d
и текущий индекс i
, контекст this
внутри функции привязывается к текущему элементу DOM. Затем функция используется для установки данных элемента. Значение null
означает, что привязанные данные нужно удалить. Этот оператор не меняет индексы.
Если параметр value не указан, возвращает привязанные данные первого ненулевого элемента в выборке. Этот метод в основном полезен, если вы знаете, что выборка содержит один элемент.
Обратите внимание: этот метод раньше назывался map. Старое имя устарело.
Метод datum полезен для доступа к пользовательским атрибутам данных HTML5 из D3. Например, мы имеем следующие элементы:
<ul id="list">
<li data-username="shawnbot">Shawn Allen</li>
<li data-username="mbostock">Mike Bostock</li>
</ul>
Вы можете передать пользовательские атрибуты данных в D3 путём установки данных каждого элемента из встроенного свойства dataset:
selection.datum(function() { return this.dataset; })
Это может использоваться, например, для сортироки элементов по имени пользователя.
# selection.sort(comparator)
Сортирует элементы в текущей выборке в соответствии с указанной функцией сравнения comparator. Функции сравнения передаётся два элемента данных a и b для сравнения, возвращаемое значение должно быть отрицательным, положительным или нулём. Если результат отрицателен, a идёт перед b; если положителен, a идёт после b; в противном случае a и b считаются равными и их порядок не важен. Обратите внимание, что метод sort не гарантирует стабильность сортироки; однако, гарантирует поведение, идентичное встроенному методу sort массива.
# selection.order()
Повторно вставляет элементы в документ так, чтобы порядок элементов в документе совпадал с порядком в выборке. Этот метод эквивалентен вызову метода sort
, если данные уже отсортированы, но значительно быстрее.
# selection.on(type[, listener[, capture]])
Добавляет или удаляет слушатель событий listener для каждого элемента в текущей выборке для указанного типа type событий. Тип type — это строковое имя типа события, например "click", "mouseover", или "submit". Указанный слушатель listener вызывается таким же образом, как и другие операторы, параметрами передаются текущая привязка к данным d
и текущий индекс i
, контекст this
внутри функции привязывается к текущему элементу DOM. Для доступа к текущему событию изнутри слушателя испольуйте глобальный объект d3.event. Возвращаемое значение слушателя событий игнорируется.
Если на выбранном элементе уже зарегистрирован слушатель событий под тем же самым типом, он будет удалён перед тем как новый слушатель будет добавлен. Для регистрирования нескольких слушателей с одинаковым типом события, за типом может следовать необязательное пространство имён, например «click.foo» или «click.bar».
Для удаления слушателя передайте значение null
в качестве параметра listener. Для удаления всех слушателей определённого типа события передайте значение null
в качестве параметра listener и .type
в качестве типа события type, например selection.on(".foo", null)
.
Необязательный флаг capture соответствует флагу useCapture W3C: «После инициализации захвата, все события указанного типа будут направлены в зарегистрированный EventListener до того, как они будут направлены в любой EventTarget, находящийся ниже по иерархии в дереве. События, всплывающие вверх по дереву, не вызовут срабатывания EventListener, объявленного с флагом захвата.»
Если параметр listener не указан, возвращает текущий слушатель, ассоциированный с указаным типом type, если таковой имеется.
# d3.event
Хранит текущее событие, если таковое имеется. Этот глобальный объект существует во время вызова функции обратного вызова слушателя событий, зарегистрированного через оператор on. Данное событие сбрасывается после того, как слушатель получает уведомление в последний раз. Так сделано для того, чтобы слушатели событий имели тот же вид, что и остальные функции в операторах, принимая параметрами текущую привязку к данным d
и индекс i
.
Объект d3.event
является событием DOM и реализует стандартные поля события, такие как timeStamp
и keyCode
, а так же методы preventDefault()
и stopPropagation()
. В то время как вы можете использовать нативные поля события pageX и pageY, часто более удобно перейти к локальной системе координат относительно контейнера, принявшего событие. Например, если вы внедрили SVG в нормальный поток страницы, вы можете захотеть, что бы позиция в событии отсчитываласть от верхнего левого угла изображения SVG. Если ваш SVG содержит трансформации, вы так же можете захотеть знать позицию события относительно этих трансформаций. Используйте оператор d3.mouse для взаимодействия с указателем мыши и оператор d3.touches для взаимодействия с событиями мультитача на iOS.
# d3.mouse(container)
Возвращает координаты x и y текущего d3.event, относительно указанного контейнера container. Контейнер может быть HTML или SVG элементом-контейнером, например svg:g или svg:svg. Координаты возвращаются в виде двухэлементного массива [x, y].
# d3.touch(container[, touches], identifier)
Возвращает координаты x и y касания с указанным идентификатором identifier, ассоциированного с текущим d3.event, относительно указанного контейнера container. Если параметр touches не определён, то по умолчанию ассоциируется с текущим событием changedTouches.
Контейнер может быть HTML или SVG элементом-контейнером, например svg:g или svg:svg. Координаты возвращаются в виде массива двухэлементных массивов [ [ x1, y1], [ x2, y2], … ]. Если в touches нет касания с указанным идентификатором, возвращает null
; это может быть полезно для игнорирования событий перемещения касаний, когда перемещаются только некоторые касания.
# d3.touches(container[, touches])
Возвращает координаты x и y каждого касания, ассоциированного с текущим d3.event, на основе атрибута touches, относительно указанного контейнера container. Контейнер может быть HTML или SVG элементом-контейнером, например svg:g или svg:svg. Координаты возвращаются в виде массива двухэлементных массивов [ [ x1, y1], [ x2, y2], … ]. Если указан параметр touches, возвращает позиции указанных касаний; если же touches не указан, то по умолчанию он равен свойству touches
текушего события.
# selection.transition()
Начинает переход для текущей выборки. Переходы подобны выборкам, за исключением того, что операторы применяются не мгновенно, а с плавно, с анимацией.
# selection.interrupt()
Немедленно прерывает текущий переход переход, если он есть. Не отменяет запланированные переходы, если они ещё не начались. Для отмены запланированных переходов просто создайте номый переход с нулевым временем задержки после прерывания текущего перехода:
selection
.interrupt() // отменяем текущий переход
.transition(); // пресекаем любые запланированные переходы
В то время как общий метод select работает по всему документу, операторы select и selectAll выборки ограничивают запросы потомками каждого выбранного элемента; мы зовём их «вложенными выборками». Например, d3.selectAll("p").select("b")
возвратит первый жирный ("b"
) элемент в каждом элементе абзаца ("p"
). Вложенные выборки через selectAll группируют элементы по предку. Так, d3.selectAll("p").selectAll("b")
сгруппирует абзацы, а d3.selectAll("p b")
вернёт плоскую выборку. Вложенная выборка через select действует похожим образом, но сохраняет группы и передаёт данные. Группировка играет важную роль в привязке данных и функциональные операторы могут зависеть от числового индекса текущего элемента внутри его группы.
# selection.select(selector)
Для каждого элемента в текущей выборке, выбирает первого потомка, удовлетворяющего строке селектора selector. Если для текущего элемента соответствия с указанным селектором не нашлось, элемент по текущему индексу будет равен null
в возвращённой выбоке; операторы (за исключением оператора data) автоматически пропускают нулевые элементы, тем самым сохраняя индекс существующей выборки. Если текущий элемент имеет ассоциированные с ним данные, эти данные будут унаследованы возвращённой вложенной выборкой и автоматически привязаны к новым элементам. Если селектору удовлетворяют несколько элементов, будет выбран только первый элемент в порядке обхода документа.
Параметр selector так же может быть функцией, возвращающей элемент или null
, если не нашлось соответствующего элемента. В этом случае, указанный селектор selector вызывается таким же образом, как и остальные функции в операторах, принимая параметрами текущую привязку к данным d
и индекс i
, контекст this
привязывается к текущему элементу DOM.
# selection.selectAll(selector)
Для каждого элемента в текущей выборке, выбирает всех потомков, удовлетворяющих строке селектора selector. Возвращённая выборка группируется по узлу родителя в текущей выборке. Если для текущего элемента соответствия с указанным селектором не нашлось, группа по текущему индексу будет равна null
в возвращённой выборке. Вложенная выборка не наследует данные от текущей выборки; однако, если значение data определено как функция, эта функция будет вызвана с данными d
родительского узла и индексом группы i
для определения привязки данных для вложенной выборки.
Группировка в selectAll также влияет на последующие входные узлы-заменители. Таким образом, для определения родительского узла, к которому необходимо присоединять входные узлы используйте select, а затем selectAll:
d3.select("body").selectAll("div")
Вы можете добраться до родительского узла каждой группы через свойство parentNode
группы, вот таким образом selection[0].parentNode
.
Параметр selector так же может быть функцией, возвращающей массив элемент (или NodeList) пустой массив, если не нашлось соответствующих элементов. В этом случае, указанный селектор selector вызывается таким же образом, как и остальные функции в операторах, принимая параметрами текущую привязку к данным d
и индекс i
, контекст this
привязывается к текущему элементу DOM.
Для продвинутого использования D3 имеет несколько дополнительных операторов для гибкого управления данными.
# selection.each(function)
Вызывает указанную функцию function для каждого элемента в текущей выборке; параметрами передаются текущая привязка к данным d
и текущий индекс i
, контекст this
внутри функции привязывается к текущему элементу DOM. Этот оператор используется внутри почти любого другого оператора и может применяться для выполнения произвольного кода над каждым выбранным элементом. Оператор each может использоваться для рекурсивной обработки выборки через вызов d3.select(this)
внутри функции обратного вызова.
# selection.call(function[, arguments…])
Вызывает указанную функцию function один раз, передавая её в текущую выборку вместе с любым количеством необязательных аргументов arguments. Оператор call всегда возвращает текущую выборку, независимо от возвращаемого значения указанной функции. Оператор call идентичен ручному вызову функции; но он делает более простым использование цепочечных вызовов. Например, мы хотим установить несколько атрибутов одинаковым образом в нескольких различных местах. Так что мы пишем код и оборачиваем его в переиспользуемую функцию:
function foo(selection) {
selection
.attr("name1", "value1")
.attr("name2", "value2");
}
Теперь мы можем написать так:
foo(d3.selectAll("div"))
Или эквивалентно так:
d3.selectAll("div").call(foo);
Контекст this
вызываемой функции так же привязан к текущей выборке. Это немного излишне, поскольку у нас уже есть первый аргумент, возможно в будущем это будет поправлено.
Если вы используете методы объекта в selection.call и вам нужно, чтобы this
указывал на этот объект, вам нужно привязать вашу функцию к объекту до вызова.
function Foo(text) {
this.text = text;
}
Foo.prototype.setText = function(selection) {
selection.text(this.text);
}
var bar = new Foo("Bar");
d3.selectAll("span").call(bar.setText.bind(bar));
// Или
d3.selectAll("span").call(Foo.prototype.setText.bind(bar));
# selection.empty()
Возвращает true
, если текущая выборка пустая; выборка пустая, если она не содержит элементов или содержит только нулевые элементы.
# selection.node()
Возвращает первый ненулевой элемент в текущей выборке. Если выборка пустая, возвращает null
.
# selection.size()
Возвращает общее число элементов в текущей выборке.
# d3.selection()
Возвращает корневую выборку, эквивалентна d3.select(document.documentElement)
. Эта функция так же может использоваться для проверки того, что объект является выборкой: o instanceof d3.selection
. Кроме того, вы можете добавить новые методы к прототипу selection. Например, для добавления удобновго метода для установки свойства checked
флажков-переключателей вы можете написать:
d3.selection.prototype.checked = function(value) {
return arguments.length < 1
? this.property("checked")
: this.property("checked", value);
};