如何在Vega-Lite中实现同一数据集内父子行字段动态查找
Power BI Deneb(Vega-Lite 5.6.1)树形可视化:动态获取父行字段值需求
我在Power BI的Deneb可视化组件中使用Vega-Lite 5.6.1,已实现树形/矩阵混合可视化效果:
当前需要实现子行动态查找过滤后数据集内父行对应字段的功能,以此支持用户展开/折叠行操作。
尝试过的无效方案
1. Lookup Transform
Lookup Transform要求传入二级数据集,无法设置"from"参数,无法满足需求:
{ "data": {"name": "dataset"}, "transform": [ ..., {"filter": ... }, {"lookup": "Parent_Path", "from": ... , "key": "Child_Path", "fields": ["Horiz_Offset", "Vert_Offset"], "as": "Parent_Row"} ], "layer": [ ... ] }
2. JoinAggregate Transform
JoinAggregate Transform的"field"参数不支持表达式过滤,无法实现父子行匹配逻辑:
{ "data": {"name": "dataset"}, "transform": [ ..., {"filter": ... }, {"joinaggregate": [{"op": "min", "field": {"value": {"expr": "child.Parent_Path == parent.Child_Path ? Horiz_Offset : null"}}, "as": "Parent_Horiz_Offset"}]}], "layer": [ ... ] }
示例代码说明
以下是包含硬编码数据集的完整示例(实际使用时数据通过"data": {"name": "dataset"}从外部传入)。目标是移除Parent_Horiz_Offset和Parent_Vert_Offset字段,直接从父行动态获取对应值:
{ "data": { "values": [ {"Full_Path": "Level 1a\\Level 2a\\Level 3a\\Employee 01", "Child_Path": "Level 1a", "Parent_Path": "", "Node_Text": "Level 1a", "Horiz_Offset": 0, "Vert_Offset": 0, "Parent_Horiz_Offset": null, "Parent_Vert_Offset": null}, {"Full_Path": "Level 1a\\Level 2a\\Level 3a\\Employee 01", "Child_Path": "Level 1a\\Level 2a", "Parent_Path": "Level 1a", "Node_Text": "Level 2 a", "Horiz_Offset": 1, "Vert_Offset": 1, "Parent_Horiz_Offset": 0, "Parent_Vert_Offset": 0}, {"Full_Path": "Level 1a\\Level 2a\\Level 3a\\Employee 01", "Child_Path": "Level 1a\\Level 2a\\Level 3a", "Parent_Path": "Level 1a\\Level 2a", "Node_Text": "Level 3a", "Horiz_Offset": 2, "Vert_Offset": 2, "Parent_Horiz_Offset": 1, "Parent_Vert_Offset": 1}, {"Full_Path": "Level 1a\\Level 2a\\Level 3a\\Employee 01", "Child_Path": "Level 1a\\Level 2a\\Level 3a\\Employee 01", "Parent_Path": "Level 1a\\Level 2a\\Level 3a", "Node_Text": "Employee 01", "Horiz_Offset": 3, "Vert_Offset": 3, "Parent_Horiz_Offset": 2, "Parent_Vert_Offset": 2} ] }, "params": [ {"name": "_indentSize", "value": 30}, {"name": "_iconSize", "value": 80}, {"name": "_rowHeight", "value": 15}, {"name": "_headerRowHeight", "value": 0} ], "transform": [ {"window": [{"op": "dense_rank", "as": "_rowNum"}], "ignorePeers": true, "sort": [{"field": "Parent_Path", "order": "ascending"}]}, {"window": [{"op": "row_number", "as": "_index"}], "groupby": ["Child_Path"]}, {"calculate": "datum.Horiz_Offset * _indentSize", "as": "_xPos"}, {"calculate": "datum.Vert_Offset * _rowHeight", "as": "_yPos"}, {"calculate": "datum.Parent_Horiz_Offset * _indentSize", "as": "_xPos_Parent"}, {"calculate": "datum.Parent_Vert_Offset * _rowHeight", "as": "_yPos_Parent"}, {"calculate": "datum.Full_Path == datum.Child_Path", "as": "_isLeafNode"}, {"calculate": "datum.Parent_Path == ''", "as": "_isRootNode"}, {"filter": "datum._index == 1"} ], "layer": [ { "description": "Row Background", "params": [{"name": "isSelected", "select": "point"}], "mark": {"type": "rect", "stroke": "#E1E2E3", "cursor": "pointer"}, "encoding": { "x": {"value": {"expr": "datum._xPos - 8"}}, "y": {"value": {"expr": "datum._yPos - ceil(_rowHeight / 2)"}}, "x2": {"value": {"expr": "320"}}, "y2": {"value": {"expr": "datum._yPos + floor(_rowHeight / 2)"}}, "color": {"value": {"expr": "datum._yPos % 2 == 0 ? 'white' : '#F1F2F3'"}}, "opacity": {"condition": {"param": "isSelected", "value": 1}, "value": 0.5} } }, { "description": "Node line horiz", "mark": {"type": "rule", "color": "#00002D"}, "encoding": { "x": {"value": {"expr": "datum._xPos_Parent"}}, "x2": {"value": {"expr": "datum._xPos"}}, "y": {"value": {"expr": "datum._yPos"}}, "y2": {"value": {"expr": "datum._yPos"}}, "opacity": {"value": {"expr": "datum._isRootNode ? 0 : 1"}} } }, { "description": "Node line vert", "mark": {"type": "rule", "color": "#00002D"}, "encoding": { "x": {"value": {"expr": "datum._xPos_Parent"}}, "x2": {"value": {"expr": "datum._xPos_Parent"}}, "y": {"value": {"expr": "datum._yPos_Parent"}}, "y2": {"value": {"expr": "datum._yPos"}}, "opacity": {"value": {"expr": "datum._isRootNode ? 0 : 1"}} } }, { "description": "Node icon", "mark": {"type": "point"}, "encoding": { "x": {"value": {"expr": "datum._xPos"}}, "y": {"value": {"expr": "datum._yPos"}}, "shape": {"value": {"expr": "datum._isLeafNode ? 'circle' : 'square'"}} } }, { "description": "Node text", "mark": {"type": "text"}, "encoding": { "x": {"value": {"expr": "datum._xPos + 10"}}, "y": {"value": {"expr": "datum._yPos"}}, "text": {"field": "Node_Text"}, "opacity": {"condition": {"param": "isSelected", "value": 1}, "value": 0.5} } } ], "config": { "text": { "fill": "#00002D", "align": "left", "font": "Arial", "fontSize": 10 }, "point": { "size": 80, "opacity": 1 } } }
内容的提问来源于stack exchange,提问作者Sean McLarty
相关产品推荐
相关产品推荐

