Система связывания bind в спецификациях Vega и Vega-Lite
реализует прямую интеграцию параметров визуализации с DOM-элементами
управления. Она позволяет сигналам (signals) и параметрам (params)
изменяться через стандартные HTML-инпуты без ручного написания
обработчиков событий, обеспечивая декларативную модель
интерактивности.
В Vega интерактивность строится вокруг системы сигналов. Сигнал представляет собой реактивную переменную, значение которой может изменяться в ответ на внешние события или пользовательский ввод.
Базовая структура сигнала:
{
"signals": [
{
"name": "threshold",
"value": 10
}
]
}
Сигнал сам по себе не связан с DOM. Связь появляется через поле
bind, которое описывает источник значения.
Поле bind определяет, каким образом сигнал отображается
в пользовательском интерфейсе и каким HTML-элементом управляется его
значение. Это декларативная замена ручной работы с
addEventListener.
Обобщённая структура:
{
"signals": [
{
"name": "threshold",
"value": 10,
"bind": {
"input": "range",
"min": 0,
"max": 100,
"step": 1
}
}
]
}
В момент рендеринга Vega создаёт соответствующий DOM-элемент и синхронизирует его значение с сигналом.
Используется для строковых значений или чисел в свободном вводе.
{
"name": "label",
"value": "A",
"bind": {
"input": "text"
}
}
Особенности:
Один из наиболее распространённых типов управления числовыми параметрами.
{
"name": "opacity",
"value": 0.5,
"bind": {
"input": "range",
"min": 0,
"max": 1,
"step": 0.01
}
}
Семантика:
Используется для выбора из конечного множества значений.
{
"name": "colorScheme",
"value": "category10",
"bind": {
"input": "select",
"options": ["category10", "set1", "accent"]
}
}
Свойства:
Булевы переключатели для бинарных состояний.
{
"name": "showPoints",
"value": true,
"bind": {
"input": "checkbox"
}
}
Используется для:
Связывание bind реализует двунаправленную модель:
Изменение сигнала программно также обновляет UI:
{
"signals": [
{
"name": "zoom",
"value": 1,
"bind": {
"input": "range",
"min": 1,
"max": 10
}
}
]
}
Если zoom обновляется через трансформации или другие
сигналы, ползунок синхронизируется автоматически.
Наиболее частый сценарий применения bind — интерактивная
фильтрация данных.
{
"signals": [
{
"name": "minValue",
"value": 0,
"bind": {
"input": "range",
"min": 0,
"max": 100
}
}
],
"data": [
{
"name": "table",
"transform": [
{
"type": "filter",
"expr": "datum.value >= minValue"
}
]
}
]
}
Механизм работы:
minValueВ Vega-Lite концепция bind реализуется через
params. Vega-Lite абстрагирует сигналы, но сохраняет ту же
модель реактивности.
Пример:
{
"params": [
{
"name": "cutoff",
"value": 50,
"bind": {
"input": "range",
"min": 0,
"max": 100
}
}
],
"transform": [
{
"filter": "datum.x > cutoff"
}
]
}
Отличие от Vega:
bind интегрирован в уровень параметровДля select возможно вычисление списка значений через
данные:
{
"name": "category",
"value": "A",
"bind": {
"input": "select",
"options": {"signal": "data('table').map(d => d.type)"}
}
}
Это связывает DOM не только с сигналами, но и с вычисляемыми данными.
Несколько bind могут управляться одновременно, формируя
связанную систему параметров:
{
"signals": [
{
"name": "xMin",
"value": 0,
"bind": {"input": "range", "min": 0, "max": 50}
},
{
"name": "xMax",
"value": 100,
"bind": {"input": "range", "min": 50, "max": 200}
}
]
}
Такая конфигурация часто используется для управления диапазонами осей.
Механизм привязки имеет ряд структурных ограничений:
Несмотря на это, декларативность обеспечивает воспроизводимость и переносимость визуализаций.
Сигналы, управляемые через bind, могут использоваться в
выражениях Vega Expression Language:
{
"signals": [
{
"name": "scale",
"value": 1,
"bind": {"input": "range", "min": 0.5, "max": 5}
},
{
"name": "computedSize",
"update": "scale * 20"
}
]
}
Здесь:
scale управляется DOMcomputedSize зависит от scalebind выступает мостом между декларативной графической
моделью и императивной пользовательской средой браузера. В рамках Vega
он интегрирует систему сигналов с DOM без нарушения принципа
декларативности спецификации.
Ключевая роль: