Программный доступ к View API в Vega основан на объекте
View, который представляет активный экземпляр визуализации,
связывающий декларативную спецификацию с системой рендеринга, обработкой
событий и состоянием данных. Именно через View
осуществляется императивное управление диаграммой после её создания,
включая обновление данных, сигналов, повторный рендеринг и интеграцию с
внешними системами.
View выступает промежуточным слоем между:
После компиляции спецификации создаётся runtime-модель, в которой
View становится точкой управления жизненным циклом
визуализации.
Ключевая особенность заключается в том, что View не
хранит исходную спецификацию в исполняемом виде как «пассивный JSON», а
оперирует компилированным набором операторов данных, сцен-графом и
реактивными зависимостями.
Создание экземпляра View обычно происходит после
компиляции спецификации через vega.parse:
import { parse, View } from "vega";
const spec = {
width: 400,
height: 200,
data: [
{
name: "table",
values: [
{ x: 1, y: 28 },
{ x: 2, y: 55 },
{ x: 3, y: 43 }
]
}
],
marks: [
{
type: "line",
from: { data: "table" },
encode: {
enter: {
x: { scale: "x", field: "x" },
y: { scale: "y", field: "y" }
}
}
}
]
};
const runtime = parse(spec);
const view = new View(runtime)
.renderer("canvas")
.initialize("#vis");
После вызова initialize происходит привязка к DOM-узлу и
подготовка графического контекста.
View проходит несколько стадий:
Метод runAsync() запускает полный цикл вычислений:
view.runAsync();
Асинхронная модель позволяет не блокировать поток выполнения при загрузке внешних источников данных.
Одной из ключевых возможностей является программное управление dataset-ами.
view.change(
"table",
vega.changeset().insert([
{ x: 4, y: 60 },
{ x: 5, y: 20 }
])
).runAsync();
Объект changeset обеспечивает атомарные операции над
потоками данных:
insertremoveupdatetoggleview.change(
"table",
vega.changeset()
.remove(d => d.x === 2)
).runAsync();
Важно, что изменения не применяются мгновенно — они попадают в очередь реактивных обновлений, после чего пересчитываются зависимости сцены.
Сигналы (signals) представляют реактивные переменные внутри Vega runtime.
const value = view.signal("threshold");
view.signal("threshold", 42).runAsync();
Сигналы используются для:
Хотя Vega является реактивной системой, существуют сценарии, требующие явного вызова пересчёта:
view.runAsync();
или синхронного варианта:
view.run();
Синхронный режим используется в контролируемых окружениях, где важна предсказуемость последовательности операций.
View поддерживает подписку на события сцены:
view.addEventListener("click", function (event, item) {
console.log(item.datum);
});
События делятся на:
Каждое событие предоставляет доступ к item, содержащему
ссылку на элемент сцены и связанные данные.
Внутренняя структура сцены (scenegraph) доступна через:
const scene = view.scenegraph().root;
Доступ к сцене позволяет:
Однако прямое манипулирование сценой считается низкоуровневым подходом и может нарушать реактивность.
Изменение размеров визуализации:
view.width(600).height(400).runAsync();
После изменения размеров автоматически пересчитываются:
View поддерживает загрузку внешних данных через data transforms, однако программный API позволяет инициировать повторное вычисление после обновления источников:
view.data("table", newData).runAsync();
При этом все зависимости, связанные с dataset, пересчитываются автоматически.
Режимы рендеринга:
"canvas" — оптимален для больших наборов данных,"svg" — удобен для DOM-интеграции и стилизации.const view = new View(runtime).renderer("svg");
Оптимизация достигается за счёт:
Корректное завершение работы View:
view.finalize();
Операция освобождает:
Игнорирование финализации приводит к утечкам памяти при длительной работе приложений.
View часто интегрируется в современные фронтенд-стековые решения:
useEffect и ref контейнер),Общий принцип — создание и управление жизненным циклом View вне декларативного DOM-рендеринга, с последующей синхронизацией состояния.
Метод runAsync() опирается на внутреннюю очередь задач
Vega runtime:
Такая модель позволяет поддерживать интерактивность даже при сложных визуализациях с множеством зависимостей.
View всегда создаётся на основе результата parse():
import { parse, View } from "vega";
const runtime = parse(spec);
const view = new View(runtime);
На этапе компиляции:
View лишь исполняет уже построенный граф вычислений.
Хотя Vega ориентирована на декларативный подход, View API позволяет частично модифицировать поведение без пересборки всей спецификации:
При более глубокой модификации требуется повторный
parse() и пересоздание View.
View предоставляет инструменты диагностики:
console.log(view.toSVG());
или доступ к внутренним структурам сцены и данных.
Дополнительно может использоваться инспекция сигналов и dataflow-узлов для анализа вычислительного графа.
В экосистеме Vega-Lite View API скрыт за более высоким уровнем
абстракции, однако при компиляции Vega-Lite-спецификаций результатом
также является runtime-модель Vega, в которой View играет
центральную роль исполнения и управления визуализацией.