You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Vega中实现嵌套hconcat与vconcat的多视图组合布局?

在Vega中实现多视图拼接布局的方案

Vega里没有Vega-Lite那样直接的hconcat/vconcat语法,得靠group容器结合flex布局来实现拼接,同时用信号(signal)来让左侧两个视图共享x轴。下面是对应你需求的完整实现思路和代码示例:

核心实现逻辑

  • 外层用一个顶级group,设置layout: {type: 'flex', direction: 'row'},实现左右两个区块的水平拼接;
  • 左侧嵌套一个垂直方向的group(layout: {type: 'flex', direction: 'column'}),用来放折线图和水平条形图;
  • 给左侧垂直group定义一个共享信号(比如xDomain),让折线图和水平条形图的x轴scale都绑定这个信号,实现x轴范围同步;
  • 右侧垂直条形图作为顶级group的独立子元素,单独配置自己的scale和轴,和左侧完全隔离。

完整示例代码

{
  "$schema": "https://vega.github.io/schema/vega/v5.json",
  "width": 800,
  "height": 400,
  "signals": [
    // 定义共享的x轴范围信号,供左侧两个图使用
    {
      "name": "xDomain",
      "update": "data('lineData').map(d => d.x)"
    }
  ],
  "data": [
    // 折线图数据
    {
      "name": "lineData",
      "values": [
        {"x": "A", "y": 10}, {"x": "B", "y": 20}, {"x": "C", "y": 15}, {"x": "D", "y": 25}
      ]
    },
    // 水平条形图数据
    {
      "name": "barHData",
      "values": [
        {"x": "A", "y": 5}, {"x": "B", "y": 12}, {"x": "C", "y": 8}, {"x": "D", "y": 18}
      ]
    },
    // 右侧垂直条形图数据
    {
      "name": "barVData",
      "values": [
        {"category": "X", "value": 30}, {"category": "Y", "value": 25}, {"category": "Z", "value": 35}
      ]
    }
  ],
  "scales": [
    // 左侧共享x轴scale
    {
      "name": "xScale",
      "type": "band",
      "domain": {"signal": "xDomain"},
      "range": "width",
      "padding": 0.1
    },
    // 折线图y轴scale
    {
      "name": "yLineScale",
      "type": "linear",
      "domain": {"data": "lineData", "field": "y"},
      "range": "height",
      "nice": true
    },
    // 水平条形图y轴scale
    {
      "name": "yBarHScale",
      "type": "linear",
      "domain": {"data": "barHData", "field": "y"},
      "range": "height",
      "nice": true
    },
    // 右侧垂直条形图x轴scale
    {
      "name": "xBarVScale",
      "type": "band",
      "domain": {"data": "barVData", "field": "category"},
      "range": "width",
      "padding": 0.1
    },
    // 右侧垂直条形图y轴scale
    {
      "name": "yBarVScale",
      "type": "linear",
      "domain": {"data": "barVData", "field": "value"},
      "range": "height",
      "nice": true
    }
  ],
  "axes": [
    // 左侧折线图x轴(放在底部)
    {
      "scale": "xScale",
      "orient": "bottom",
      "group": "leftVerticalGroup"
    },
    // 左侧折线图y轴
    {
      "scale": "yLineScale",
      "orient": "left",
      "group": "leftLinePlot"
    },
    // 左侧水平条形图y轴
    {
      "scale": "yBarHScale",
      "orient": "left",
      "group": "leftBarHPlot"
    },
    // 右侧垂直条形图x轴
    {
      "scale": "xBarVScale",
      "orient": "bottom",
      "group": "rightBarVPlot"
    },
    // 右侧垂直条形图y轴
    {
      "scale": "yBarVScale",
      "orient": "left",
      "group": "rightBarVPlot"
    }
  ],
  "marks": [
    // 外层水平拼接group
    {
      "type": "group",
      "layout": {"type": "flex", "direction": "row", "spacing": 20},
      "groups": [
        // 左侧垂直嵌套group
        {
          "name": "leftVerticalGroup",
          "type": "group",
          "layout": {"type": "flex", "direction": "column", "spacing": 10},
          "width": 450,
          "height": 400,
          "groups": [
            // 左侧折线图
            {
              "name": "leftLinePlot",
              "type": "group",
              "height": 185,
              "marks": [
                {
                  "type": "line",
                  "from": {"data": "lineData"},
                  "encode": {
                    "enter": {
                      "x": {"scale": "xScale", "field": "x"},
                      "y": {"scale": "yLineScale", "field": "y"},
                      "stroke": {"value": "#2c7fb8"},
                      "strokeWidth": {"value": 2}
                    }
                  }
                },
                {
                  "type": "symbol",
                  "from": {"data": "lineData"},
                  "encode": {
                    "enter": {
                      "x": {"scale": "xScale", "field": "x"},
                      "y": {"scale": "yLineScale", "field": "y"},
                      "fill": {"value": "#2c7fb8"},
                      "size": {"value": 80}
                    }
                  }
                }
              ]
            },
            // 左侧水平条形图
            {
              "name": "leftBarHPlot",
              "type": "group",
              "height": 185,
              "marks": [
                {
                  "type": "rect",
                  "from": {"data": "barHData"},
                  "encode": {
                    "enter": {
                      "x": {"scale": "xScale", "field": "x"},
                      "x2": {"scale": "xScale", "value": 0},
                      "y": {"scale": "yBarHScale", "field": "y"},
                      "y2": {"scale": "yBarHScale", "value": 0},
                      "fill": {"value": "#7fcdbb"}
                    }
                  }
                }
              ]
            }
          ]
        },
        // 右侧垂直条形图
        {
          "name": "rightBarVPlot",
          "type": "group",
          "width": 300,
          "height": 400,
          "marks": [
            {
              "type": "rect",
              "from": {"data": "barVData"},
              "encode": {
                "enter": {
                  "x": {"scale": "xBarVScale", "field": "category"},
                  "x2": {"scale": "xBarVScale", "field": "category", "band": 1},
                  "y": {"scale": "yBarVScale", "field": "value"},
                  "y2": {"scale": "yBarVScale", "value": 0},
                  "fill": {"value": "#fdbb84"}
                }
              }
            }
          ]
        }
      ]
    }
  ]
}

关键细节说明

  • 共享x轴:通过xDomain信号同步左侧两个图的x轴范围,确保数据变化时两者x轴始终对齐;
  • 布局控制:每个group的width/height可以手动调整,spacing属性控制视图间的间距;
  • 轴的归属:通过group属性指定轴属于哪个视图,避免轴的重复或错位。

内容的提问来源于stack exchange,提问作者tomecsek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 02:24:55