之前在技术实践中分享过许多可视化与AI结合的搭建方案,今天和大家继续探讨一款结合 AI Coding 能力开发的、面向财务分析领域的可视化流程编辑器——杜邦分析流程图编辑器。

这是一款基于 Vue 3 的可视化流程图编辑器,专为创建和管理财务指标节点关系图而设计。它支持节点参数配置、节点连接计算关系、自动布局等功能,旨在将复杂的财务指标拆解过程变得直观和可交互。
把杜邦分析变成“搭积木”
传统杜邦分析通常采用线性思维,在一张庞大的表格中层层嵌套公式。但财务指标本身具有天然的树状结构:
ROE (树干)
├── 销售净利率 (树枝)
│ ├── 净利润 (叶子)
│ └── 营业收入 (叶子)
├── 资产周转率 (树枝)
│ ├── 营业收入 (叶子)
│ └── 总资产 (叶子)
└── 权益乘数 (树枝)
├── 总资产 (叶子)
└── 净资产 (叶子)
这不正是我们前端开发中熟悉的组件树结构吗?基于此洞察,我们的解决方案对比如下:
| 传统方式 |
新工具方案 |
| Excel公式层层嵌套 |
每个指标是一个独立组件节点 |
| 改数据需手动重算 |
数据变更自动向上传导计算 |
| 静态表格展示 |
可视化流程图实时渲染 |
| 单人操作 |
支持多人协作编辑指标 |
我们运用 Vue3 的组件化思维重构了财务分析流程。每个财务指标都被封装成可复用的 MetricNode 组件,通过 props 接收下游数据,并通过 emit 事件向上汇报计算结果。
核心功能拆解
这款杜邦分析编辑器专注于财务分析领域,其交互设计也围绕该场景展开。以下是其核心功能模块:

1. 指标节点管理
编辑器支持新建各类财务指标节点,并灵活修改其类型。用户点击节点后,可在右侧面板中配置指标的样式与数据类型。

右键点击画布任意位置也可添加节点

每个节点都支持丰富的配置项:
我们提供了非常灵活的节点样式配置选项,下图展示了样式配置的演示效果:

除了样式,节点数据也支持详细配置,例如绑定具体的指标数值、变化率、对比周期等,方便企业接入自身业务数据进行可视化展示。

2. 连线管理
连线管理是定义指标间计算逻辑的核心,主要功能包括:
- 创建节点之间的连接关系
- 支持多种关系类型(相加、相减、相乘、相除、相关)
- 连线样式配置
在金融数据分析中,明确指标间的计算关系至关重要。我们提供了以下几种基础关系供选择,企业研发人员也可在此基础上进行二次扩展。

3. 指标配置
指标配置模块主要负责:
例如,在添加子指标时,用户可以从预设的指标库中选择不同类型的节点。

4. 自动布局算法
系统实现了一套复杂的自动布局算法,以确保节点在画布中的合理、美观分布。

算法核心规则包括:
- 当节点只有一个子节点时,子节点与父节点水平中心对齐。
- 当节点有多个子节点时,子节点对称分布,与父节点形成局部对称效果。
- 新增节点时,确保不与现有节点重叠。
- 子节点与父节点之间保持固定的水平间距。
- 父节点与同级节点(叔叔节点)之间的垂直间距大于子节点之间的垂直间距。
技术实践与核心代码
整个流程图编辑器采用以下技术方案实现:
- Vue 3.5.13:使用最新的组合式API进行开发。
- TypeScript:提供类型安全和更好的开发体验。
- Vite 6.3.4:作为主流前端构建工具,提供快速的开发体验。
- Pinia:Vue官方推荐的状态管理库,用于替代Vuex。
流程图编辑器的核心挑战在于模块化的设计架构和高效的布局算法。
在优化节点自动布局时,我设计了一种混合分段式函数来处理节点位置的自动计算,核心思路是根据子节点数量动态调整所需空间,以避免布局过于拥挤或稀疏。
if (childCount <= 5) {
// 非线性增长(使用更平缓的对数函数)
const factor = childCount <= 3 ? (childCount - 2) : 1 + Math.log(childCount - 2) / Math.log(3)
neededSpace = BASE_PARENT_UNCLE_SPACING + LINEAR_INCREMENT * factor
} else if (childCount <= 9) {
// 6-9个子节点:使用对数函数(更平缓的增长)
neededSpace = BASE_PARENT_UNCLE_SPACING +
PARENT_UNCLE_SPACING_INCREMENT * Math.log(childCount - 4) / Math.log(2)
} else {
// 10+子节点:次线性增长(更平缓)
neededSpace = BASE_PARENT_UNCLE_SPACING +
PARENT_UNCLE_SPACING_INCREMENT * Math.pow(childCount - 9, 0.8) +
PARENT_UNCLE_SPACING_INCREMENT * Math.log(5) / Math.log(2)
}
当在已有节点的画布中添加新节点时,为了保证节点不重叠,我引入了传播衰减机制来优化新节点位置对其他节点的影响。
const propagateVerticalAdjustment = (..., depth = 0) => {
const decayFactor = Math.pow(0.6, depth) // 每层衰减40%
const adjustedDeltaY = deltaY * decayFactor
// ...
}
对于整个画布的状态管理,我设计了统一的状态管理函数来维护视图状态(如缩放、平移),为后续接入真实数据存储和持久化打下基础。
const useCanvasStore = defineStore('canvas', {
state: (): CanvasState => ({
scale: 1,
position: { x: 0, y: 0 },
dimensions: { width: 5000, height: 5000 }
}),
actions: {
// 设置画布缩放
setScale(scale: number) {
// 限制缩放范围
this.scale = Math.min(Math.max(0.1, scale), 2)
},
// 设置画布位置
setPosition(position: Position) {
this.position = position
},
// 设置画布尺寸
setDimensions(dimensions: Size) {
this.dimensions = dimensions
},
// 画布缩放
zoom(delta: number, center: Position) {
const newScale = this.scale + delta * 0.001
this.setScale(newScale)
// 调整位置以保持缩放中心
const scaleFactor = newScale / this.scale
const newPosition = {
x: center.x - (center.x - this.position.x) * scaleFactor,
y: center.y - (center.y - this.position.y) * scaleFactor
}
this.setPosition(newPosition)
},
// 画布平移 - 优化版本
pan(deltaX: number, deltaY: number) {
// 直接修改属性,避免创建新对象
this.position.x += deltaX;
this.position.y += deltaY;
},
// 重置画布
resetView() {
this.scale = 1
this.position = { x: 0, y: 0 }
}
}
})
总结
通过将 Vue3 的组件化理念与财务分析场景深度融合,我们构建了一个直观、可交互的杜邦分析可视化工具。其核心价值在于将复杂的财务公式拆解为可视化的节点与连线,并通过自动布局算法和状态管理确保了良好的用户体验与可维护性。该项目后续计划在 GitHub 上开源,对于想深入探索可视化搭建或AI应用落地的开发者而言,是一个不错的开源实战案例参考。如果你对这类技术实践感兴趣,欢迎在 云栈社区 的 前端框架/工程化 或 人工智能 板块交流探讨。