功能结构图(Function Tree / Org Tree)是常见的展示方式。它能够直观表达父子节点关系、模块层次与逻辑结构。但有时我们希望让层级连接更清晰,这时“箭头”就能起到很好的视觉引导作用。
本文将介绍如何在功能结构图中,为节点动态添加箭头,并支持开关隐藏箭头的功能。先给大家看一下功能结构图的效果吧,在网站tools.anqstar.com/tools/struc… 就可以使用改功能,可以自己手动输入节点就自动生成功能结构图,也可以使用AI生成,下面是图片展示效果:
编辑
一、基本思路
结构图的每个节点通常是一个 DOM 元素,我们可以通过修改节点样式和插入新的元素(如 <div>)来控制箭头显示。关键点包括:
- 使用配置项控制样式(如
borderColor、arrowSize、showArrows等)。 - 遍历所有节点,根据是否是根节点决定是否添加箭头。
- 使用纯 CSS 的三角形实现箭头。
- 支持通过配置动态隐藏或显示箭头。
二、核心代码实现
核心函数是 updateTreeStyle,用于更新整棵功能结构树的样式。下面是完整实现(已包含箭头逻辑):
import type { TreeNode } from '../data'
import type { StructureConfig } from '../store'
export const updateTreeStyle = (config: StructureConfig, treeData: TreeNode) => {
const { borderWidth, borderColor, isBold, showArrows, arrowTop, arrowSize, nodeSpacing, lineHeight } = config
const data = treeData
const eles = document.getElementsByClassName('org-tree-node-label-inner')
for (let i = 0; i < eles.length; i++) {
const element = eles[i] as HTMLElement
element.style.border = `${borderWidth}px solid ${borderColor}`
element.style.borderRadius = '0'
element.style.fontWeight = isBold ? 'bold' : 'normal'
element.style.position = 'relative'
// 移除旧箭头
const existingArrow = element.querySelector('.node-arrow')
if (existingArrow) {
element.removeChild(existingArrow)
}
// 判断是否为根节点
const isFirstNode = element.textContent === data.name
// 非根节点才显示箭头
if (!isFirstNode && showArrows) {
const arrow = document.createElement('div')
arrow.style.position = 'absolute'
arrow.style.top = `-${arrowTop}px`
arrow.style.left = `calc(50% + ${arrowSize / 4}px)`
arrow.style.transform = 'translateX(-50%)'
arrow.style.width = '0'
arrow.style.height = '0'
arrow.style.borderLeft = `${arrowSize}px solid transparent`
arrow.style.borderRight = `${arrowSize}px solid transparent`
arrow.style.borderTop = `${arrowTop}px solid ${borderColor}`
arrow.className = 'node-arrow'
element.appendChild(arrow)
}
}
// 更新连接线样式
const style = document.createElement('style')
style.type = 'text/css'
const css = `
.org-tree-node-children{
padding-top: ${nodeSpacing}px;
}
.org-tree-node-children:before {
height: ${nodeSpacing}px;
}
.org-tree-node:before, .org-tree-node:after{
height: ${lineHeight}px;
}
.org-tree-node{
padding-top: ${lineHeight}px;
}
.org-tree-node:not(:first-child)::before {
border-top: ${borderWidth}px solid ${borderColor};
}
.org-tree-node:not(:last-child)::after {
border-top: ${borderWidth}px solid ${borderColor};
}
.org-tree-node:after {
border-left: ${borderWidth}px solid ${borderColor};
}
.org-tree-node-children:before {
border-left: ${borderWidth}px solid ${borderColor};
}
`
style.innerHTML = css
document.head.appendChild(style)
}
三、实现原理解析
这段逻辑主要做了三件事:
1. 遍历节点并统一样式
通过修改 borderWidth、fontWeight 等属性,保持节点样式一致。
2. 动态添加箭头
在每个节点中创建一个新的 <div> 元素,用纯 CSS 绘制一个三角形箭头,利用 border 实现。例如:
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-top: 8px solid #333;
这样即可得到一个朝上的小箭头。
3. 控制箭头显示与隐藏
通过 showArrows 参数控制逻辑:
true→ 添加箭头false→ 不添加箭头(或移除已存在的)
四、使用效果
在 StructureConfig 中加入相关配置项:
{
borderColor: '#333',
borderWidth: 2,
isBold: true,
showArrows: true,
arrowTop: 8,
arrowSize: 6,
nodeSpacing: 20,
lineHeight: 40
}
当 showArrows 为 true 时,子节点上方会出现一个小箭头,指示父级方向;当关闭时,箭头会自动隐藏。
五、总结
通过简单的 DOM 操作和样式控制,我们就能为结构图添加直观的箭头效果。这种方式无需引入额外图形库,适合在已有组织结构树或功能结构图组件中快速增强视觉层次。