Описание данных: поле data

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

Базовая концепция данных

В спецификациях Vega-Lite данные задаются как объект или массив объектов, каждый из которых описывает отдельный набор данных. Каждый набор данных может быть:

  • встроенным (inline)
  • загружаемым из внешнего источника
  • производным (через трансформации)
  • именованным (для повторного использования)

Vega использует более низкоуровневую модель, где данные обычно определяются через массив data, содержащий объекты с именами наборов, источниками и преобразованиями.

Inline-данные: values

Наиболее прямой способ описания данных — использование поля values. Оно содержит массив объектов или примитивов, которые интерпретируются как строки данных.

Пример структуры

{
  "data": {
    "values": [
      { "category": "A", "value": 28 },
      { "category": "B", "value": 55 },
      { "category": "C", "value": 43 }
    ]
  }
}

В этом случае данные полностью встроены в спецификацию. Такой подход применяется для:

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

Особенность values заключается в том, что Vega-Lite немедленно интерпретирует массив как таблицу, где каждый объект — это строка, а ключи объекта — поля.

Типы допустимых значений

Поле values может содержать:

  • массив объектов (табличные данные)
  • массив чисел (одномерные данные)
  • массив строк (категориальные списки)

Однако наиболее устойчивый и распространённый формат — массив объектов.

Загрузка внешних данных: url

Поле url используется для загрузки данных из внешнего источника. Vega и Vega-Lite поддерживают различные форматы:

  • JSON
  • CSV
  • TSV
  • TopoJSON
  • XML (через расширения или предварительную обработку)

Пример загрузки CSV

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

При этом Vega автоматически определяет формат, если он явно не указан, либо использует стандартные правила парсинга.

Явное указание формата

{
  "data": {
    "url": "data/sales.csv",
    "format": {
      "type": "csv"
    }
  }
}

Поле format

format определяет способ интерпретации входных данных. Оно критически важно при работе с неоднородными источниками.

Основные типы форматов

  • csv — таблицы с разделителями
  • tsv — табличные данные с табуляцией
  • json — структурированные объекты
  • topojson — географические данные
  • dsv — данные с произвольным разделителем

Пример JSON-формата

{
  "data": {
    "url": "data/items.json",
    "format": {
      "type": "json"
    }
  }
}

В случае JSON Vega ожидает либо массив объектов, либо объект, который затем преобразуется через property:

{
  "data": {
    "url": "data/root.json",
    "format": {
      "type": "json",
      "property": "data.items"
    }
  }
}

Поле property позволяет извлекать вложенные структуры.

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

В Vega-Lite существует механизм datasets, позволяющий определить несколько наборов данных на верхнем уровне и ссылаться на них по имени.

Пример

{
  "datasets": {
    "tableA": [
      { "x": 1, "y": 10 },
      { "x": 2, "y": 20 }
    ],
    "tableB": [
      { "x": 1, "y": 5 },
      { "x": 2, "y": 15 }
    ]
  },
  "data": { "name": "tableA" }
}

Такой подход позволяет:

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

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

Поле name используется в Vega (низкоуровневой спецификации) для идентификации набора данных внутри графа вычислений.

{
  "data": [
    {
      "name": "sourceTable",
      "url": "data.csv"
    }
  ]
}

Идентификатор name позволяет:

  • ссылаться на данные в transform-цепочках
  • использовать результат одного набора как вход другого
  • выполнять сложные последовательности обработки

Трансформации внутри data

Одной из ключевых особенностей Vega является возможность описания преобразований прямо в блоке данных через transform.

Пример фильтрации

{
  "data": {
    "values": [
      { "category": "A", "value": 10 },
      { "category": "B", "value": 20 }
    ],
    "transform": [
      {
        "type": "filter",
        "expr": "datum.value > 15"
      }
    ]
  }
}

Пример вычисления поля

{
  "data": {
    "values": [
      { "a": 2, "b": 3 }
    ],
    "transform": [
      {
        "type": "formula",
        "as": "sum",
        "expr": "datum.a + datum.b"
      }
    ]
  }
}

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

Переименование и структурирование данных

При работе с внешними источниками часто возникает необходимость привести данные к единому формату. Для этого используются:

  • calculate / formula
  • aggregate
  • fold
  • pivot
  • lookup

Пример агрегирования

{
  "data": {
    "url": "sales.csv",
    "transform": [
      {
        "type": "aggregate",
        "groupby": ["region"],
        "fields": ["amount"],
        "ops": ["sum"],
        "as": ["total"]
      }
    ]
  }
}

Здесь данные преобразуются из строк транзакций в агрегированную таблицу.

Множественные источники данных

Vega поддерживает использование нескольких наборов данных в одной визуализации. Это особенно важно для:

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

Пример

{
  "data": [
    {
      "name": "points",
      "url": "points.csv"
    },
    {
      "name": "lines",
      "url": "lines.csv"
    }
  ]
}

Каждый набор данных становится независимой сущностью внутри графа исполнения.

Связывание данных через lookup

Один из мощных механизмов — связывание таблиц по ключу.

{
  "transform": [
    {
      "type": "lookup",
      "from": "tableB",
      "key": "id",
      "fields": ["id"],
      "as": ["joined"]
    }
  ]
}

Так реализуется поведение, аналогичное join в реляционных базах данных.

Обработка геоданных

При работе с картографией используется формат TopoJSON:

{
  "data": {
    "url": "world-110m.json",
    "format": {
      "type": "topojson",
      "feature": "countries"
    }
  }
}

Поле feature указывает, какие геометрические объекты извлекать.

Поток данных и ленивые вычисления

Vega строит граф вычислений, где каждый data-узел может зависеть от других. Это создаёт:

  • ленивую обработку
  • переиспользование результатов
  • минимизацию повторных вычислений

Каждое изменение входных данных приводит к пересборке зависимых узлов.

Сравнение моделей Vega и Vega-Lite

В Vega-Lite поле data более декларативно и упрощено:

  • меньше низкоуровневых деталей
  • автоматическая генерация трансформаций
  • упрощённые структуры values, url, name

В Vega:

  • полный контроль над pipeline
  • явные зависимости
  • расширенные трансформации

Типовые ошибки при работе с data

На практике часто возникают следующие проблемы:

  • несоответствие формата JSON ожидаемой структуре
  • отсутствие поля format при нестандартных CSV
  • неправильные пути в url
  • конфликт имён в datasets
  • попытка использовать трансформации без корректного name

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

Структурная роль data в визуализации

Поле data является точкой входа всей системы визуализации. Оно определяет:

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

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