Поле legend

В спецификациях Vega-Lite поле legend относится к механизму управления легендами — визуальными компонентами, которые объясняют соответствие между данными и визуальными переменными (цветом, формой, размером, прозрачностью и другими каналами кодирования).

Легенда в контексте Vega и Vega-Lite не является автономным элементом, а всегда привязана к конкретному encoding channel. Это означает, что легенда автоматически выводится на основе используемого кодирования данных, но может быть полностью переопределена через конфигурацию legend.


Роль legend в системе encoding

В Vega-Lite визуальные каналы (color, shape, size, opacity, strokeDash и др.) могут быть связаны с полями данных. Когда канал является дискретным или непрерывным, система автоматически определяет необходимость легенды.

Пример базового связывания:

{
  "mark": "point",
  "encoding": {
    "x": { "field": "x", "type": "quantitative" },
    "y": { "field": "y", "type": "quantitative" },
    "color": { "field": "category", "type": "nominal" }
  }
}

В этом случае color создаёт легенду автоматически, поскольку категориальная переменная требует отображения соответствий.


Основная структура legend

Поле legend может задаваться внутри encoding или через глобальные настройки config.legend.

Формат:

"color": {
  "field": "category",
  "type": "nominal",
  "legend": {
    "title": "Категории",
    "orient": "right"
  }
}

Ключевые свойства:

  • title — заголовок легенды
  • orient — расположение
  • format — форматирование значений
  • values — фиксированный список значений
  • direction — направление элементов
  • symbolType — форма маркеров
  • labelFont, labelFontSize — стилизация текста

Автоматическая генерация legend

При отсутствии явного определения Vega-Lite анализирует тип данных:

  • nominal → категориальная легенда
  • ordinal → упорядоченная шкала
  • quantitative → цветовая шкала (gradient legend)
  • temporal → временная шкала с форматированием дат

Например:

"color": {
  "field": "value",
  "type": "quantitative"
}

Приводит к созданию градиентной легенды (color ramp), а не дискретного списка.


Позиционирование legend (orient)

Свойство orient управляет размещением легенды:

  • "right" — справа (дефолт)
  • "left" — слева
  • "top" — сверху
  • "bottom" — снизу
  • "none" — отключение отображения

Пример:

"legend": {
  "orient": "bottom"
}

Размещение влияет на layout всей визуализации, особенно при множественных легендах.


Управление отображаемыми значениями (values)

Свойство values позволяет ограничить набор отображаемых категорий:

"legend": {
  "values": ["A", "B", "C"]
}

Это особенно важно при:

  • фильтрации визуального интерфейса
  • упрощении сложных категориальных наборов
  • синхронизации с внешними UI-фильтрами

Форматирование текста legend

Свойство format применяется к значениям шкалы:

"legend": {
  "format": ".2f"
}

Поддерживаются d3-format спецификации. Для временных данных применяется d3-time-format.

Пример для даты:

"legend": {
  "format": "%Y-%m"
}

Стилизация символов legend

Для дискретных легенд (например, color + nominal) можно управлять внешним видом маркеров:

"legend": {
  "symbolType": "square",
  "symbolSize": 100
}

Возможные значения symbolType:

  • circle
  • square
  • triangle
  • diamond
  • stroke

legend для шкал непрерывных данных

Для количественных переменных легенда превращается в цветовую шкалу (gradient legend).

Пример:

"color": {
  "field": "temperature",
  "type": "quantitative",
  "legend": {
    "title": "Температура"
  }
}

Здесь легенда отображает:

  • градиент значений
  • подписи min/max
  • промежуточные деления (ticks)

Скрытие legend

Легенда отключается явно:

"legend": null

или

"legend": false

Это применяется при:

  • перегруженных визуализациях
  • кастомных UI-элементах фильтрации
  • встроенных интерактивных панелях

config.legend (глобальные настройки)

В Vega-Lite возможно централизованное управление легендами:

"config": {
  "legend": {
    "labelFontSize": 12,
    "titleFontSize": 14,
    "padding": 10
  }
}

Эти параметры применяются ко всем легендам, если не переопределены локально.


Множественные legend в одной визуализации

Если используются несколько encoding-каналов, возможно появление нескольких легенд:

"encoding": {
  "color": { "field": "A", "type": "nominal" },
  "shape": { "field": "B", "type": "nominal" },
  "size": { "field": "C", "type": "quantitative" }
}

Результат:

  • отдельная легенда для color
  • отдельная для shape
  • цветовая шкала для size

Управление каждой осуществляется независимо.


Поведение legend при трансформациях данных

При использовании transform-операций (filter, aggregate, calculate) легенда может:

  • автоматически пересчитываться
  • исключать отсутствующие значения
  • менять диапазон шкалы

Особенно это заметно при aggregate:

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

Легенда отражает уже агрегированные данные.


Связь legend и scale

Легенда напрямую зависит от scale:

  • scale определяет отображение данных
  • legend интерпретирует результат этого отображения

Пример:

"color": {
  "field": "score",
  "type": "quantitative",
  "scale": { "scheme": "blues" },
  "legend": { "title": "Оценка" }
}

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


Особенности поведения в Vega vs Vega-Lite

В Vega legend задаётся более низкоуровнево через legends в scales, где требуется явное управление доменами и диапазонами.

В отличие от этого, Vega-Lite:

  • автоматически генерирует легенды
  • упрощает конфигурацию
  • скрывает низкоуровневые детали scale binding

Практическая структура legend-конфигурации

Типовая полная конфигурация:

"color": {
  "field": "group",
  "type": "nominal",
  "legend": {
    "title": "Группа данных",
    "orient": "right",
    "symbolType": "circle",
    "labelFontSize": 12,
    "titleFontSize": 14,
    "values": ["A", "B", "C"]
  }
}

Эта структура управляет:

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

Поведение legend при взаимодействии

В интерактивных спецификациях legend может участвовать в событиях:

  • highlight
  • filter
  • selection binding

Пример:

"selection": {
  "sel": { "type": "multi", "fields": ["category"] }
}

При связывании с легендой элементы становятся интерактивными фильтрами.


Ограничения и особенности реализации

  • legend не создаётся для непривязанных каналов
  • количественные шкалы могут объединять деления
  • слишком длинные списки категорий автоматически сокращаются
  • некоторые стили могут игнорироваться при компактных layout

Итоговая модель поведения legend

Поведение legend можно интерпретировать как результат взаимодействия трёх уровней:

  • данные (data domain)
  • масштабирование (scale mapping)
  • визуальное представление (legend rendering)

В Vega-Lite этот процесс максимально автоматизирован, но при этом остаётся полностью управляемым через декларативную конфигурацию legend.