绘制组织架构图需分三步:先用递归算法自底向上计算节点坐标避免重叠,再用贝塞尔曲线绘制自然连接线并按深度调整线宽,最后分背景层、节点层、高亮层分层渲染提升性能与清晰度。

Canvas 本身不提供自动布局或连线逻辑,绘制精美的组织架构图关键在于:合理排布节点位置 + 精准绘制连接线 + 分层视觉处理。纯靠手算坐标容易重叠错位,必须结合算法或结构化策略。
用递归计算实现自底向上的树形定位
避免节点覆盖的核心是“先算子树占位,再定父节点位置”。对每个节点,先递归统计其最底层叶子总数,再按等距分配水平空间:
- 定义每个节点宽120px、高50px,横向间距40px,纵向间距80px
- 写
getSubtreeWidth(node):返回该节点及其所有后代占据的总宽度(含间距) - 父节点
x坐标 = 左子树宽度 + (当前节点宽/2);y坐标 = 子节点y- 80 - 子节点逐个从左到右排列:
child.x = parent.x - 总宽/2 + 已占宽度 + child宽/2
用贝塞尔曲线画自然连接线
直线连线生硬,用 quadraticCurveTo() 模拟树枝分叉感更专业:
- 从父节点底部中点
(px, py+50)开始moveTo() - 控制点设为
(px, py+50 + 30)(略向下偏移,制造下垂弧度) - 终点为子节点顶部中点
(cx, cy),调用quadraticCurveTo(cpX, cpY, cx, cy) - 线宽随深度变细(如根部3px → 第3层1.2px),末端加
lineCap = 'round'
分层渲染提升清晰度与性能
把图拆成三部分独立绘制,避免重叠干扰和重复计算:
立即学习“前端免费学习笔记(深入)”;
-
背景层:先画所有连接线(半透明灰色,
globalAlpha = 0.7) - 节点层:再画带圆角矩形框 + 居中文本,不同层级用色块区分(如总监层浅蓝、经理层浅灰)
-
高亮层:鼠标悬停时,仅重绘该节点及其直连线(用
isPointInStroke(x,y)判断热区)
加一点细节让图更耐看
小优化能显著提升专业感:
- 文本居中:用
ctx.textBaseline = 'middle'和ctx.textAlign = 'center',配合measureText()算准横纵偏移 - 轻微抖动:每条线控制点加 ±0.6px 随机偏移,消除机械感
- 展开/折叠支持:节点对象加
collapsed: true字段,只在展开时递归绘制子树 - 导出图片:调用
canvas.toDataURL('image/png')一键保存



















