Поле datum: привязка к конкретному значению

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

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

datum всегда соответствует одной строке исходного или промежуточного набора данных в текущем контексте:

  • в mark encoding — текущая визуальная сущность (точка, прямоугольник, линия);
  • в transform — текущая обрабатываемая запись;
  • в выражениях — текущий объект данных в момент вычисления.

Структура обращения всегда строится через точечную нотацию:

datum.fieldName

или через доступ к вложенным структурам:

datum["nested"]["value"]

Контекст вычисления и область видимости

datum не является глобальной переменной. Его значение определяется исключительно текущим контекстом исполнения:

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

Каждое выражение, использующее datum, выполняется построчно, что позволяет строить декларативные правила без явного цикла.

Привязка к конкретному значению через datum

Привязка к конкретному значению реализуется через прямое сравнение полей datum с константами или вычисляемыми выражениями. Такой подход позволяет фиксировать условия на уровне отдельных записей данных.

Простейшая форма сравнения

datum.value > 10

Здесь значение поля value каждой записи сравнивается с фиксированным числом.

Привязка к строковому значению

datum.category == "A"

Такая конструкция фиксирует визуальную или вычислительную логику на конкретной категории данных.

Составные условия

datum.value > 10 && datum.category == "A"

Логические операторы позволяют формировать сложные ограничения на уровне одной записи.

Использование в фильтрации данных

Фильтрация является одним из основных сценариев применения datum. В Vega-Lite это реализуется через трансформацию filter.

Пример фильтрации по числовому значению

{
  "data": {"values": [
    {"x": 1, "y": 5},
    {"x": 2, "y": 15},
    {"x": 3, "y": 8}
  ]},
  "transform": [
    {
      "filter": "datum.y > 10"
    }
  ],
  "mark": "point",
  "encoding": {
    "x": {"field": "x", "type": "quantitative"},
    "y": {"field": "y", "type": "quantitative"}
  }
}

Фильтр применяет выражение к каждой записи, исключая те, для которых условие ложно.

Комбинированная фильтрация

filter: "datum.y > 10 && datum.x < 5"

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

Вычисление новых значений через datum

В трансформации calculate datum используется для построения производных полей.

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

{
  "transform": [
    {
      "calculate": "datum.x + datum.y",
      "as": "sum"
    }
  ]
}

Каждая запись получает новое поле sum, вычисленное на основе исходных значений текущего datum.

Работа с вложенными структурами

datum.metrics.sales / datum.metrics.count

Подобный доступ применяется для сложных JSON-структур, где данные имеют иерархическую организацию.

Условная логика в encoding

datum широко используется для условного форматирования визуальных элементов.

Условный цвет

{
  "mark": "circle",
  "encoding": {
    "x": {"field": "x", "type": "quantitative"},
    "y": {"field": "y", "type": "quantitative"},
    "color": {
      "condition": {
        "test": "datum.y > 10",
        "value": "red"
      },
      "value": "blue"
    }
  }
}

Каждый визуальный элемент получает цвет в зависимости от значения конкретной записи.

Условные размеры

size: {
  "condition": "datum.value > 100",
  "value": 200,
  "else": 50
}

Логика привязана к текущему datum, что позволяет дифференцировать элементы без агрегации.

Использование в выражениях Vega

В чистом Vega datum применяется в expressions более гибко, чем в Vega-Lite.

Пример выражения в signal или calculate

"expr": "datum.a * datum.b"

или в transform:

{
  "type": "formula",
  "as": "product",
  "expr": "datum.a * datum.b"
}

Сравнение datum с внешними значениями

Хотя datum относится к текущей записи данных, он часто сравнивается с внешними параметрами или сигналами.

Пример сравнения с константой

datum.value > 50

Сравнение с параметром (Vega-Lite)

{
  "params": [
    {"name": "threshold", "value": 10}
  ],
  "transform": [
    {
      "filter": "datum.y > threshold"
    }
  ]
}

В этом случае datum сохраняет локальный контекст, а threshold выступает внешним управляющим значением.

Обработка отсутствующих и вложенных значений

При работе с реальными наборами данных часто встречаются отсутствующие поля.

Проверка на null

datum.value != null

Безопасный доступ к вложенным данным

datum.a && datum.a.b

или

datum["a"] && datum["a"]["b"]

Такие конструкции предотвращают ошибки при обращении к отсутствующим структурам.

Привязка визуальных элементов к конкретной записи

Каждый mark в Vega фактически привязан к одному datum. Это обеспечивает прямое соответствие между данными и графическим представлением.

Пример scatter plot

{
  "mark": "circle",
  "encoding": {
    "x": {"field": "x", "type": "quantitative"},
    "y": {"field": "y", "type": "quantitative"},
    "color": {
      "condition": "datum.y > 0",
      "value": "green"
    }
  }
}

Каждая точка интерпретируется как независимый datum, а визуальные свойства вычисляются локально.

Поведение datum в агрегациях

После применения агрегирующих трансформаций datum начинает представлять уже агрегированную запись.

Пример:

{
  "aggregate": [
    {"op": "mean", "field": "value", "as": "avg"}
  ],
  "groupby": ["category"]
}

После такой операции:

  • datum.category — группа;
  • datum.avg — агрегированное значение.

Особенности семантики привязки

Привязка через datum всегда локальна и детерминирована текущей записью:

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

Такой подход обеспечивает воспроизводимость визуализаций и предсказуемость вычислений в pipeline обработки данных.