В системе интерактивности Vega и Vega-Lite поле on
определяет события, при которых изменяется состояние выделения
(selection). Через него описываются пользовательские
действия:
Поле on является центральным механизмом управления
интерактивностью. Именно оно связывает визуальные элементы с
DOM-событиями браузера и позволяет строить:
В Vega-Lite поле on находится внутри описания
выделения:
{
params: [
{
name: "selectPoint",
select: {
type: "point",
on: "click"
}
}
]
}
Здесь:
type: "point" — выделение отдельных точек;on: "click" — событие, запускающее выделение.Vega использует собственную декларативную систему событий поверх DOM API браузера.
Поддерживаются:
| Категория | Примеры |
|---|---|
| События мыши | click, dblclick,
mousemove |
| Кнопки мыши | mousedown, mouseup |
| Наведение | mouseover, mouseout |
| Колёсико | wheel |
| Сенсорные события | touchstart, touchmove |
| Клавиатура | keydown, keyup |
| Комбинации | [mousedown, mouseup] > mousemove |
{
params: [
{
name: "pointSelect",
select: {
type: "point",
on: "click"
}
}
]
}
Выделение произойдёт при каждом клике по mark-элементу.
Одним из самых распространённых сценариев является реакция на курсор.
{
params: [
{
name: "hoverSelect",
select: {
type: "point",
on: "mouseover"
}
}
]
}
Теперь объект активируется при наведении мыши.
mousemoveСобытие mousemove срабатывает постоянно при движении
курсора.
{
params: [
{
name: "tracking",
select: {
type: "point",
on: "mousemove"
}
}
]
}
Такой подход используется:
dblclick{
params: [
{
name: "doubleClickSelection",
select: {
type: "point",
on: "dblclick"
}
}
]
}
Типичные сценарии:
mousedownСрабатывает в момент нажатия.
{
on: "mousedown"
}
mouseupСрабатывает при отпускании кнопки.
{
on: "mouseup"
}
Такие события критически важны для drag-and-drop взаимодействий.
mouseoverАктивируется при входе курсора в область элемента.
{
on: "mouseover"
}
mouseoutСрабатывает при выходе курсора.
{
on: "mouseout"
}
Пример очистки выделения:
{
params: [
{
name: "hover",
select: {
type: "point",
on: "mouseover",
clear: "mouseout"
}
}
]
}
clearХотя clear является отдельным свойством, оно тесно
связано с on.
{
params: [
{
name: "hoverState",
select: {
type: "point",
on: "mouseover",
clear: "mouseout"
}
}
]
}
Здесь:
mouseover создаёт выделение;mouseout удаляет его.Vega поддерживает сложные цепочки событий.
{
on: "[mousedown, mouseup] > mousemove"
}
Это означает:
mouseup.Такая конструкция применяется для:
onПример интервального выделения:
{
params: [
{
name: "brush",
select: {
type: "interval",
on: "[mousedown, mouseup] > mousemove"
}
}
]
}
Vega позволяет фильтровать события.
{
on: "mousedown[event.button === 0]"
}
{
on: "mousedown[event.button === 2]"
}
{
on: "click[event.shiftKey]"
}
{
on: "click[event.ctrlKey]"
}
{
on: "click[event.altKey]"
}
Можно указывать несколько событий.
{
on: "click, mouseover"
}
Выделение будет происходить:
Допускается массив.
{
on: [
"click",
"mouseover"
]
}
В Vega доступна расширенная объектная конфигурация.
{
on: {
type: "click",
filter: ["event.shiftKey"]
}
}
filter{
on: {
type: "click",
filter: [
"event.shiftKey",
"event.button === 0"
]
}
}
Условия:
События могут приходить из различных источников.
view{
on: {
type: "mousemove",
source: "view"
}
}
| Источник | Назначение |
|---|---|
view |
Всё представление |
window |
Глобальное окно браузера |
scope |
Локальная область |
event |
Текущий event-контекст |
windowПолезно для drag-взаимодействий.
{
on: {
type: "mousemove",
source: "window"
}
}
Даже если курсор покинет график, событие продолжит отслеживаться.
{
on: "keydown"
}
{
on: "keyup"
}
{
on: "keydown[event.key === 'Escape']"
}
{
on: "keydown[event.key === 'Enter']"
}
Для мобильных устройств Vega поддерживает touch API.
{
on: "touchstart"
}
{
on: "touchmove"
}
{
on: "touchend"
}
Колёсико мыши активно используется для масштабирования.
{
on: "wheel"
}
{
on: "wheel[event.deltaY < 0]"
}
Такой фильтр реагирует только на прокрутку вверх.
consumeИногда необходимо предотвратить дальнейшее распространение события.
{
on: {
type: "wheel",
consume: true
}
}
Аналогично event.preventDefault().
on и
toggleПоле toggle определяет поведение повторного выбора.
{
params: [
{
name: "multi",
select: {
type: "point",
on: "click",
toggle: "event.shiftKey"
}
}
]
}
Здесь:
on и
nearest{
params: [
{
name: "hover",
select: {
type: "point",
nearest: true,
on: "mousemove"
}
}
]
}
Теперь выбирается ближайшая точка к курсору.
{
params: [
{
name: "dragBrush",
select: {
type: "interval",
on: "[mousedown, window:mouseup] > window:mousemove"
}
}
]
}
Особенности:
В Vega поддерживаются механизмы оптимизации.
{
on: {
type: "mousemove",
throttle: 50
}
}
Событие будет срабатывать не чаще одного раза в 50 мс.
debounce{
on: {
type: "mousemove",
debounce: 100
}
}
Событие выполнится только после паузы.
throttle и debounce| Механизм | Поведение |
|---|---|
throttle |
Ограничивает частоту |
debounce |
Ждёт завершения серии событий |
{
params: [
{
name: "hover",
select: {
type: "point",
nearest: true,
on: "mousemove",
clear: "mouseout"
}
}
]
}
Такой шаблон используется почти во всех интерактивных графиках.
{
params: [
{
name: "multiSelect",
select: {
type: "point",
on: "click",
toggle: "event.shiftKey"
}
}
]
}
{
params: [
{
name: "zoomArea",
select: {
type: "interval",
on: "[mousedown, mouseup] > mousemove"
}
}
]
}
В Vega события применяются не только в selections, но и в signals.
{
"signals": [
{
"name": "cursorX",
"on": [
{
"events": "mousemove",
"update": "x()"
}
]
}
]
}
eventsВ чистой Vega вместо on часто используется
events.
{
"events": "mousemove"
}
Это более низкоуровневый API.
Signals позволяют:
{
"signals": [
{
"name": "mousePosition",
"on": [
{
"events": "mousemove",
"update": "[x(), y()]"
}
]
}
]
}
Некоторые события генерируются чрезвычайно часто:
mousemove;wheel;touchmove.Без ограничений они могут перегружать визуализацию.
{
on: {
type: "mousemove",
throttle: 30
}
}
{
on: {
type: "mousemove",
debounce: 100
}
}
Не рекомендуется:
mousemove;{
on: "hover"
}
События hover не существует.
Правильно:
{
on: "mouseover"
}
click и
dblclickБраузер сначала генерирует click, затем
dblclick.
Это может вызывать двойные реакции интерфейса.
Ошибка:
{
on: "[mousedown, mouseup] > mousemove"
}
Если курсор покидает область графика, drag может оборваться.
Лучше:
{
on: "[mousedown, window:mouseup] > window:mousemove"
}
{
on: "mousemove",
clear: "mouseout"
}
{
on: "[mousedown, window:mouseup] > window:mousemove"
}
{
on: "click",
toggle: "event.shiftKey"
}
{
throttle: 50
}
{
params: [
{
name: "interactiveSelection",
select: {
type: "point",
on: "mousemove",
nearest: true,
clear: "mouseout",
toggle: "event.shiftKey"
}
}
]
}
Такое выделение: