Сигналы

Сигналы — динамические переменные, задающие параметры визуализации и управляющие её интерактивностью. Сигналы можно использовать в разных частях спецификации Vega, например для задания свойства примитива или параметра преобразования данных.

Значения сигналов реактивны: они могут изменяться при поступлении событий ввода, вызовах внешнего API или изменении других сигналов. Потоки событий собирают и упорядочивают события ввода, например mousedown и touchmove. При возникновении события связанные с ним сигналы вычисляются заново в порядке их определения в спецификации. Затем новые значения передаются остальным частям спецификации, и визуализация автоматически перерисовывается.

Пример определения сигнала и его использования в спецификации:

{
  "signals": [
    {
      "name": "indexDate",
      "description": "Дата, которая обновляется при перемещении указателя мыши.",
      "update": "datetime(2005, 0, 1)",
      "on": [{"events": "mousemove", "update": "invert('x', x())"}]
    }
  ],
  "data": [
    { "name": "stocks", ... },
    {
      "name": "index",
      "source": "stocks",
      "transform": [
        {
          "type": "filter",
          "expr": "month(datum.date) === month(indexDate)"
        }
      ]
    }
  ],
  "scales": [
    { "name": "x", "type": "time", ... }
  ],
  "marks": [
    {
      "type": "rule",
      "encode": {
        "update": {
          "x": {"scale": "x", "signal": "indexDate"}
        }
      }
    }
  ]
}

Свойства сигнала

При определении сигнала можно использовать следующие свойства.

Свойство Тип Описание
name String Обязательно. Уникальное имя сигнала. Оно должно быть допустимым идентификатором JavaScript: содержать только буквы, цифры, $ или _ и не начинаться с цифры. Зарезервированные имена "datum", "event", "item" и "parent" использовать нельзя.
bind Привязка Привязывает сигнал к элементу ввода, например ползунку, раскрывающемуся списку или группе переключателей.
description String Текстовое описание сигнала для документации внутри спецификации.
on Обработчик[ ] Массив обработчиков потоков событий, обновляющих значение сигнала при событиях ввода.
init Выражение ≥ 4.4 Выражение для инициализации значения сигнала. Вычисляется только один раз. Свойства init и update взаимоисключающие.
update Выражение Выражение для обновления значения сигнала. Оно может ссылаться на другие сигналы; тогда значение обновляется при их изменении, если свойство react не равно false. Свойства init и update взаимоисключающие.
react Boolean Логический признак, определяющий, нужно ли автоматически пересчитывать выражение update при изменении связанных сигналов. По умолчанию true. Если задано false, зависимости от других сигналов не регистрируются даже при инициализации.
value Any Начальное значение сигнала (по умолчанию undefined). Присваивается до вычисления выражения init или update.

Встроенные сигналы

Некоторые имена сигналов обрабатываются автоматически или зарезервированы:

  • Сигналы для свойств спецификации width, height, padding, autosize, а начиная с версии ≥ 5.10 и background, определяются автоматически. Их можно также определить в массиве signals верхнего уровня. В этом случае определения объединяются со значениями одноимённых свойств спецификации, причём приоритет имеют свойства из массива signals.
  • Экземпляры групповых примитивов автоматически содержат сигнал parent, связанный с объектом данных группы. Определять в спецификации сигнал с именем parent нельзя.
  • Имена datum, item и event зарезервированы для переменных верхнего уровня в выражениях. Определять сигналы с этими именами нельзя.
  • Если определить сигнал cursor, его значение будет управлять CSS-видом указателя мыши в представлении Vega. Подробнее см. описание сигнала cursor ниже.

Сигнал cursor

По умолчанию Vega меняет вид указателя мыши, когда он находится над примитивом со свойством cursor. Но при некоторых взаимодействиях курсор должен сохранять свой вид до их завершения: например, во время перетаскивания, даже если указатель ушёл с исходного примитива. Для этого служит отдельный сигнал cursor. Если ему задано значение, Vega использует его вместо свойств cursor отдельных примитивов. Значение "default" возвращает управление курсором свойствам примитивов.

Вложенные сигналы

Сигналы можно определять на верхнем уровне спецификации или внутри группового примитива. Сигнал, определённый во вложенной группе, доступен только в её области видимости: все примитивы, оси, легенды и другие элементы, которые на него ссылаются, должны находиться внутри этой группы. Если имя вложенного сигнала совпадает с именем сигнала во внешней области видимости, вложенное определение переопределяет внешнее.

Помимо новых определений, вложенный групповой примитив может содержать обновления сигналов из внешней области видимости. Свойство "push": "outer" означает, что обновление относится к уже существующему сигналу, а не создаёт новый. Во вложенном обновлении сигнала нельзя использовать свойства value и update. Доступны следующие свойства:

Свойство Тип Описание
name String Обязательно. Имя обновляемого сигнала.
push String Обязательно. Для обновления сигнала из внешней области видимости свойству push нужно присвоить "outer".
description String Текстовое описание сигнала для документации.
on Обработчик[ ] Массив обработчиков потоков событий, обновляющих значение сигнала при событиях ввода.

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

Объект обработчика содержит определение потока событий, задающее обрабатываемые события, а также выражение update для нового значения сигнала либо набор свойств кодирования encode для обновления примитива, с которым взаимодействует пользователь.

Свойство Тип Описание
events Поток событий Обязательно. События, на которые реагирует обработчик.
update Выражение Выражение, вычисляемое при возникновении события. Его результат становится новым значением сигнала. Свойство обязательно, если не указано encode.
encode String Имя набора свойств кодирования примитива, который нужно пересчитать для элемента, вызвавшего событие ввода. Свойство обязательно, если не указано update.
force Boolean Логический признак (по умолчанию false), определяющий, нужно ли передавать обновления, которые не изменяют значение сигнала. При true зависимые сигналы получат уведомление, даже если событие установит прежнее значение.

Этот сигнал увеличивает своё значение при событии mouseover на элементах rect:

{
  "name": "count",
  "value": 0,
  "on": [
    {"events": "rect:mouseover", "update": "count + 1"}
  ]
}

Этот сигнал применяет специальные наборы свойств кодирования при событиях mousedown и mouseup на элементах примитивов. Определение примитива должно содержать наборы "select" и "release" в свойстве "encode".

{
  "name": "clickEncode",
  "on": [
    {"events": "*:mousedown", "encode": "select"},
    {"events": "*:mouseup", "encode": "release"}
  ]
}

Привязка к элементу ввода

Свойство bind привязывает сигнал к элементу ввода вне визуализации. Vega создаёт элементы HTML-формы и устанавливает двустороннюю связь: изменение элемента обновляет сигнал, а изменение сигнала — элемент. Предусмотрена поддержка типов checkbox (флажок с логическим значением), radio (группа переключателей), select (раскрывающийся список) и range (ползунок). Сигнал также можно привязать к существующему внешнему элементу.

Свойство Тип Описание
input String Обязательно. Тип элемента ввода: checkbox, radio, range, select или любой другой допустимый тип элемента HTML-формы.
element String Необязательный CSS-селектор родительского элемента, в который нужно добавить элемент ввода. По умолчанию элементы ввода добавляются в родительский контейнер представления Vega.
name String По умолчанию элемент ввода подписывается именем сигнала. Свойство name позволяет задать для связанного сигнала другую подпись.
debounce Number Если задано, откладывает обработку события до истечения указанного числа миллисекунд после последнего события.

Свойства элементов radio и select

Свойство Тип Описание
options Array Обязательно. Массив вариантов для выбора.
labels String[ ] ≥ 5.9 Массив подписей для значений options. Если не задан, значение options преобразуется в строку и используется как подпись.
name String По умолчанию элемент ввода подписывается именем сигнала. Свойство name позволяет задать другую подпись.
debounce Number Если задано, откладывает обработку события до истечения указанного числа миллисекунд после последнего события.

Свойства элемента range

Свойство Тип Описание
max Number Максимальное значение ползунка range. По умолчанию — большее из значения сигнала и 100.
min Number Минимальное значение ползунка range. По умолчанию — меньшее из значения сигнала и 0.
step Number Минимальный шаг ползунка range. Если не задан, шаг определяется автоматически по значениям min и max.
name String По умолчанию элемент ввода подписывается именем сигнала. Свойство name позволяет задать другую подпись.
debounce Number Если задано, откладывает обработку события до истечения указанного числа миллисекунд после последнего события.

Другие типы элементов ввода

Свойству input можно присвоить любой допустимый тип элемента ввода HTML, например "text" (однострочное текстовое поле), "color" (выбор цвета) или "date" (ввод года, месяца и дня). В этих случаях дополнительные свойства, например placeholder для "text", добавляются как атрибуты создаваемого элемента HTML-формы.

Прямая привязка к внешним элементам

Вместо создания нового элемента ввода Vega может привязать сигнал к уже существующему внешнему элементу. Для этого свойство input не задаётся, а свойство element ссылается на существующий элемент.

Свойство Тип Описание
element String Обязательно. Элемент ввода со свойством value и поддержкой интерфейса EventTarget либо CSS-селектор такого элемента. Когда элемент изменяется и отправляет событие, значение value становится новым значением связанного сигнала. Когда сигнал изменяется независимо от элемента, его значение записывается в value, после чего на элементе отправляется новое событие.
event String Событие, по которому отслеживаются изменения внешнего элемента. По умолчанию "input".
debounce Number Если задано, откладывает обработку события до истечения указанного числа миллисекунд после последнего события.