Группа (group): контейнер марок

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

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


Базовая структура group в Vega

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

{
  "type": "group",
  "marks": [
    {
      "type": "rect",
      "encode": {
        "enter": {
          "x": {"value": 0},
          "y": {"value": 0},
          "width": {"value": 200},
          "height": {"value": 100},
          "fill": {"value": "#eee"}
        }
      }
    }
  ]
}

Группа в данном случае выступает как контейнер, внутри которого прямоугольник интерпретируется в локальных координатах.


Локальная система координат группы

Каждая группа в Vega формирует собственную систему координат, которая наследуется дочерними элементами. Это означает, что:

  • координата (0, 0) внутри группы — это верхний левый угол группы;
  • трансформации группы (translate, scale, rotate) применяются ко всему содержимому;
  • вложенные группы создают каскадные системы координат.

Пример с трансформацией:

{
  "type": "group",
  "encode": {
    "enter": {
      "x": {"value": 100},
      "y": {"value": 50}
    }
  },
  "marks": [
    {
      "type": "text",
      "encode": {
        "enter": {
          "x": {"value": 0},
          "y": {"value": 0},
          "text": {"value": "Локальная система координат"}
        }
      }
    }
  ]
}

Здесь текст отображается не в глобальной точке (0,0) сцены, а в локальной точке группы, которая смещена на (100, 50).


encode группы: визуальное оформление контейнера

Группа может иметь собственные визуальные свойства через encode, что позволяет рассматривать её как полноценный графический объект.

Основные наборы каналов:

  • enter — начальные параметры
  • update — динамические изменения
  • exit — удаление

Пример стилизованной группы:

{
  "type": "group",
  "encode": {
    "enter": {
      "fill": {"value": "#f9f9f9"},
      "stroke": {"value": "#333"},
      "strokeWidth": {"value": 1},
      "cornerRadius": {"value": 6}
    }
  },
  "marks": [
    {
      "type": "symbol",
      "encode": {
        "enter": {
          "x": {"value": 20},
          "y": {"value": 20},
          "size": {"value": 100},
          "fill": {"value": "steelblue"}
        }
      }
    }
  ]
}

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


вложенные группы и иерархия сцены

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

{
  "type": "group",
  "encode": {
    "enter": {
      "x": {"value": 50},
      "y": {"value": 50}
    }
  },
  "marks": [
    {
      "type": "group",
      "encode": {
        "enter": {
          "x": {"value": 0},
          "y": {"value": 0}
        }
      },
      "marks": [
        {
          "type": "rect",
          "encode": {
            "enter": {
              "width": {"value": 120},
              "height": {"value": 60},
              "fill": {"value": "tomato"}
            }
          }
        }
      ]
    }
  ]
}

Иерархия позволяет:

  • структурировать сложные визуализации;
  • переиспользовать компоненты;
  • изолировать локальные трансформации.

group как контейнер для данных и scales

Группа может иметь собственные data, scales, axes, что делает её полноценным независимым визуальным блоком.

Локальные данные внутри группы

{
  "type": "group",
  "data": [
    {
      "name": "localData",
      "values": [
        {"x": 1, "y": 10},
        {"x": 2, "y": 20}
      ]
    }
  ],
  "marks": [
    {
      "type": "symbol",
      "from": {"data": "localData"},
      "encode": {
        "enter": {
          "x": {"scale": "xscale", "field": "x"},
          "y": {"scale": "yscale", "field": "y"},
          "size": {"value": 80}
        }
      }
    }
  ]
}

Локализация данных позволяет создавать независимые визуальные подграфики внутри одного spec.


scales и axes внутри group

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

{
  "type": "group",
  "scales": [
    {
      "name": "xscale",
      "type": "linear",
      "domain": {"data": "localData", "field": "x"},
      "range": "width"
    }
  ],
  "axes": [
    {
      "scale": "xscale",
      "orient": "bottom"
    }
  ],
  "marks": [
    {
      "type": "symbol",
      "encode": {
        "enter": {
          "x": {"scale": "xscale", "value": 10},
          "y": {"value": 20}
        }
      }
    }
  ]
}

Такой подход позволяет строить независимые мини-графики внутри одного полотна.


Vega-Lite и group: абстракция через facet

В Vega-Lite прямое использование group скрыто от пользователя, но концептуально реализуется через:

  • facet
  • concat
  • repeat

facet как декларативная группа

{
  "data": {"url": "data.csv"},
  "facet": {
    "row": {"field": "category", "type": "nominal"}
  },
  "spec": {
    "mark": "bar",
    "encoding": {
      "x": {"field": "x", "type": "quantitative"},
      "y": {"field": "y", "type": "quantitative"}
    }
  }
}

Каждая ячейка facet — это фактически скрытая group, обладающая собственной системой координат и масштабами.


group и композиция визуализаций

Группы активно применяются для композиции нескольких типов графиков в одном полотне:

  • комбинирование диаграмм;
  • создание панелей (dashboard layout);
  • связывание интерактивных элементов.

Пример комбинированного блока:

{
  "type": "group",
  "encode": {
    "enter": {
      "width": {"value": 400},
      "height": {"value": 300}
    }
  },
  "marks": [
    {
      "type": "rect",
      "encode": {
        "enter": {
          "width": {"value": 400},
          "height": {"value": 300},
          "fill": {"value": "#fafafa"}
        }
      }
    },
    {
      "type": "symbol",
      "encode": {
        "enter": {
          "x": {"value": 100},
          "y": {"value": 100},
          "size": {"value": 200},
          "fill": {"value": "steelblue"}
        }
      }
    }
  ]
}

сигналы внутри group

Группа может инкапсулировать signals, создавая локальную интерактивность.

{
  "type": "group",
  "signals": [
    {
      "name": "hover",
      "value": false,
      "on": [
        {"events": "rect:mouseover", "update": "true"},
        {"events": "rect:mouseout", "update": "false"}
      ]
    }
  ],
  "marks": [
    {
      "type": "rect",
      "encode": {
        "enter": {
          "fill": {"value": "lightgray"}
        },
        "update": {
          "fillOpacity": {"signal": "hover ? 0.5 : 1"}
        }
      }
    }
  ]
}

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


типичные паттерны использования group

Панельный макет

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

Вложенные диаграммы

  • основной график + inset zoom;
  • группа как мини-карта.

Аннотационные слои

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

особенности рендеринга и производительности

Группы влияют на рендеринг следующим образом:

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

Оптимизация часто достигается за счёт:

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

роль group в архитектуре Vega

Group выступает базовым строительным блоком всей сцены Vega. Она объединяет:

  • композицию (layout контейнер);
  • изоляцию координат (local transform space);
  • инкапсуляцию данных и масштабов;
  • поддержку интерактивности;
  • иерархическую структуру визуализации.

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