基于含nodes和edges的JSON生成任意层级父子关系图的最优方案咨询
从JSON节点边数据生成任意层级父子关系结构
我手里有包含nodes和edges的JSON数据,edges存储节点间的关联关系,nodes存储节点源信息。需要基于这些数据生成支持任意层级深度的父子关系图,用于Web UI展示。我对解析嵌套JSON经验不足,之前考虑过用Pandas构建父子关系再用SQL生成树结构,但想找更优的实现方案。已经把S2DCMWorkflow修改为Table_5,也画出了树状图,现在需要整理父子层级数据用于Web UI展示。
原始JSON数据
{ "graph": { "depthComputed": 1, "depthRequested": 2, "edges": [ {"source": "a84a8484-63e8-43c8-9b20-90302a768537", "target": "e4a8ffc8-c13b-49cc-a11a-af8f0212acea"}, {"source": "c5084be9-b3ed-486a-a078-534690507d0d", "target": "e4a8ffc8-c13b-49cc-a11a-af8f0212acea"}, {"source": "c4679e97-55af-4d99-9458-6d694cb3de4e", "target": "e4a8ffc8-c13b-49cc-a11a-af8f0212acea"}, {"source": "e4a8ffc8-c13b-49cc-a11a-af8f0212acea", "target": "0c5fe88a-ad7c-44db-ab03-e9ceaa5900c6"} ], "nodes": [ {"_id": "0c5fe88a-ad7c-44db-ab03-e9ceaa5900c6", "_type": "DataSourceNode", "name": "Table_4"}, {"_id": "a84a8484-63e8-43c8-9b20-90302a768537", "_type": "DataSourceNode", "name": "Table_1"}, {"_id": "c5084be9-b3ed-486a-a078-534690507d0d", "_type": "DataSourceNode", "name": "Table_2"}, {"_id": "c4679e97-55af-4d99-9458-6d694cb3de4e", "_type": "DataSourceNode", "name": "Table_3"}, {"_id": "e4a8ffc8-c13b-49cc-a11a-af8f0212acea", "_type": "ExecutionNode", "agentInfo": {"name": "spline", "version": "0.6.1"}, "name": "Table_5", "systemInfo": {"name": "spark", "version": "2.4.8"}} ] }, "info": { "application": "dsfasfasdafadffafsafaa", "targetDataSourceId": "0c5fe88a-ad7c-44db-ab03-e9ceaa5900c6", "timestamp": 3454345343555 } }
最优实现方案(前端直接处理)
不用依赖Pandas或SQL,直接在前端通过JavaScript处理,步骤简单高效:
- 构建节点快速查找表:把nodes数组转成以
_id为键的对象,能瞬间找到任意节点的信息。 - 建立父子关系映射:遍历edges数组,根据需求构建正向(父→子)或反向(子→父)的关系映射,适配不同的树展示方向。
- 递归生成层级树结构:从指定节点出发,递归遍历关系映射,生成包含层级深度的树结构,直接用于Web UI渲染(比如用Vue/React的递归组件展示)。
代码示例
// 假设data是上面的JSON数据对象 const data = { /* 原始JSON数据 */ }; // 1. 生成ID到节点的映射表 const nodeMap = data.graph.nodes.reduce((map, node) => { map[node._id] = node; return map; }, {}); // 2. 构建子节点到父节点的映射(符合你需要的反向依赖树) const childToParents = {}; data.graph.edges.forEach(edge => { const parentId = edge.source; const childId = edge.target; if (!childToParents[childId]) { childToParents[childId] = []; } childToParents[childId].push(parentId); }); // 3. 递归生成带层级的反向树结构 function buildReverseTree(nodeId, depth = 0) { const node = nodeMap[nodeId]; // 递归获取当前节点的所有父节点 const parents = childToParents[nodeId]?.map(parentId => buildReverseTree(parentId, depth + 1)) || []; return { ...node, depth, parents }; } // 从最终节点Table_4出发,生成完整的反向依赖树 const dependencyTree = buildReverseTree("0c5fe88a-ad7c-44db-ab03-e9ceaa5900c6"); console.log(JSON.stringify(dependencyTree, null, 2));
预期父子关系展示
按照需求整理出的父子对如下:
| 子节点 | 父节点 |
|---|---|
| Table_4 | Table_5 |
| Table_5 | Table_1 |
| Table_5 | Table_2 |
| Table_5 | Table_3 |
或者层级结构:
Table_4 └── Table_5 ├── Table_1 ├── Table_2 └── Table_3
内容的提问来源于stack exchange,提问作者GeekSQL
相关产品推荐
相关产品推荐

