Vega-Lite(Deneb)瀑布图BEGIN列前置显示问题求助
问题
在Vega-Lite(Deneb)中制作瀑布图时,遇到以下瓶颈:
- 已成功让END列显示在X轴(1-12月)的末端,但无法让BEGIN列正确显示在Jan之前
- BEGIN列要么不显示,要么出现在Jan之后,调整X轴排序也无效
请问能否直接在Vega-Lite中实现BEGIN列位于Jan之前、END列位于Dec之后的瀑布图效果?
失败尝试效果:
当前使用的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
相关产品推荐
相关产品推荐

