如何在Vega中平滑连接Actual与Forecast折线?
在Vega中实现Actual与Forecast折线平滑连接的方法
当前代码中两条折线断开的核心原因是:Actual折线到C点后无后续数据,Forecast折线从D点开始,缺少C点的衔接数据,导致两段折线之间没有连续的点支撑连线。以下是两种可行的解决方案:
方法一:通过数据变换自动补全连接点
利用Vega的数据变换功能,自动提取Actual的最后一个点并合并到Forecast数据集中,让Forecast折线从Actual终点开始绘制。
修改后的完整代码:
{ "$schema": "https://vega.github.io/schema/vega/v5.json", "width": 400, "height": 200, "padding": 5, "data": [ { "name": "table", "values": [ {"x": "A", "y": 28, "type":"Actual"}, {"x": "B", "y": 55, "type":"Actual"}, {"x": "C", "y": 43, "type":"Actual"}, {"x": "D", "y": 91, "type":"Forecast"}, {"x": "E", "y": 81, "type":"Forecast"}, {"x": "F", "y": 53, "type":"Forecast"}, {"x": "G", "y": 19, "type":"Forecast"}, {"x": "H", "y": 87, "type":"Forecast"}, {"x": "I", "y": 52, "type":"Forecast"}, {"x": "J", "y": 48, "type":"Forecast"} ] }, { "name": "forecast_connected", "source": "table", "transform": [ // 过滤出所有Forecast数据 {"type": "filter", "expr": "datum.type === 'Forecast'"}, // 合并Actual的最后一条数据 {"type": "union", "tables": [ { "data": "table", "transform": [ {"type": "filter", "expr": "datum.type === 'Actual'"}, // 按x排序后取最后一条Actual数据 {"type": "window", "ops": ["row_number"], "as": ["row"], "sort": [{"field": "x"}]}, {"type": "filter", "expr": "datum.row === max('row')"} ] } ]}, // 按x轴顺序排序,确保折线连接正确 {"type": "sort", "field": "x"} ] } ], "scales": [ { "name": "x", "type": "band", "range": "width", "domain": {"data": "table", "field": "x"} }, { "name": "y", "type": "linear", "range": "height", "nice": true, "zero": true, "domain": {"data": "table", "field": "y"} } ], "axes": [ {"orient": "bottom", "scale": "x"}, {"orient": "left", "scale": "y"} ], "marks": [ { "type": "line", "from": {"data": "table"}, "encode": { "enter": { "x": {"scale": "x", "field": "x"}, "y": {"scale":"y","field": "y"}, "stroke": {"value": "black"}, "strokeWidth": {"value": 2} }, // 只显示Actual类型的点 "update": {"opacity": {"expr": "datum.type === 'Actual' ? 1 : 0"}} } }, { "type": "line", "from": {"data": "forecast_connected"}, "encode": { "enter": { "x": {"scale": "x", "field": "x"}, "y": {"scale":"y","field": "y"}, "stroke": {"value": "gray"}, "strokeWidth": {"value": 2}, "strokeDash": {"value": [3,5]} } } } ] }
方法二:手动补充数据源(简单直接)
如果数据量小且固定,可直接在数据源中添加一个衔接点:复制Actual的最后一条记录,将类型改为Forecast,让Forecast折线自然连接到Actual终点。
修改后的数据部分:
"data": [ { "name": "table", "values": [ {"x": "A", "y": 28, "type":"Actual"}, {"x": "B", "y": 55, "type":"Actual"}, {"x": "C", "y": 43, "type":"Actual"}, {"x": "C", "y": 43, "type":"Forecast"}, // 新增连接点 {"x": "D", "y": 91, "type":"Forecast"}, {"x": "E", "y": 81, "type":"Forecast"}, {"x": "F", "y": 53, "type":"Forecast"}, {"x": "G", "y": 19, "type":"Forecast"}, {"x": "H", "y": 87, "type":"Forecast"}, {"x": "I", "y": 52, "type":"Forecast"}, {"x": "J", "y": 48, "type":"Forecast"} ] } ]
保留原marks中的折线定义即可,Forecast折线会自动从C点连接到D点。
核心原理
折线的绘制依赖连续的数据点,只要让其中一段折线包含另一段的终点数据,就能在两个分段之间形成自然的平滑连接。
内容的提问来源于stack exchange,提问作者tomecsek
相关产品推荐
相关产品推荐

