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

在Angular+D3.js应用中如何根据id勾选指定节点及其所有后代节点

问题背景

我正在开发一款使用D3的Angular应用,使用的树形结构数据和节点样式如下:

const treeData = {
  "id": 1,
  "name": "Root",
  "checked": false,
  "color": "white",
  "children": [
    {
      "id": 2,
      "name": "Leaf A",
      "checked": false,
      "color": "red",
      "children": [
        {
          "id": 3,
          "name": "A - 1",
          "checked": false,
          "color": "brown",
        }, 
        {
          "id": 4,
          "name": "A - 2",
          "checked": false,
          "color": "orange",
        },
        {
          "id": 5,
          "name": "A - 3",
          "checked": false,
          "color": "yellow",
        },
      ]
    }, 
    {
      "id": 6,
      "name": "Leaf B",
      "checked": false,
      "color": "green",
      "children": [
        {
          "id": 7,
          "name": "B - 1",
          "checked": false,
          "color": "#00ff40",
        }, 
        {
          "id": 8,
          "name": "B - 2",
          "checked": false,
          "color": "#00ff80",
        }
      ]
    }
  ]  
};
.node {
  cursor: pointer;
}

.node circle {
  fill: #fff;
  stroke: #C0C0C0;
  stroke-width: 1.5px;
}

.node text {
  font: 10px sans-serif;
}

.link {
  fill: none;
  stroke: #C0C0C0;
  stroke-width: 1.5px;
}

需求说明

我会从API获取一个id值,该id会匹配上述数据中存在的任意节点id,需要将该匹配节点、其所有子节点及子孙节点都设置为选中状态,请问该如何实现?

实现方案

1. 编写递归处理函数

通过两次递归操作即可完成需求:第一次遍历整棵树找到对应id的目标节点,第二次遍历目标节点的所有后代,将所有节点的checked属性设为true。

// 递归将目标节点及其所有后代的checked属性设为true
function setCheckedForNodeAndDescendants(node) {
  node.checked = true;
  if (Array.isArray(node.children) && node.children.length) {
    node.children.forEach(child => setCheckedForNodeAndDescendants(child));
  }
}

// 递归遍历树查找指定id的节点
function findNodeById(root, targetId) {
  if (root.id === targetId) return root;
  if (Array.isArray(root.children) && root.children.length) {
    for (const child of root.children) {
      const matchedNode = findNodeById(child, targetId);
      if (matchedNode) return matchedNode;
    }
  }
  return null;
}

// 调用示例,假设从API获取到的目标id为2
const apiTargetId = 2;
const matchedNode = findNodeById(treeData, apiTargetId);
if (matchedNode) {
  setCheckedForNodeAndDescendants(matchedNode);
  // 此处调用你的D3树重绘方法,更新视图上的节点选中状态
}

2. 更新D3视图

修改你的节点渲染逻辑,将节点样式和checked属性绑定,更新数据后重新触发D3渲染即可看到选中效果,示例绑定逻辑如下:

// 绘制节点圆形部分的逻辑调整
node.append('circle')
  .attr('r', 8)
  .style('fill', d => d.checked ? d.color : '#fff') // 选中时填充节点对应颜色,未选中为白色
  .style('stroke', '#C0C0C0')
  .style('stroke-width', '1.5px');

如果是在Angular组件中实现,更新数据后如果视图没有自动刷新,可以注入ChangeDetectorRef调用detectChanges()手动触发变更检测。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.20 15:54:01