Примитивы

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

Поддерживаемые типы примитивов

Поддерживаются следующие типы примитивов:

  • arc — дуги окружности, включая секторы круговых и кольцевых диаграмм.
  • area — закрашенные области с горизонтальной или вертикальной ориентацией.
  • image — изображения, включая значки и фотографии.
  • group — контейнеры для других примитивов, полезные для вложенных графиков.
  • line — линии, часто используемые для отображения изменений во времени.
  • path — произвольные контуры или многоугольники, заданные синтаксисом путей SVG.
  • rect — прямоугольники, например для столбчатых диаграмм и временных шкал.
  • rule — отрезки, часто используемые для делений осей и линий сетки.
  • shape — специальный вариант контуров для ускоренного отображения карт.
  • symbol — символы на графике, включая круги, квадраты и другие фигуры.
  • text — текстовые подписи с настройкой шрифта, выравнивания и угла поворота.
  • trail — линии с толщиной, меняющейся в зависимости от данных.

Визуальное кодирование

У каждого типа примитива есть набор свойств визуального кодирования, определяющих положение и внешний вид его экземпляров. Обычно для каждой записи данных создаётся один экземпляр. Исключения — line и area: они представляют несколько записей одной линией или областью.

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

{
  "type": "rect",
  "from": {"data": "table"},
  "encode": {
    "enter": {
      "y": {"scale": "yscale", "field": "value"},
      "y2": {"scale": "yscale", "value": 0},
      "fill": {"value": "steelblue"}
    },
    "update": {...},
    "exit": {...},
    "hover": {...}
  }
}

Есть три основных набора свойств: enter, update и exit. Свойства enter вычисляются при первой обработке данных, когда новый экземпляр примитива добавляется в сцену. Свойства update вычисляются для всех существующих экземпляров, кроме удаляемых. Свойства exit вычисляются, когда запись данных удаляется и связанный с ней экземпляр покидает сцену. Подробнее об этих наборах рассказывается в материале Майка Бостока «Thinking with Joins».

Необязательный набор hover определяет внешний вид экземпляра примитива при наведении указателя мыши. Когда указатель покидает элемент, снова применяется набор update.

Особый тип примитива group может содержать другие примитивы, а также локальные определения данных, сигналов, шкал, осей и легенд. Группы позволяют строить визуализации из повторяющихся элементов: например, диаграммы с накоплением, где каждый слой — отдельная группа, или набор небольших графиков, каждый в своей группе. Подробнее см. страницу «Группы примитивов».

Свойства примитива верхнего уровня

Свойство Тип Описание
type String Обязательно. Тип графического примитива. Должен входить в список поддерживаемых типов.
clip Обрезка Определяет, нужно ли обрезать примитивы по заданной области (по умолчанию false). При логическом значении область обрезки задаётся шириной и высотой охватывающей группы. Объект позволяет указать произвольный контур SVG или картографическую проекцию для обрезки по сфере Земли.
encode Кодирование Объект с наборами правил визуального кодирования свойств примитива.
from Источник данных Объект, описывающий данные для этого набора примитивов. Если не задан, используется набор из одной пустой записи. Свойство from может указывать набор данных, например {"data": "table"}, или содержать указание на разбиение данных между несколькими группами group.
interactive Boolean Логический признак (по умолчанию true), определяющий, могут ли примитивы быть источниками событий ввода. При false события мыши и касания для них не создаются. Можно также указать сигнал, чтобы менять интерактивность динамически.
key Field Поле данных, используемое как уникальный ключ при связывании записей с примитивами. При обновлении данных ключ помогает сопоставить записи с уже существующими экземплярами и сохранить их идентичность при переходах.
name String Уникальное имя примитива. На него можно ссылаться в определении потока событий. При выводе SVG это имя добавляется как CSS-класс охватывающего элемента группы (g), содержащего экземпляры примитива.
on Триггер[ ] Набор триггеров, изменяющих свойства примитива при изменении сигналов.
sort Compare Правило сравнения для сортировки экземпляров примитива. Порядок сортировки определяет порядок их отрисовки по умолчанию. Сортировка выполняется после вычисления кодирования над элементами графа сцены, поэтому их можно сортировать по размеру или положению. Чтобы дополнительно сортировать по исходным данным, добавьте к имени поля префикс datum., например {"field": "datum.field"}.
transform Преобразование[ ] Набор преобразований, выполняемых после блоков encode непосредственно над элементами графа сцены, а не над исходными объектами данных. Они полезны для размещения элементов и могут задавать x, y, width, height и другие свойства. Допускаются только преобразования, которые не создают и не фильтруют объекты данных.
role String Строка метаданных, обозначающая роль примитива. При выводе SVG значение с префиксом role- добавляется как CSS-класс охватывающей группы (g). Vega использует роли при размещении элементов. Задавайте это свойство, только если понимаете, как оно повлияет на размещение.
style String | String[ ] Имя стиля или массив имён стилей для примитива. Стиль — именованный набор значений свойств по умолчанию, заданный в конфигурации. Его свойства применяются к набору кодирования enter; более поздние стили переопределяют предыдущие. Свойства, явно указанные в блоке encode, имеют приоритет над значениями стиля.
zindex Number Целое число, задающее слой набора примитивов относительно других примитивов, осей и легенд. По умолчанию 0; наборы с большим значением рисуются поверх наборов с меньшим. Свойство относится ко всему набору, а не к отдельным элементам. Для изменения порядка элементов внутри набора используйте канал кодирования zindex.

Свойства доступности ≥ 5.11

Свойства доступности определяют атрибуты ARIA при выводе SVG. Vega автоматически создаёт атрибуты ARIA role и roleDescription для элементов контейнера SVG <g>, содержащих набор экземпляров примитива. Приведённые ниже свойства позволяют отключить атрибуты ARIA или добавить текстовое описание. Для отдельных экземпляров атрибуты ARIA можно также задать в каналах кодирования.

Свойство Тип Описание
aria Boolean Логический признак (по умолчанию true), определяющий, нужно ли добавлять атрибуты ARIA при выводе SVG. При false группе SVG присваивается aria-hidden, и примитив исключается из дерева доступности.
description String Текстовое описание примитива для ARIA (только при выводе SVG). Если aria равно true, описание записывается в атрибут aria-label.

Обрезка примитивов

Свойство clip ограничивает область видимости набора примитивов. Значение по умолчанию false отключает обрезку. Значение true обрезает примитивы по ширине и высоте охватывающей группы. Свойство clip также принимает сигнал, вычисляемый в логическое значение.

Для более сложной области обрезки используйте объект. Он должен содержать либо свойство path для произвольного контура SVG, либо sphere для обрезки по земному шару с учётом картографической проекции, но не оба сразу. Каждое из этих свойств может быть сигналом, чтобы область обрезки менялась динамически.

Свойство Тип Описание
path String | Signal Строка пути SVG, описывающая область обрезки. Координаты задаются относительно охватывающей группы.
sphere String | Signal Имя картографической проекции, по которой примитивы обрезаются границей проецируемого земного шара. Это полезно для проекций, отображающих за пределами шара линии координатной сетки и другие элементы.

Источники данных примитивов (from)

Свойство from указывает источник данных для набора примитивов.

Свойство Тип Описание
data String Имя набора данных для отображения.
facet Разбиение Необязательное определение разбиения данных между несколькими группами. Указание facet допускается только в определениях примитива group.

Разбиение данных на группы

Указание facet разбивает источник данных между несколькими экземплярами группового примитива. Каждой группе соответствует агрегированная запись, представляющая группу целиком, и собственный именованный источник с её частью данных. Разбиение может выполняться по данным, когда записи группируются по заданным полям, или использовать заранее разбитые данные, где исходная запись уже содержит массив вложенных записей.

Свойство Тип Описание
name String Обязательно. Имя создаваемого источника данных группы. Примитивы внутри этой группы могут обращаться к нему для отображения локальной части данных.
data String Обязательно. Имя исходного набора данных для разбиения.
field Field Для заранее разбитых данных — имя поля с массивом записей локальной группы. В этом случае свойство обязательно.
groupby Field | Field[ ] Для разбиения по данным — массив имён полей, по которым группируются записи. В этом случае свойство обязательно.
aggregate Object Для разбиения по данным — необязательный объект с параметрами преобразования aggregate для агрегированных записей групп. Поддерживаются fields, ops, as и cross.

При разбиении по данным для каждого экземпляра группы по умолчанию создаётся новая агрегированная запись. Но если в объекте from заданы оба свойства — data и facet, — используются уже существующие агрегированные записи из источника data. В этом случае значения groupby для агрегирования и разбиения обязательно должны совпадать. Иначе поведение визуализации не определено.

Реактивная геометрия

Обычно запись "from": {"data": "..."} обращается к источнику, определённому в блоке "data". Но Vega позволяет использовать экземпляры одного набора примитивов как данные для другого набора. Это называется реактивной геометрией. Например, можно создать текстовые подписи и разместить их по вычисленным значениям x, y, width или height исходных примитивов.

Чтобы использовать набор примитивов как источник данных, задайте ему уникальное свойство name. После этого на набор можно ссылаться как "from": {"data": "name"}.

В этом примере точечные примитивы служат источником данных для текстовых примитивов:

{
  "marks": [
    {
      "name": "baseMarks",
      "type": "point",
      "from": {"data": "source"},
      "encode": {...}
    },
    {
      "type": "text",
      "from": {"data": "baseMarks"},
      "encode": {
        "update": {
          "x": {"field": "x", "offset": 4},
          "y": {"field": "y"},
          "text": {"field": "datum.label"}
        }
      }
    }
  ]
}

Наборы кодирования примитивов

Визуальные свойства примитива задаются парами «имя — значение» внутри набора свойств, например update, enter или exit. Имя обозначает визуальное свойство. У каждого типа примитива есть стандартные каналы кодирования, но можно указать и произвольное имя: оно станет новым именованным свойством элемента графа сцены. Значение свойства задаётся ссылкой на значение или условным правилом, описанными ниже.

Набор enter применяется при создании экземпляра примитива. Если не указано иное, набор update применяется при каждом обновлении данных или свойств отображения. Набор exit применяется при удалении связанной с экземпляром записи данных. Если для представления Vega включена обработка наведения, при наведении указателя применяется набор hover.

Допускаются и собственные наборы кодирования с произвольными именами. Чтобы применить такой набор вместо update, передайте его имя методу запуска представления Vega или определите обработчик события сигнала со свойством "encode".

Ссылки на значения

Ссылка на значение задаёт значение свойства примитива. Это может быть константа или значение из объекта данных. Кроме того, значение можно преобразовать шкалой или изменить другим способом. Примеры:

  • {"value": "left"} — константа.
  • {"field": "amount"} — значение поля данных.
  • {"scale": "yscale", "field": "amount"} — значение поля данных после преобразования шкалой.
  • {"signal": "hypot(datum.a, datum.b)" — значение выражения сигнала.

Подробнее см. описание типа Value, а также специальных типов ColorValue и FieldValue.

Условные правила

Визуальные свойства также можно задавать цепочкой условных правил по схеме «если — то — иначе». Правила представляют собой массив ссылок на значения; каждая из них должна содержать дополнительное свойство test. Оно задаёт логическое выражение, возвращающее true или false. Свойство получает значение из первого правила, у которого выражение test возвращает true.

Последним элементом массива можно указать ссылку на значение без свойства test — она будет соответствовать ветке «иначе». Если ни одно условие test не вернуло true, используется эта последняя ссылка на значение. Если ветка «иначе» отсутствует, значение свойства по умолчанию — null.

Например, здесь цвет заливки примитива задаётся условным правилом:

"fill": [
  {
    "test": "indata('selectedPoints', 'key', datum.key)",
    "scale": "c",
    "field": "species"
  },
  {"value": "grey"}
]

Если идентификатор записи найден в источнике selectedPoints, цвет заливки определяется преобразованием шкалой. Иначе примитив окрашивается в серый цвет.