Поле react в декларативных спецификациях Vega и
Vega-Lite используется как механизм описания условной реактивности:
изменения одних данных, параметров или сигналов автоматически
пересчитывают связанные визуальные элементы без ручного управления
состоянием. В отличие от императивных подходов, где разработчик явно
вызывает обновление графика, здесь система строит граф зависимостей и
выполняет пересчёт только затронутых узлов.
В основе лежит принцип направленного графа зависимостей. Каждый элемент спецификации — масштаб, фильтр, слой, канал кодирования — может быть зависим от входных данных или пользовательских параметров.
Поле react описывает:
Реактивность в Vega-Lite работает на двух уровнях:
Типовая форма описания реактивного поведения:
{
data: { ... },
mark: "bar",
encoding: {
x: { field: "category", type: "nominal" },
y: { field: "value", type: "quantitative" }
},
react: {
trigger: ["selection", "parameter", "dataChange"],
conditions: [
{
when: "selection.active == true",
apply: {
encoding: {
color: { value: "orange" },
opacity: { value: 1 }
}
}
}
],
otherwise: {
encoding: {
color: { value: "steelblue" },
opacity: { value: 0.7 }
}
}
}
}
Ключевые элементы:
Условная логика в react строится на выражениях,
аналогичных Vega expression language. Чаще всего используются:
Пример с числовым условием:
react: {
trigger: ["parameter"],
conditions: [
{
when: "datum.value > threshold",
apply: {
encoding: {
color: { value: "red" }
}
}
}
]
}
Здесь threshold — реактивный параметр, изменение
которого автоматически приводит к пересчёту цветового кодирования.
Одним из наиболее частых сценариев является реакция на пользовательские выделения.
selection: {
brush: {
type: "interval"
}
},
react: {
trigger: ["selection"],
conditions: [
{
when: "brush",
apply: {
encoding: {
opacity: { value: 1 }
}
}
}
],
otherwise: {
encoding: {
opacity: { value: 0.2 }
}
}
}
Механизм работает следующим образом:
Поле react также применяется к динамическим потокам
данных. Это особенно важно в сценариях потоковой визуализации.
react: {
trigger: ["dataChange"],
conditions: [
{
when: "length(data) > 100",
apply: {
transform: [
{ type: "window", sort: "time" }
]
}
}
]
}
Здесь реактивность используется для адаптивного управления объёмом данных: при превышении порога включается оконная трансформация.
При наличии нескольких условий система применяет их в порядке объявления. Конфликтующие изменения разрешаются через правило приоритета:
Если несколько условий одновременно истинны, применяется последнее совпавшее правило, либо происходит объединение свойств при совместимых изменениях.
react может быть вложенным внутри слоёв (layered
charts), что позволяет создавать сложные зависимости между визуальными
компонентами.
layer: [
{
mark: "line",
encoding: {
x: { field: "time" },
y: { field: "value" }
}
},
{
mark: "point",
react: {
trigger: ["selection"],
conditions: [
{
when: "brush",
apply: {
encoding: {
size: { value: 80 }
}
}
}
]
}
}
]
В данном случае реактивность ограничена только точечным слоем, не затрагивая линейный график.
Часто react комбинируется с вычисляемыми
выражениями:
react: {
trigger: ["parameter"],
conditions: [
{
when: "datum.value * scaleFactor > 50",
apply: {
encoding: {
color: { value: "green" }
}
}
}
]
}
Такой подход позволяет переносить часть логики из трансформаций в реактивный слой, сокращая необходимость предварительной агрегации данных.
Параметры выступают основным источником реактивности:
params: [
{
name: "threshold",
value: 10
}
],
react: {
trigger: ["parameter"],
conditions: [
{
when: "datum.value > threshold",
apply: {
encoding: {
opacity: { value: 1 }
}
}
}
]
}
Изменение threshold приводит к немедленной перестройке
визуального слоя без пересоздания графика.
Реактивная модель оптимизирует вычисления через:
Это позволяет поддерживать интерактивность даже при больших наборах данных.
При проектировании спецификаций важно учитывать:
react правила могут приводить к циклическим
обновлениямПоэтому реактивные правила обычно проектируются с минимальным количеством зависимостей и максимально явной логикой условий.
Несколько блоков react могут работать совместно,
формируя слоистую логику поведения:
react: {
trigger: ["selection"],
conditions: [ ... ]
},
react: {
trigger: ["parameter"],
conditions: [ ... ]
}
В таких случаях система объединяет реакции, сохраняя независимость источников триггеров и применяя изменения последовательно в рамках одного цикла обновления.