Условное кодирование (conditional encoding) в Vega-Lite позволяет изменять визуальные свойства элементов графика в зависимости от состояния данных, взаимодействий пользователя или логических выражений. Наиболее распространённый сценарий — выделение объектов при наведении курсора, клике, выборе диапазона или активации фильтра.
Механизм основан на конструкции condition, которая
определяет:
Благодаря этому диаграмма становится интерактивной без ручного управления DOM-элементами.
conditionПростейший пример изменения цвета точки при выделении:
{
mark: "point",
encoding: {
color: {
condition: {
param: "hover",
value: "red"
},
value: "gray"
}
}
}
Здесь:
hover активен — точка окрашивается в
красный;paramsСовременный подход в Vega-Lite строится вокруг params.
Параметры позволяют хранить состояние взаимодействия.
Пример определения выделения:
params: [
{
name: "hover",
select: {
type: "point",
on: "mouseover",
clear: "mouseout"
}
}
]
| Свойство | Назначение |
|---|---|
name |
имя выделения |
select.type |
тип выделения |
on |
событие активации |
clear |
событие сброса |
Выделение отдельных элементов.
select: {
type: "point"
}
Используется для:
Выделение диапазона.
select: {
type: "interval"
}
Подходит для:
Один из самых популярных сценариев.
const spec = {
data: {
values: [
{x: 10, y: 20},
{x: 20, y: 40},
{x: 30, y: 10}
]
},
params: [
{
name: "hover",
select: {
type: "point",
on: "mouseover",
clear: "mouseout"
}
}
],
mark: "point",
encoding: {
x: {field: "x", type: "quantitative"},
y: {field: "y", type: "quantitative"},
size: {
condition: {
param: "hover",
value: 300
},
value: 100
},
color: {
condition: {
param: "hover",
value: "orange"
},
value: "steelblue"
}
}
};
При наведении:
Клик позволяет сохранять состояние выбора.
params: [
{
name: "selectPoint",
select: "point"
}
]
Использование:
opacity: {
condition: {
param: "selectPoint",
value: 1
},
value: 0.2
}
Такой подход часто применяется в dashboard-интерфейсах.
По умолчанию point selection поддерживает множественный выбор через Shift.
Явная настройка:
select: {
type: "point",
toggle: true
}
select: {
type: "point",
toggle: false
}
clickon: "click"
on: "dblclick"
on: "mouseover[event.shiftKey]"
Выделение активируется только при зажатом Shift.
Наиболее распространённый паттерн.
opacity: {
condition: {
param: "highlight",
value: 1
},
value: 0.15
}
shape: {
condition: {
param: "selected",
value: "diamond"
},
value: "circle"
}
strokeWidth: {
condition: {
param: "selected",
value: 4
},
value: 1
}
Особенно полезно в line chart.
test)Условие может основываться не только на selection, но и на логическом выражении.
color: {
condition: {
test: "datum.value > 100",
value: "red"
},
value: "green"
}
datumdatum представляет текущую строку данных.
test: "datum.value > 100 && datum.category === 'A'"
test: "datum.score >= 80 ? true : false"
color: {
condition: [
{
param: "hover",
value: "orange"
},
{
test: "datum.value > 50",
value: "red"
}
],
value: "gray"
}
Условия проверяются сверху вниз.
Пример для bar chart:
const spec = {
data: {
values: [
{category: "A", value: 28},
{category: "B", value: 55},
{category: "C", value: 43}
]
},
params: [
{
name: "selectBar",
select: "point"
}
],
mark: "bar",
encoding: {
x: {field: "category", type: "nominal"},
y: {field: "value", type: "quantitative"},
color: {
condition: {
param: "selectBar",
value: "crimson"
},
value: "lightgray"
}
}
};
params: [
{
name: "brush",
select: "interval"
}
]
color: {
condition: {
param: "brush",
value: "steelblue"
},
value: "lightgray"
}
Одно из сильнейших применений conditional encoding — coordinated views.
transform: [
{
filter: {
param: "brush"
}
}
]
Выделение может применяться между слоями.
layer: [
{
mark: "line"
},
{
mark: "point",
encoding: {
opacity: {
condition: {
param: "hover",
value: 1
},
value: 0
}
}
}
]
Частый паттерн для line chart.
params: [
{
name: "hover",
select: {
type: "point",
nearest: true,
on: "mouseover",
clear: "mouseout"
}
}
]
nearest: trueПозволяет автоматически выбирать ближайшую точку к курсору.
Интерактивность часто комбинируется с tooltip.
tooltip: [
{field: "x"},
{field: "y"}
]
Совместно с hover selection создаётся полноценное интерактивное исследование данных.
text: {
condition: {
param: "hover",
field: "value"
},
value: ""
}
Текст отображается только при наведении.
Для акцентирования элементов:
order: {
condition: {
param: "selected",
value: 1
},
value: 0
}
params: [
{
name: "legendSelect",
select: {
type: "point",
fields: ["category"]
},
bind: "legend"
}
]
bind: "legend"Легенда становится интерактивной:
opacity: {
condition: {
param: "legendSelect",
value: 1
},
value: 0.1
}
Иногда условие проще вынести в transform.
transform: [
{
calculate: "datum.value > 50",
as: "isHigh"
}
]
После этого:
color: {
condition: {
test: "datum.isHigh",
value: "red"
},
value: "blue"
}
color: {
condition: {
test: "datum.value > 80",
value: "darkred"
},
value: "lightyellow"
}
on: "keydown"
Можно использовать:
clear: "mouseout"
clear: "dblclick"
clear: false
Состояние будет сохраняться до следующего выбора.
Контроль поведения при отсутствии selection.
condition: {
param: "brush",
empty: false,
value: "red"
}
Если выделение пустое — условие не применяется.
При работе с большими наборами данных важно учитывать:
Сложные цепочки condition увеличивают стоимость
рендеринга.
mousemove значительно тяжелее click.
Много слоёв с condition могут приводить к заметным задержкам.
Один из самых популярных UX-приёмов.
opacity: {
condition: {
param: "hover",
value: 1
},
value: 0.05
}
Комбинация interval selection и linked views.
params: [
{
name: "brush",
select: "interval"
}
]
Используется для:
bind: "legend"
Позволяет превратить обычную легенду в полноценный инструмент фильтрации.
В Vega условное кодирование обычно реализуется через
signals.
fill: [
{
test: "hover",
value: "red"
},
{
value: "gray"
}
]
Наиболее эффективные сценарии:
clearclear: "mouseout"
Без очистки выделение может «залипать».
condition: [
{...},
{...}
]
Первое совпавшее условие имеет приоритет.
Нежелательно использовать одинаковые имена параметров для разных типов выделения.
Слишком большое количество hover-эффектов ухудшает UX и производительность.
Пользователь должен понимать:
Изменение прозрачности:
Это важный UX-принцип при проектировании интерактивных визуализаций.
const spec = {
data: {
values: [
{x: 1, y: 28, category: "A"},
{x: 2, y: 55, category: "B"},
{x: 3, y: 43, category: "A"},
{x: 4, y: 91, category: "C"},
{x: 5, y: 81, category: "B"}
]
},
params: [
{
name: "hover",
select: {
type: "point",
on: "mouseover",
clear: "mouseout",
nearest: true
}
},
{
name: "selected",
select: {
type: "point",
on: "click"
}
}
],
mark: "point",
encoding: {
x: {
field: "x",
type: "quantitative"
},
y: {
field: "y",
type: "quantitative"
},
color: {
condition: [
{
param: "selected",
value: "crimson"
},
{
param: "hover",
value: "orange"
}
],
field: "category",
type: "nominal"
},
size: {
condition: {
param: "hover",
value: 300
},
value: 100
},
opacity: {
condition: {
param: "selected",
value: 1
},
value: 0.3
},
tooltip: [
{field: "x"},
{field: "y"},
{field: "category"}
]
}
};