如何在D3JS层级员工树状图中点击新节点时折叠已展开节点?
实现D3.js树状图点击新节点时自动折叠其他展开节点
核心思路
通过跟踪当前处于展开状态的节点,在点击新的经理节点时,先折叠之前展开的节点,再切换当前节点的展开状态,确保同一时间只有一个节点处于展开状态,节省视图空间。
具体实现步骤
- 定义跟踪变量:用一个变量记录当前展开的节点,初始值为
null。 - 修改点击事件逻辑:在节点点击处理函数中,先处理旧节点的折叠,再处理当前节点的展开/切换。
- 重新渲染树状图:状态变更后调用树的更新函数刷新视图。
代码示例
// 跟踪当前展开的节点 let currentExpandedNode = null; // 节点点击事件处理函数 function onNodeClick(event, nodeData) { // 点击的是当前已展开的节点,切换其折叠状态 if (currentExpandedNode === nodeData) { // 保存子节点引用,然后清空children实现折叠 nodeData._children = nodeData.children; nodeData.children = null; currentExpandedNode = null; } else { // 折叠之前展开的节点(如果存在) if (currentExpandedNode) { currentExpandedNode._children = currentExpandedNode.children; currentExpandedNode.children = null; } // 展开当前节点(仅当有子节点时) if (nodeData._children) { nodeData.children = nodeData._children; nodeData._children = null; currentExpandedNode = nodeData; } else { // 当前节点无下属,重置跟踪变量 currentExpandedNode = null; } } // 调用树更新函数刷新视图 updateTreeLayout(nodeData); } // 树状图更新函数(示例框架,需结合你的现有逻辑调整) function updateTreeLayout(sourceNode) { // 初始化树布局(根据你的尺寸需求调整) const treeLayout = d3.tree().size([window.innerHeight - 100, window.innerWidth - 200]); // 重新计算树布局 treeLayout(root); // 以下是节点和链接的更新逻辑,替换为你现有代码 // 更新节点位置、样式... // 更新链接路径... }
关键细节说明
- 折叠/展开的存储方式:D3树状图通常用
_children存储折叠状态下的子节点引用,展开时将children指向_children,折叠时将children设为null,这样可以保留子节点数据不丢失。 - 节点类型判断:如果你的树中存在无下属的普通员工节点,点击时不会触发任何折叠/展开操作,避免无效状态变更。
- 动态加载场景适配:如果你的子节点是点击时异步加载的,需要在折叠旧节点后,再触发当前节点的子数据加载,加载完成后再更新
children并渲染。
内容的提问来源于stack exchange,提问作者anuruddha bandara
相关产品推荐
相关产品推荐

