You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular中TypeScript实现图节点的正确排序与渲染问题

解决方案

1. 先构建图的邻接表

首先把linksArray转换成邻接表结构,方便快速查找任意节点的所有后继节点:

// 邻接表:key为源节点ID,value为对应目标节点ID的数组
const adjacencyList = new Map<string, string[]>();
linksArray.forEach(link => {
  if (!adjacencyList.has(link.source)) {
    adjacencyList.set(link.source, []);
  }
  adjacencyList.get(link.source)!.push(link.target);
});

2. 实现遍历算法(DFS/BFS)

通过深度优先(DFS)或广度优先(BFS)遍历节点,按顺序调用graph.add(node),同时记录已访问节点避免重复添加:

深度优先遍历(适合层级嵌套展示)

const visited = new Set<string>();

function dfs(nodeId: string) {
  if (visited.has(nodeId)) return;
  // 添加节点到图
  graph.add(nodeId);
  visited.add(nodeId);
  // 遍历当前节点的所有后继节点
  const neighbors = adjacencyList.get(nodeId) || [];
  neighbors.forEach(neighbor => dfs(neighbor));
}

// 从指定起始节点开始遍历
const startNode = linksArray[0].source;
dfs(startNode);

// 处理孤立子图(比如NodeId8、NodeId10这类不在起始连通分量的节点)
linksArray.forEach(link => {
  if (!visited.has(link.source)) dfs(link.source);
  if (!visited.has(link.target)) dfs(link.target);
});

广度优先遍历(适合层级平铺展示)

如果希望节点按层级顺序排列(起始节点在第一层,直接后继在第二层,以此类推),可以用BFS:

const visited = new Set<string>();
const queue: string[] = [];

const startNode = linksArray[0].source;
queue.push(startNode);
visited.add(startNode);

while (queue.length > 0) {
  const currentNode = queue.shift()!;
  // 添加节点到图
  graph.add(currentNode);
  // 将未访问的后继节点加入队列
  const neighbors = adjacencyList.get(currentNode) || [];
  neighbors.forEach(neighbor => {
    if (!visited.has(neighbor)) {
      visited.add(neighbor);
      queue.push(neighbor);
    }
  });
}

// 处理孤立子图
linksArray.forEach(link => {
  if (!visited.has(link.source)) {
    queue.push(link.source);
    visited.add(link.source);
    while (queue.length > 0) {
      const node = queue.shift()!;
      graph.add(node);
      const neighbors = adjacencyList.get(node) || [];
      neighbors.forEach(n => {
        if (!visited.has(n)) {
          visited.add(n);
          queue.push(n);
        }
      });
    }
  }
  // 处理无出边的孤立目标节点
  if (!visited.has(link.target) && !adjacencyList.has(link.target)) {
    graph.add(link.target);
    visited.add(link.target);
  }
});

3. 节点排列优化建议

要让节点相邻展示,除了添加顺序,还需在渲染阶段配合布局逻辑:

  • DFS遍历结果:按嵌套层级设置节点坐标(子节点在父节点下方/右侧偏移固定距离)
  • BFS遍历结果:按层级分组,同一层级节点横向排列,不同层级纵向排列

初始思路的局限说明

你的思路仅能处理单分支链式结构,遇到多分支(比如NodeId1同时指向3和6)时会遗漏分支节点,也无法覆盖孤立子图(比如8→10)。通过邻接表+遍历算法,可覆盖所有节点并处理多分支场景。

内容的提问来源于stack exchange,提问作者1zz0

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 22:23:13