Горизонтальная конкатенация: hconcat

Базовая идея горизонтального компоновщика

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

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

Структура базового объекта:

{
  "hconcat": [
    { /* первая визуализация */ },
    { /* вторая визуализация */ }
  ]
}

Минимальный пример горизонтальной конкатенации

{
  "data": {
    "values": [
      {"category": "A", "value": 28},
      {"category": "B", "value": 55},
      {"category": "C", "value": 43}
    ]
  },
  "hconcat": [
    {
      "mark": "bar",
      "encoding": {
        "x": {"field": "category", "type": "nominal"},
        "y": {"field": "value", "type": "quantitative"}
      }
    },
    {
      "mark": "line",
      "encoding": {
        "x": {"field": "category", "type": "nominal"},
        "y": {"field": "value", "type": "quantitative"}
      }
    }
  ]
}

В данном случае формируются две независимые визуализации:

  • столбчатая диаграмма
  • линейный график

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


Управление шириной элементов hconcat

Каждый элемент hconcat может иметь собственные параметры размера. Управление шириной осуществляется через свойства width внутри вложенных спецификаций.

{
  "hconcat": [
    {
      "width": 200,
      "mark": "bar",
      "encoding": {
        "x": {"field": "category", "type": "nominal"},
        "y": {"field": "value", "type": "quantitative"}
      }
    },
    {
      "width": 300,
      "mark": "point",
      "encoding": {
        "x": {"field": "category", "type": "nominal"},
        "y": {"field": "value", "type": "quantitative"}
      }
    }
  ]
}

Результат:

  • первая визуализация фиксированной ширины 200px
  • вторая — 300px

При отсутствии явных значений Vega-Lite распределяет пространство автоматически.


Единые данные для всех визуализаций

Часто hconcat используется с общим набором данных на верхнем уровне. Это позволяет синхронизировать сравнение графиков.

{
  "data": {"url": "data/cars.json"},
  "hconcat": [
    {
      "mark": "bar",
      "encoding": {
        "x": {"field": "Origin", "type": "nominal"},
        "y": {"aggregate": "count", "type": "quantitative"}
      }
    },
    {
      "mark": "area",
      "encoding": {
        "x": {"field": "Horsepower", "type": "quantitative"},
        "y": {"aggregate": "count", "type": "quantitative"}
      }
    }
  ]
}

Общий источник данных снижает дублирование и упрощает поддержку спецификации.


Раздельные источники данных внутри hconcat

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

{
  "hconcat": [
    {
      "data": {"url": "data/temperature.json"},
      "mark": "line",
      "encoding": {
        "x": {"field": "date", "type": "temporal"},
        "y": {"field": "temp", "type": "quantitative"}
      }
    },
    {
      "data": {"url": "data/rainfall.json"},
      "mark": "bar",
      "encoding": {
        "x": {"field": "date", "type": "temporal"},
        "y": {"field": "rain", "type": "quantitative"}
      }
    }
  ]
}

Такой подход применяется при сравнении различных временных рядов.


Синхронизация шкал и осей

По умолчанию каждая визуализация имеет независимые шкалы. Для согласования используется resolve.

{
  "resolve": {
    "scale": {
      "y": "shared"
    }
  },
  "hconcat": [
    {
      "mark": "bar",
      "encoding": {
        "x": {"field": "A", "type": "nominal"},
        "y": {"field": "value", "type": "quantitative"}
      }
    },
    {
      "mark": "bar",
      "encoding": {
        "x": {"field": "A", "type": "nominal"},
        "y": {"field": "value", "type": "quantitative"}
      }
    }
  ]
}

Типы разрешения:

  • shared — общая шкала
  • independent — независимая шкала (по умолчанию)

Комбинация hconcat с vconcat

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

{
  "vconcat": [
    {
      "hconcat": [
        {
          "mark": "bar",
          "encoding": {
            "x": {"field": "A", "type": "nominal"},
            "y": {"field": "value", "type": "quantitative"}
          }
        },
        {
          "mark": "line",
          "encoding": {
            "x": {"field": "A", "type": "nominal"},
            "y": {"field": "value", "type": "quantitative"}
          }
        }
      ]
    },
    {
      "hconcat": [
        {
          "mark": "point",
          "encoding": {
            "x": {"field": "B", "type": "quantitative"},
            "y": {"field": "value", "type": "quantitative"}
          }
        },
        {
          "mark": "area",
          "encoding": {
            "x": {"field": "B", "type": "quantitative"},
            "y": {"field": "value", "type": "quantitative"}
          }
        }
      ]
    }
  ]
}

Такая структура образует таблицу визуализаций с контролируемой логикой расположения.


Работа с заголовками в hconcat

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

{
  "hconcat": [
    {
      "title": "Продажи",
      "mark": "bar",
      "encoding": {
        "x": {"field": "month", "type": "ordinal"},
        "y": {"field": "sales", "type": "quantitative"}
      }
    },
    {
      "title": "Прибыль",
      "mark": "bar",
      "encoding": {
        "x": {"field": "month", "type": "ordinal"},
        "y": {"field": "profit", "type": "quantitative"}
      }
    }
  ]
}

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


Вложенные композиции и сложные структуры

hconcat поддерживает вложенные композиции, включая сочетание с layer, facet и другими структурами.

{
  "hconcat": [
    {
      "layer": [
        {
          "mark": "line",
          "encoding": {
            "x": {"field": "x", "type": "quantitative"},
            "y": {"field": "y1", "type": "quantitative"}
          }
        },
        {
          "mark": "point",
          "encoding": {
            "x": {"field": "x", "type": "quantitative"},
            "y": {"field": "y1", "type": "quantitative"}
          }
        }
      ]
    },
    {
      "layer": [
        {
          "mark": "line",
          "encoding": {
            "x": {"field": "x", "type": "quantitative"},
            "y": {"field": "y2", "type": "quantitative"}
          }
        },
        {
          "mark": "point",
          "encoding": {
            "x": {"field": "x", "type": "quantitative"},
            "y": {"field": "y2", "type": "quantitative"}
          }
        }
      ]
    }
  ]
}

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


Отступы и визуальная структура

Vega-Lite автоматически управляет промежутками между элементами hconcat, однако дополнительные настройки доступны через spacing.

{
  "spacing": 20,
  "hconcat": [
    {
      "mark": "bar",
      "encoding": {
        "x": {"field": "a", "type": "nominal"},
        "y": {"field": "v", "type": "quantitative"}
      }
    },
    {
      "mark": "bar",
      "encoding": {
        "x": {"field": "a", "type": "nominal"},
        "y": {"field": "v", "type": "quantitative"}
      }
    }
  ]
}

Параметр spacing влияет на расстояние между всеми соседними элементами в конкатенации.


Поведение осей при горизонтальной конкатенации

Оси в hconcat ведут себя независимо:

  • каждая визуализация имеет собственную систему координат
  • подписи и сетка не синхронизируются автоматически
  • возможна ручная унификация через resolve.axis
{
  "resolve": {
    "axis": {
      "y": "shared"
    }
  },
  "hconcat": [
    {
      "mark": "line",
      "encoding": {
        "x": {"field": "t", "type": "temporal"},
        "y": {"field": "v1", "type": "quantitative"}
      }
    },
    {
      "mark": "line",
      "encoding": {
        "x": {"field": "t", "type": "temporal"},
        "y": {"field": "v2", "type": "quantitative"}
      }
    }
  ]
}

Типовые сценарии применения hconcat

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

Ограничения и особенности композиции

  • вложенные hconcat увеличивают сложность рендеринга
  • большое количество элементов влияет на производительность
  • синхронизация масштабов требует явной настройки через resolve
  • единообразие дизайна зависит от ручного управления width, height и spacing
  • поведение адаптивной верстки может отличаться в зависимости от контейнера рендеринга