Канал detail: дополнительная группировка без кодирования

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

В системе декларативной визуализации Vega-Lite данные часто группируются автоматически на основе каналов кодирования, таких как x, y, color, shape, size. Эти каналы не только определяют внешний вид графика, но и влияют на то, как выполняется агрегация данных.

Канал detail выполняет иную функцию:

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

Таким образом, detail можно рассматривать как механизм «скрытого разбиения» данных.


Логика группировки в Vega-Lite

При построении визуализаций Vega-Lite формирует группы данных, которые определяют, как вычисляются агрегаты (например, mean, sum, count). Любой канал, участвующий в кодировании, становится частью ключа группировки.

Если требуется сохранить визуально единый стиль, но при этом разделить данные внутри вычислений, используется detail.

Ключевая особенность:

  • данные разбиваются на подгруппы;
  • визуально остаются одинаковыми.

Отличие detail от color и других каналов

Канал Влияет на внешний вид Участвует в группировке Назначение
color да да различение категорий
shape да да визуальная дифференциация
size да да масштабирование
detail нет да скрытая группировка

Канал detail особенно важен в ситуациях, когда визуальное кодирование уже занято, но требуется сохранить разбиение данных.


Базовый синтаксис использования

В Vega-Lite detail задаётся в блоке encoding как массив полей.

{
  "data": {"url": "data.csv"},
  "mark": "circle",
  "encoding": {
    "x": {"field": "value", "type": "quantitative"},
    "y": {"field": "category", "type": "nominal"},
    "detail": [{"field": "id", "type": "nominal"}]
  }
}

В этом примере:

  • точки размещаются по x и y;
  • каждая точка визуально идентична;
  • но каждая группа id обрабатывается отдельно.

Сценарии применения

Разделение точек внутри одной категории

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

{
  "mark": "circle",
  "encoding": {
    "x": {"field": "time", "type": "temporal"},
    "y": {"field": "value", "type": "quantitative"},
    "detail": [{"field": "sensor_id"}]
  }
}

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


Сохранение точности агрегации

При использовании агрегатов detail предотвращает «слияние» строк:

{
  "mark": "bar",
  "encoding": {
    "x": {"field": "category", "type": "nominal"},
    "y": {"aggregate": "sum", "field": "amount"},
    "detail": [{"field": "transaction_id"}]
  }
}

Без detail возможна потеря гранулярности, если данные требуют более тонкой группировки.


Многомерная структура данных

detail позволяет добавлять дополнительные измерения, не перегружая визуальные каналы:

{
  "mark": "line",
  "encoding": {
    "x": {"field": "date", "type": "temporal"},
    "y": {"field": "value", "type": "quantitative"},
    "detail": [{"field": "series"}, {"field": "region"}]
  }
}

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


Поведение при агрегации

При наличии агрегирующих функций Vega-Lite формирует группы по всем полям, участвующим в кодировании и в detail.

Пример:

  • x = category
  • y = sum(value)
  • detail = id

Результат:

  • агрегирование происходит отдельно для каждого id;
  • затем значения визуально отображаются в рамках одной оси category.

Взаимодействие с transform

Канал detail часто используется совместно с трансформациями:

  • aggregate
  • stack
  • window
  • filter

Особенно важно его использование при aggregate, когда требуется сохранить исходную детализацию.


Различие между detail и groupby в transform

Хотя концептуально detail похож на groupby, различие заключается в уровне применения:

  • groupby в transform формирует новые данные;
  • detail влияет только на этап визуального кодирования.

Пример transform:

{
  "transform": [
    {
      "aggregate": [{"op": "sum", "field": "value", "as": "total"}],
      "groupby": ["category", "id"]
    }
  ]
}

Эквивалент через detail:

{
  "encoding": {
    "x": {"field": "category"},
    "y": {"aggregate": "sum", "field": "value"},
    "detail": [{"field": "id"}]
  }
}

Особенности поведения в слоях (layer)

В многослойных графиках detail работает локально в пределах слоя:

  • каждый слой имеет собственные группы;
  • detail не переносится между слоями;
  • пересечение слоёв не влияет на группировку.

Использование с интерактивностью

В интерактивных визуализациях detail часто используется для:

  • точного выбора элемента;
  • различения объектов при selection;
  • хранения идентификаторов без визуального выделения.

Пример:

{
  "selection": {
    "hover": {
      "type": "single",
      "on": "mouseover",
      "fields": ["id"]
    }
  },
  "mark": "circle",
  "encoding": {
    "x": {"field": "x"},
    "y": {"field": "y"},
    "detail": [{"field": "id"}]
  }
}

Ограничения канала detail

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

Практическая роль в архитектуре Vega-Lite

Канал detail выполняет функцию связующего слоя между:

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

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