Интерактивность в Vega и Vega-Lite строится вокруг сигналов
(signals) и параметров (params). Одним из
ключевых механизмов связи интерфейса и визуализации является свойство
bind, позволяющее привязать HTML-элементы управления к
данным графика.
Через bind реализуются:
range);select);checkbox);input);radio).Наиболее востребованы именно ползунки и выпадающие списки, поскольку они позволяют:
В Vega-Lite пользовательский интерфейс обычно строится так:
Создаётся параметр (param).
Параметр связывается с HTML-элементом через
bind.
Значение параметра используется:
encoding),condition).Схема работы:
HTML input -> bind -> param -> график
range)Ползунок создаётся через bind: { input: "range" }.
Пример:
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"data": {
"values": [
{"x": 1, "y": 10},
{"x": 2, "y": 20},
{"x": 3, "y": 30},
{"x": 4, "y": 40}
]
},
"params": [
{
"name": "pointSize",
"value": 100,
"bind": {
"input": "range",
"min": 10,
"max": 500,
"step": 10
}
}
],
"mark": "point",
"encoding": {
"x": {"field": "x", "type": "quantitative"},
"y": {"field": "y", "type": "quantitative"},
"size": {
"value": {
"expr": "pointSize"
}
}
}
}
minМинимальное значение.
"min": 0
maxМаксимальное значение.
"max": 100
stepШаг изменения.
"step": 5
Если шаг не указан, браузер может использовать дробные значения.
nameПодпись рядом с ползунком.
"bind": {
"input": "range",
"name": "Размер: "
}
Один из самых частых сценариев — управление размерами объектов.
{
"params": [
{
"name": "radius",
"value": 50,
"bind": {
"input": "range",
"min": 10,
"max": 300
}
}
],
"mark": {
"type": "circle"
},
"encoding": {
"size": {
"expr": "radius"
}
}
}
Ползунок удобно использовать для настройки opacity.
{
"params": [
{
"name": "alpha",
"value": 0.5,
"bind": {
"input": "range",
"min": 0,
"max": 1,
"step": 0.1
}
}
],
"mark": {
"type": "bar",
"opacity": {
"expr": "alpha"
}
}
}
Ползунок может ограничивать отображаемые данные.
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"data": {
"url": "data/cars.json"
},
"params": [
{
"name": "minHorsepower",
"value": 100,
"bind": {
"input": "range",
"min": 50,
"max": 250,
"step": 10,
"name": "Минимум HP: "
}
}
],
"transform": [
{
"filter": "datum.Horsepower >= minHorsepower"
}
],
"mark": "point",
"encoding": {
"x": {
"field": "Horsepower",
"type": "quantitative"
},
"y": {
"field": "Miles_per_Gallon",
"type": "quantitative"
}
}
}
exprПараметры через bind часто работают совместно с
выражениями (expr).
Это позволяет:
Пример:
"expr": "sliderValue * 2"
Интерактивность становится особенно мощной при использовании нескольких параметров.
{
"params": [
{
"name": "widthValue",
"value": 2,
"bind": {
"input": "range",
"min": 1,
"max": 10
}
},
{
"name": "opacityValue",
"value": 0.7,
"bind": {
"input": "range",
"min": 0,
"max": 1,
"step": 0.1
}
}
]
}
select)Выпадающий список создаётся через:
"bind": {
"input": "select"
}
optionsГлавный параметр — options.
{
"params": [
{
"name": "selectedCountry",
"value": "USA",
"bind": {
"input": "select",
"options": [
"USA",
"Japan",
"Germany"
]
}
}
]
}
"bind": {
"input": "select",
"name": "Страна: "
}
Наиболее популярный сценарий — фильтрация категориальных данных.
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"data": {
"url": "data/cars.json"
},
"params": [
{
"name": "originFilter",
"value": "USA",
"bind": {
"input": "select",
"options": [
"USA",
"Japan",
"Europe"
],
"name": "Регион: "
}
}
],
"transform": [
{
"filter": "datum.Origin == originFilter"
}
],
"mark": "point",
"encoding": {
"x": {
"field": "Horsepower",
"type": "quantitative"
},
"y": {
"field": "Miles_per_Gallon",
"type": "quantitative"
},
"color": {
"field": "Origin",
"type": "nominal"
}
}
}
Иногда требуется показать человеку одни значения, а использовать другие.
Для этого применяются:
optionslabels{
"bind": {
"input": "select",
"options": [
"usa",
"jp",
"eu"
],
"labels": [
"США",
"Япония",
"Европа"
]
}
}
Выпадающий список может менять тип визуализации.
mark{
"params": [
{
"name": "chartType",
"value": "bar",
"bind": {
"input": "select",
"options": [
"bar",
"line",
"area"
]
}
}
],
"mark": {
"type": {
"expr": "chartType"
}
}
}
{
"params": [
{
"name": "scheme",
"value": "blues",
"bind": {
"input": "select",
"options": [
"blues",
"reds",
"greens",
"viridis"
]
}
}
],
"encoding": {
"color": {
"field": "value",
"scale": {
"scheme": {
"expr": "scheme"
}
}
}
}
}
Интерфейс часто строится из нескольких связанных контролов.
{
"params": [
{
"name": "category",
"value": "A",
"bind": {
"input": "select",
"options": ["A", "B", "C"]
}
},
{
"name": "limit",
"value": 50,
"bind": {
"input": "range",
"min": 0,
"max": 100
}
}
]
}
bind в
VegaВ чистой Vega механизм строится на signals.
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"signals": [
{
"name": "scaleFactor",
"value": 1,
"bind": {
"input": "range",
"min": 1,
"max": 10,
"step": 1
}
}
]
}
Использует:
paramsПодходит для:
Использует:
signalsПодходит для:
bind поддерживает дополнительные HTML-атрибуты.
"bind": {
"input": "range",
"min": 0,
"max": 100,
"step": 1,
"name": "Значение: "
}
На стороне браузера это превращается в обычный:
<input type="range">
Ползунки часто используются для управления доменом шкалы.
{
"params": [
{
"name": "maxX",
"value": 100,
"bind": {
"input": "range",
"min": 10,
"max": 500
}
}
],
"encoding": {
"x": {
"field": "value",
"scale": {
"domain": [0, {"expr": "maxX"}]
}
}
}
}
Параметры могут участвовать в условиях.
{
"encoding": {
"color": {
"condition": {
"test": "threshold > 50",
"value": "red"
},
"value": "blue"
}
}
}
Ползунки способны управлять временными диапазонами.
{
"params": [
{
"name": "year",
"value": 2000,
"bind": {
"input": "range",
"min": 1990,
"max": 2020,
"step": 1
}
}
]
}
bindbind создаёт только стандартные HTML-контролы.
Нельзя напрямую встроить:
Стилизация зависит от браузера.
Для полноценного UI обычно используют:
Сложные взаимосвязи между элементами удобнее реализовывать в Vega
через signals.
Плохо:
"name": "x"
Хорошо:
"name": "minPrice"
Слишком широкий диапазон ухудшает UX.
Плохо:
"min": 0,
"max": 1000000
Лучше:
"min": 0,
"max": 100
stepБез шага пользователь получает неудобные дробные значения.
"step": 1
Всегда желательно задавать value.
"value": 50
valueИногда график стартует с undefined.
{
"name": "slider"
}
Правильно:
{
"name": "slider",
"value": 10
}
Ползунок возвращает число, список — строку.
Ошибка:
datum.value > category
exprОшибка:
"expr": slider
Правильно:
"expr": "slider"
Значения параметров можно получать программно.
view.signal('threshold')
Изменение значения:
view.signal('threshold', 50).run()
bind не исключает событийную модель Vega.
Можно одновременно использовать:
on;signals;params;Ползунки:
Списки:
Через bind удобно управлять:
Ползунки позволяют визуализировать:
bind и
внешнего UIbindПреимущества:
Недостатки:
Преимущества:
Недостатки:
bindbind особенно эффективен, если требуется:
Для сложных приложений обычно комбинируют: