Поле data в Vega: источники и трансформации

Структура поля data в Vega

Поле data в спецификации Vega определяет наборы данных, используемые для построения визуализаций. Оно может содержать один или несколько источников, каждый из которых описывает способ загрузки, преобразования и подготовки данных перед отрисовкой графика.

Базовая структура:

{
  "data": [
    {
      "name": "table",
      "values": [],
      "url": "",
      "format": {},
      "transform": []
    }
  ]
}

Ключевыми компонентами являются:

  • name — идентификатор набора данных внутри спецификации
  • values — встроенные данные (inline)
  • url — внешний источник данных
  • format — описание формата входных данных
  • transform — цепочка преобразований

Источники данных

Встроенные данные (values)

Поле values используется для небольших датасетов, когда данные передаются напрямую в спецификацию.

{
  "name": "points",
  "values": [
    { "x": 1, "y": 10 },
    { "x": 2, "y": 20 }
  ]
}

Особенности:

  • данные хранятся внутри JSON-спецификации
  • отсутствуют сетевые запросы
  • оптимально для прототипирования и учебных примеров
  • ограничено по объёму (практически — десятки/сотни записей)

Внешние источники (url)

Поле url позволяет загружать данные из внешних файлов или API.

{
  "name": "sales",
  "url": "data/sales.csv"
}

Поддерживаются:

  • CSV
  • TSV
  • JSON
  • TopoJSON
  • GeoJSON

Загрузка может происходить:

  • по HTTP/HTTPS
  • локально (в рамках окружения)
  • через API-эндпоинты

Форматирование входных данных (format)

Поле format описывает, как интерпретировать входные данные.

CSV и TSV

{
  "format": {
    "type": "csv"
  }
}

Дополнительно:

  • delimiter — кастомный разделитель
  • parse — типизация полей
{
  "format": {
    "type": "csv",
    "parse": {
      "date": "date",
      "value": "number"
    }
  }
}

JSON

{
  "format": {
    "type": "json",
    "property": "data"
  }
}

property позволяет извлечь вложенный массив из JSON-структуры.


Именование наборов данных

Поле name создаёт идентификатор таблицы данных внутри Vega. Он используется для:

  • ссылок в transform
  • соединения данных
  • вычислений
  • масштабирования и сигналов

Пример:

{
  "name": "source",
  "values": [ ... ]
}

Позже этот набор можно использовать как входной:

{
  "transform": [
    { "type": "filter", "expr": "datum.value > 10" }
  ]
}

Трансформации данных (transform)

transform — центральный механизм подготовки данных. Vega выполняет их последовательно, формируя pipeline обработки.

Фильтрация (filter)

Удаляет записи, не удовлетворяющие условию.

{
  "type": "filter",
  "expr": "datum.value > 100"
}

Особенности:

  • используется выражения Vega Expression Language
  • работает на уровне каждой строки
  • не изменяет структуру данных

Вычисляемые поля (calculate)

Добавляет новые поля на основе выражений.

{
  "type": "calculate",
  "as": "total",
  "expr": "datum.price * datum.quantity"
}

Характеристики:

  • создаёт новые атрибуты
  • поддерживает математические операции, строки, условия
  • аналог map-функции

Агрегация (aggregate)

Группирует данные и вычисляет статистики.

{
  "type": "aggregate",
  "groupby": ["category"],
  "fields": ["value"],
  "ops": ["sum"],
  "as": ["total"]
}

Возможные операции:

  • sum
  • mean
  • median
  • min
  • max
  • count

Бининг (bin)

Используется для гистограмм и разбиения числовых данных.

{
  "type": "bin",
  "field": "value",
  "as": "binnedValue"
}

Результат:

  • создаёт интервалы
  • добавляет bin_start и bin_end
  • используется для histogram charts

Сортировка (sort)

Упорядочивает данные.

{
  "type": "sort",
  "fields": ["value"],
  "order": "ascending"
}

Особенности:

  • поддерживает многополевую сортировку
  • используется перед визуализацией шкал

Скользящие вычисления (window)

Позволяет выполнять оконные функции.

{
  "type": "window",
  "ops": ["rank", "sum"],
  "fields": ["value"],
  "as": ["rank", "runningTotal"]
}

Поддерживаемые операции:

  • rank
  • dense_rank
  • row_number
  • lag / lead
  • running sum/mean

Расширение строк (fold)

Преобразует широкую таблицу в длинную.

{
  "type": "fold",
  "fields": ["a", "b", "c"],
  "as": ["key", "value"]
}

Используется для:

  • мультисерийных графиков
  • нормализации структуры данных

Обратная операция (pivot)

Преобразует длинную таблицу в широкую.

{
  "type": "pivot",
  "field": "key",
  "value": "value"
}

Особенности:

  • агрегирует данные при конфликте ключей
  • полезно для таблиц и матриц

Присоединение данных (lookup)

Позволяет выполнять join с внешними источниками.

{
  "type": "lookup",
  "from": "table2",
  "key": "id",
  "fields": ["id"],
  "as": ["joinedData"]
}

Механизм:

  • аналог left join
  • расширяет текущий датасет
  • часто используется для справочников

Каскадная агрегация (joinaggregate)

Добавляет агрегированные значения без уменьшения строк.

{
  "type": "joinaggregate",
  "ops": ["mean"],
  "fields": ["value"],
  "as": ["avgValue"]
}

Особенность:

  • сохраняет исходную структуру
  • добавляет статистические поля ко всем строкам

Временные преобразования (timeunit)

Группировка по временным интервалам.

{
  "type": "timeunit",
  "field": "date",
  "units": ["year", "month"]
}

Используется для:

  • временных рядов
  • календарной агрегации
  • дашбордов

Комбинирование трансформаций

Трансформации выполняются последовательно, формируя цепочку обработки.

Пример сложного pipeline:

{
  "data": [
    {
      "name": "sales",
      "url": "sales.csv",
      "format": { "type": "csv" },
      "transform": [
        { "type": "filter", "expr": "datum.amount > 0" },
        { "type": "calculate", "as": "profit", "expr": "datum.revenue - datum.cost" },
        {
          "type": "aggregate",
          "groupby": ["region"],
          "fields": ["profit"],
          "ops": ["sum"],
          "as": ["totalProfit"]
        }
      ]
    }
  ]
}

Логика выполнения:

  1. загрузка CSV
  2. фильтрация строк
  3. вычисление нового поля
  4. агрегация по регионам

Несколько наборов данных в одной спецификации

Vega позволяет использовать несколько источников одновременно:

{
  "data": [
    { "name": "a", "values": [...] },
    { "name": "b", "url": "data.json" }
  ]
}

Это необходимо для:

  • overlay-графиков
  • сравнительных визуализаций
  • lookup-операций
  • сложных dashboard-сценариев

Взаимодействие data с сигналами и масштабами

Данные в Vega тесно связаны с другими частями спецификации:

  • scales используют поля из data
  • signals могут влиять на transform
  • marks визуализируют результат обработки
  • axes привязаны к обработанным данным

Пример зависимости:

  • data → фильтрация → агрегация
  • результат → scale domain
  • scale → axis rendering

Производительность трансформаций

При проектировании сложных визуализаций важно учитывать:

  • aggregate дешевле, чем window на больших данных
  • lookup может быть узким местом при больших join-таблицах
  • calculate масштабируется линейно
  • filter лучше выполнять как можно раньше в цепочке

Оптимизационная практика:

  • ранняя фильтрация
  • минимизация числа полей
  • избегание избыточных transform-цепочек
  • предварительная агрегация на сервере при больших объемах

Отличия подхода Vega и Vega-Lite

В Vega-Lite поле data упрощено:

{
  "data": {
    "url": "data.csv"
  }
}

Основные различия:

  • Vega: массив источников + сложные transform pipeline
  • Vega-Lite: декларативное описание одного источника
  • Vega: контроль низкого уровня
  • Vega-Lite: автоматическая генерация трансформаций

Vega используется там, где требуется:

  • кастомная обработка данных
  • сложные join и window операции
  • многослойные визуализации с независимыми источниками