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

Vega-Lite(Deneb)瀑布图BEGIN列前置显示问题求助

问题

在Vega-Lite(Deneb)中制作瀑布图时,遇到以下瓶颈:

  • 已成功让END列显示在X轴(1-12月)的末端,但无法让BEGIN列正确显示在Jan之前
  • BEGIN列要么不显示,要么出现在Jan之后,调整X轴排序也无效

请问能否直接在Vega-Lite中实现BEGIN列位于Jan之前、END列位于Dec之后的瀑布图效果?

失败尝试效果:
waterfall attempt

当前使用的Vega-Lite代码:

{"data": {"name": "dataset"},"transform": [{"sort": [{"field": "MonthNo"}],"window": [{"op": "lag","field": "salesCY","as": "salesCY_previous"},{"op": "lag","field": "Month","as": "month_previous"},{"op": "lead","field": "salesCY","as": "salesCY_following"},{"op": "lead","field": "Month","as": "month_following"}]},{"calculate": "datum.month_previous == null ? 'BEGIN' : datum.month_previous","as": "month_previous"},{"calculate": "datum.month_following == null ? 'END' : datum.month_following","as": "month_following"},{"calculate": "datum.month_previous === 'BEGIN' ? -999 : datum.month_following === 'END' ? 999 : datum.MonthNo","as": "sort_order"}],"width": 500,"height": 200,"layer": [{"mark": {"type": "bar","fill": {"expr": "datum.salesCY > datum.salesCY_previous ? '#0291DC' : '#F0535A' "},"width": {"band": 0.8}}},{"transform": [{"filter": "datum.month_previous == 'BEGIN'"}],"mark": {"type": "bar","fill": "lightgrey","stroke": "black","strokeWidth": 0.5,"width": {"band": 0.8}},"encoding": {"x": {"field": "month_previous","type": "nominal","axis": {"title": null,"labels": true,"labelFontSize": 15,"labelColor": "grey","labelExpr": "datum.label[0]","labelAngle": 0,"labelPadding": 15,"domain": false,"ticks": false},"sort": {"field": "sort_order","order": "ascending"},"scale": {"zero": true}},"y2": {"datum": 0,"type": "quantitative","axis": {"title": null,"labels": false,"domain": false,"ticks": false,"grid": false}},"y": {"field": "salesCY","type": "quantitative","axis": {"title": null,"labels": false,"domain": false,"ticks": false,"grid": false}}}},{"transform": [{"filter": "datum.month_following == 'END'"}],"mark": {"type": "bar","fill": "black","width": {"band": 0.8}},"encoding": {"x": {"field": "month_following","type": "nominal","axis": {"title": null,"labels": true,"labelColor": "grey","labelExpr": "datum.label[0]","labelAngle": 0,"domain": false,"ticks": false},"sort": null,"scale": {"zero": true}},"y2": {"datum": 0,"type": "quantitative","axis": {"title": null,"labels": false,"domain": false,"ticks": false,"grid": false}},"y": {"field": "salesCY","type": "quantitative","axis": {"title": null,"labels": false,"domain": false,"ticks": false,"grid": false}}}}],"encoding": {"x": {"field": "Month","type": "nominal","axis": {"title": null,"labels": true,"labelColor": "grey","labelExpr": "datum.label[0]","labelAngle": 0,"domain": false,"ticks": false},"sort": {"field": "sort_order","type": "ordinal"},"scale": {"zero": true}},"y2": {"field": "salesCY_previous","type": "quantitative","axis": {"title": null,"labels": false,"domain": false,"ticks": false,"grid": false}},"y": {"field": "salesCY","type": "quantitative","axis": {"title": null,"labels": false,"domain": false,"ticks": false,"grid": false}}}}
解决方案

可以直接实现,核心问题在于当前图层分别使用了不同的X轴字段(主图层用Month,BEGIN图层用month_previous,END图层用month_following),导致排序规则无法统一生效。需要统一X轴字段,并将BEGIN/END的排序逻辑整合到全局排序中,具体修改后的完整代码如下:

{
  "data": {"name": "dataset"},
  "transform": [
    {"sort": [{"field": "MonthNo"}],"window": [
      {"op": "lag","field": "salesCY","as": "salesCY_previous"},
      {"op": "lead","field": "salesCY","as": "salesCY_following"}
    ]},
    // 生成统一的X轴显示字段
    {"calculate": "datum.MonthNo === 1 ? 'BEGIN' : datum.MonthNo === 12 ? 'END' : datum.Month","as": "x_label"},
    // 定义全局排序值:BEGIN为0,月份按MonthNo,END为13
    {"calculate": "datum.MonthNo === 1 ? 0 : datum.MonthNo === 12 ? 13 : datum.MonthNo","as": "sort_order"},
    // 处理BEGIN的初始值和END的最终值
    {"calculate": "datum.MonthNo === 1 ? datum.salesCY : datum.salesCY_previous","as": "bar_start"},
    {"calculate": "datum.MonthNo === 12 ? datum.salesCY : datum.salesCY","as": "bar_end"}
  ],
  "width": 500,
  "height": 200,
  "encoding": {
    "x": {
      "field": "x_label",
      "type": "nominal",
      "axis": {
        "title": null,
        "labels": true,
        "labelColor": "grey",
        "labelExpr": "datum.label[0]",
        "labelAngle": 0,
        "domain": false,
        "ticks": false
      },
      "sort": {"field": "sort_order", "order": "ascending"},
      "scale": {"zero": true}
    }
  },
  "layer": [
    // 主月份瀑布条
    {"mark": {
      "type": "bar",
      "fill": {"expr": "datum.salesCY > datum.salesCY_previous ? '#0291DC' : '#F0535A' "},
      "width": {"band": 0.8}
    },
    "transform": [{"filter": "datum.MonthNo !== 1 && datum.MonthNo !== 12"}],
    "encoding": {
      "y2": {"field": "bar_start", "type": "quantitative"},
      "y": {"field": "bar_end", "type": "quantitative"}
    }},
    // BEGIN条
    {"mark": {
      "type": "bar",
      "fill": "lightgrey",
      "stroke": "black",
      "strokeWidth": 0.5,
      "width": {"band": 0.8}
    },
    "transform": [{"filter": "datum.MonthNo === 1"}],
    "encoding": {
      "y2": {"datum": 0},
      "y": {"field": "bar_end", "type": "quantitative"}
    }},
    // END条
    {"mark": {
      "type": "bar",
      "fill": "black",
      "width": {"band": 0.8}
    },
    "transform": [{"filter": "datum.MonthNo === 12"}],
    "encoding": {
      "y2": {"field": "bar_start", "type": "quantitative"},
      "y": {"field": "bar_end", "type": "quantitative"}
    }}
  ],
  "config": {"axis": {"title": null, "labels": false, "domain": false, "ticks": false, "grid": false}}
}

修改说明

  • 新增x_label字段,将BEGIN、月份、END统一为同一个X轴字段,确保所有元素都在同一刻度上排序
  • 调整sort_order:BEGIN设为0,月份按原MonthNo(1-12),END设为13,保证排序顺序绝对正确
  • 拆分图层逻辑:主图层过滤掉1月和12月,单独处理BEGIN(1月)和END(12月)的条形样式与起始值
  • 统一全局配置,减少重复的轴定义,让代码更简洁

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 16:27:32