如何在Vega-Lite中无需lookup实现周同比(WoW)叠加折线图?
在Vega-Lite中无Lookup实现周同比双折线图
当然可以不用lookup转换,以下两种更简洁的方案能实现你要的当日与一周前观看人数叠加对比效果:
方案一:日期计算+窗口聚合+数据重塑
通过计算每条数据对应的一周前日期,再用窗口函数匹配对应数值,最后转成适合双折线图的长格式数据:
{ "$schema": "https://vega.github.io/schema/vega-lite/v5.json", "data": { "values": [ {"date": "2024-05-01", "daily_total_viewer": 100}, {"date": "2024-05-02", "daily_total_viewer": 120}, {"date": "2024-05-03", "daily_total_viewer": 115}, {"date": "2024-05-04", "daily_total_viewer": 90}, {"date": "2024-05-05", "daily_total_viewer": 130}, {"date": "2024-05-06", "daily_total_viewer": 140}, {"date": "2024-05-07", "daily_total_viewer": 125}, {"date": "2024-05-08", "daily_total_viewer": 110}, {"date": "2024-05-09", "daily_total_viewer": 130}, {"date": "2024-05-10", "daily_total_viewer": 150} ] }, "transform": [ // 计算一周前的日期并转为字符串格式 {"calculate": "format(datetime(year(datum.date), month(datum.date), date(datum.date) - 7), '%Y-%m-%d')", "as": "prev_week_date"}, {"calculate": "format(datum.date, '%Y-%m-%d')", "as": "date_str"}, // 窗口聚合匹配一周前的观看人数 { "window": [{"field": "daily_total_viewer", "op": "first", "as": "prev_week_viewer"}], "groupby": ["prev_week_date"], "frame": [null, null] }, // 过滤无对应一周前数据的行 {"filter": "datum.prev_week_viewer !== null"}, // 转成长格式数据,方便双折线展示 {"fold": ["daily_total_viewer", "prev_week_viewer"], "as": ["series", "viewers"]} ], "mark": "line", "encoding": { "x": {"field": "date_str", "type": "temporal", "title": "日期"}, "y": {"field": "viewers", "type": "quantitative", "title": "总观看人数"}, "color": { "field": "series", "type": "nominal", "title": "数据类型", "scale": {"domain": ["daily_total_viewer", "prev_week_viewer"], "range": ["#1f77b4", "#ff7f0e"]}, "legend": {"labelExpr": "datum.value === 'daily_total_viewer' ? '当日数据' : '一周前数据'"} } } }
方案优势
- 数据处理逻辑闭环,无需额外关联外部数据源
- 长格式数据适配Vega-Lite的通用可视化逻辑,图例自动生成
方案二:Layer分层绘制双折线
直接通过分层分别绘制当日数据和偏移后的一周前数据,逻辑更直观:
{ "$schema": "https://vega.github.io/schema/vega-lite/v5.json", "data": { "values": [ {"date": "2024-05-01", "daily_total_viewer": 100}, {"date": "2024-05-02", "daily_total_viewer": 120}, {"date": "2024-05-03", "daily_total_viewer": 115}, {"date": "2024-05-04", "daily_total_viewer": 90}, {"date": "2024-05-05", "daily_total_viewer": 130}, {"date": "2024-05-06", "daily_total_viewer": 140}, {"date": "2024-05-07", "daily_total_viewer": 125}, {"date": "2024-05-08", "daily_total_viewer": 110}, {"date": "2024-05-09", "daily_total_viewer": 130}, {"date": "2024-05-10", "daily_total_viewer": 150} ] }, "layer": [ // 当日数据折线 { "mark": {"type": "line", "color": "#1f77b4", "strokeWidth": 2}, "encoding": { "x": {"field": "date", "type": "temporal"}, "y": {"field": "daily_total_viewer", "type": "quantitative"} } }, // 一周前数据折线:将日期偏移7天,对齐到当日位置 { "transform": [ {"calculate": "datetime(year(datum.date), month(datum.date), date(datum.date) + 7)", "as": "current_date"} ], "mark": {"type": "line", "color": "#ff7f0e", "strokeWidth": 2, "strokeDash": [5, 5]}, "encoding": { "x": {"field": "current_date", "type": "temporal"}, "y": {"field": "daily_total_viewer", "type": "quantitative"} } } ], "resolve": {"scale": {"y": "shared"}}, "title": "当日与一周前观看人数对比", "legend": { "title": "数据类型", "entries": [ {"label": "当日数据", "symbol": {"fill": "#1f77b4", "type": "stroke", "strokeWidth": 2}}, {"label": "一周前数据", "symbol": {"fill": "#ff7f0e", "type": "stroke", "strokeWidth": 2, "strokeDash": [5,5]}} ] } }
方案优势
- 代码结构清晰,两条线的逻辑独立可单独调整样式
- 无需数据重塑,性能更优(尤其数据量较大时)
内容的提问来源于stack exchange,提问作者Raghav Mittal
相关产品推荐
相关产品推荐

