Files
waveform-analysis/SYSTEM_REFACTORING.md
2026-07-20 15:35:19 +08:00

625 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# WaveformChart 按系统拆分重构完成报告
## 🎯 重构目标
将 WaveformChart 组件按功能系统重新组织,每个系统有独立的目录,提高代码的可维护性、可理解性和可扩展性。
---
## ✅ 完成情况
### 重构前的结构
```
src/components/
├── WaveformChart.vue # 主容器组件 (~1143 行)
├── WaveformToolbar.vue # 工具栏 (174 行)
├── WaveformEditor.vue # 编辑器 (149 行)
├── WaveformTooltip.vue # 悬浮提示 (111 行)
├── WaveformTrack.vue # 波形轨道 (317 行)
├── WaveformAnnotationLayer.vue # 标注层 (281 行)
├── waveform.ts # 类型定义
├── waveform-markup.ts # 标注相关类型和工具
└── index.ts # 导出
```
### 重构后的结构
```
src/components/
├── WaveformChart.vue # 主容器组件(协调各系统)
├── index.ts # 公共导出(保持向后兼容)
├── core/ # 核心系统
│ ├── constants.ts # 常量(颜色、边距等)
│ ├── types.ts # 共享类型定义
│ └── index.ts
├── data/ # 数据系统
│ ├── types.ts # 数据相关类型(重导出)
│ └── index.ts
├── rendering/ # 渲染系统
│ ├── WaveformTrack.vue # 波形轨道组件
│ └── index.ts
├── interaction/ # 交互系统
│ ├── WaveformToolbar.vue # 工具栏组件
│ ├── WaveformTooltip.vue # 悬浮提示组件
│ └── index.ts
├── annotation/ # 标注系统
│ ├── WaveformAnnotationLayer.vue # 标注渲染层
│ ├── WaveformEditor.vue # 标注编辑器
│ ├── markup.ts # 标注工具函数
│ ├── types.ts # 标注相关类型(重导出)
│ └── index.ts
├── waveform.ts # 向后兼容(重导出)
└── waveform-markup.ts # 向后兼容(重导出)
```
---
## 📦 各系统详情
### 1. Core System (核心系统)
**目录**: `src/components/core/`
**职责**: 提供共享的类型、常量
**文件**:
- `constants.ts` - 定义全局常量
- `channelColors` - 通道颜色数组
- `margin` - 图表边距
- `minimumHeight` - 最小高度
- `types.ts` - 核心类型定义
- `DisplaySeries` - 显示系列接口
- `HoveredSeriesPoint` - 悬浮点接口
- `TrackLayout` - 轨道布局接口
**导出**: `core/index.ts`
```typescript
export * from './constants'
export * from './types'
```
---
### 2. Data System (数据系统)
**目录**: `src/components/data/`
**职责**: 重导出数据相关类型和函数
**文件**:
- `types.ts` - 重导出 `src/types` 中的所有数据类型
- `WaveformData`, `WaveformSeries`, `WaveformPoint`
- `normalizeWaveformData`, `normalizeWaveformSeries` 函数
**导出**: `data/index.ts`
```typescript
export * from './types'
```
**说明**:
此系统作为桥接层,让组件内部可以通过相对路径 `../data/types` 导入类型,而不是 `../../types`,提高了代码的可读性。
---
### 3. Rendering System (渲染系统)
**目录**: `src/components/rendering/`
**职责**: 渲染波形轨道(网格、坐标轴、波形线)
**文件**:
- `WaveformTrack.vue` - 波形轨道组件 (317 行)
- 渲染网格(主要/次要刻度)
- 渲染 X/Y 坐标轴(使用 D3.js
- 渲染 Y 轴标签
- 渲染波形线
- 渲染十字线
- 渲染帧编号水印
- 独立模式下的交互覆盖层
**导出**: `rendering/index.ts`
```typescript
export { default as WaveformTrack } from './WaveformTrack.vue'
```
---
### 4. Interaction System (交互系统)
**目录**: `src/components/interaction/`
**职责**: 处理用户交互(工具栏、悬浮提示)
**文件**:
- `WaveformToolbar.vue` - 工具栏组件 (174 行)
- 交互模式切换(缩放、选择、标注等)
- 编辑/删除按钮
- 快捷键支持
- `WaveformTooltip.vue` - 悬浮提示组件 (111 行)
- 显示数据点信息
- 自动位置计算避免溢出
- 多系列数据展示
**导出**: `interaction/index.ts`
```typescript
export { default as WaveformToolbar } from './WaveformToolbar.vue'
export { default as WaveformTooltip } from './WaveformTooltip.vue'
```
---
### 5. Annotation System (标注系统)
**目录**: `src/components/annotation/`
**职责**: 管理标注和图形(创建、编辑、删除、渲染)
**文件**:
- `WaveformAnnotationLayer.vue` - 标注渲染层 (281 行)
- 渲染标注(箭头、文本框)
- 渲染图形(垂直线、时间区间)
- 渲染区间预览
- 交互响应(选择、编辑)
- `WaveformEditor.vue` - 标注编辑器 (149 行)
- 文本输入
- 确认/取消操作
- 键盘快捷键
- `markup.ts` - 标注工具函数
- `layoutAnnotationBox()` - 标注框布局计算
- `resolveAnnotationStyle()` - 标注样式解析
- `resolveShapeStyle()` - 图形样式解析
- `normalizeRangeShape()` - 区间标准化
- 其他辅助函数
- `types.ts` - 重导出标注相关类型
- `WaveformAnnotation`, `WaveformShape`
**导出**: `annotation/index.ts`
```typescript
export { default as WaveformAnnotationLayer } from './WaveformAnnotationLayer.vue'
export { default as WaveformEditor } from './WaveformEditor.vue'
export * from './markup'
export * from './types'
```
---
## 🔄 主组件更新
### WaveformChart.vue 导入变化
**重构前**:
```typescript
import WaveformToolbar from './WaveformToolbar.vue'
import WaveformEditor from './WaveformEditor.vue'
import WaveformTooltip from './WaveformTooltip.vue'
import WaveformAnnotationLayer from './WaveformAnnotationLayer.vue'
import WaveformTrack from './WaveformTrack.vue'
import { normalizeWaveformSeries, type WaveformData, ... } from './waveform'
import { layoutAnnotationBox, resolveAnnotationStyle, ... } from './waveform-markup'
const channelColors = [...]
const margin = { top: 18, right: 24, bottom: 52, left: 64 }
const minimumHeight = 180
```
**重构后**:
```typescript
// 从各系统导入
import { WaveformToolbar, WaveformTooltip } from './interaction'
import { WaveformEditor, WaveformAnnotationLayer } from './annotation'
import { WaveformTrack } from './rendering'
import { normalizeWaveformSeries, type WaveformData, ... } from './data/types'
import { layoutAnnotationBox, resolveAnnotationStyle, ... } from './annotation/markup'
import { channelColors, margin as chartMargin, minimumHeight as chartMinimumHeight } from './core/constants'
// 使用导入的常量
const margin = chartMargin
const minimumHeight = chartMinimumHeight
```
---
## 🌉 向后兼容性
### 保持旧的导入路径可用
为了确保不破坏现有代码,保留了原有的导入路径:
**1. `waveform.ts` - 向后兼容文件**
```typescript
// 重新导出所有类型和函数
export type { ... } from '../types'
export { normalizeWaveformData, normalizeWaveformSeries } from '../core'
```
**2. `waveform-markup.ts` - 向后兼容文件**
```typescript
// 重新导出标注相关的所有内容
export * from './annotation/markup'
export type * from './annotation/types'
```
**3. `index.ts` - 更新公共导出**
```typescript
export { default as WaveformChart } from './WaveformChart.vue'
// 从新路径导出类型(透明给外部使用者)
export type { ... } from './data/types'
// 可选:导出各系统的组件
export { WaveformToolbar, WaveformTooltip } from './interaction'
export { WaveformAnnotationLayer, WaveformEditor } from './annotation'
export { WaveformTrack } from './rendering'
```
### 使用示例
**外部使用者(完全兼容)**:
```typescript
// 旧的导入方式仍然有效
import { WaveformChart, type WaveformData } from '@/components'
// 新的导入方式(推荐)
import { WaveformChart } from '@/components'
import type { WaveformData } from '@/components'
// 高级用户可以直接使用子系统组件
import { WaveformToolbar, WaveformTooltip } from '@/components/interaction'
import { WaveformAnnotationLayer } from '@/components/annotation'
```
---
## 📊 重构收益
### 1. 可维护性 ⭐⭐⭐⭐⭐
**按系统定位代码**:
- 需要修改工具栏?→ 直接到 `interaction/` 目录
- 需要修改标注渲染?→ 直接到 `annotation/` 目录
- 需要修改轨道渲染?→ 直接到 `rendering/` 目录
**职责清晰**:
- 每个系统有独立的目录和明确的职责
- 减少了跨系统的耦合
- 降低了修改的影响范围
### 2. 可理解性 ⭐⭐⭐⭐⭐
**目录即文档**:
```
interaction/ → 我是交互系统,负责用户交互
annotation/ → 我是标注系统,负责标注管理
rendering/ → 我是渲染系统,负责波形绘制
core/ → 我是核心系统,提供共享资源
data/ → 我是数据系统,处理数据
```
**新人友好**:
- 从目录结构就能快速理解系统架构
- 相关代码放在一起,容易理解上下文
- 不需要在一个大文件中上下滚动
### 3. 可扩展性 ⭐⭐⭐⭐⭐
**添加新功能**:
- 添加新的交互模式?→ 在 `interaction/` 下添加
- 添加新的标注类型?→ 在 `annotation/` 下添加
- 添加新的渲染效果?→ 在 `rendering/` 下添加
**替换实现**:
- 可以替换整个系统而不影响其他部分
- 例如:用 Canvas 替换 SVG 渲染,只需修改 `rendering/` 目录
**插件化潜力**:
- 各系统可以作为独立插件使用
- 方便构建自定义版本(例如:只要渲染,不要标注)
### 4. 可测试性 ⭐⭐⭐⭐⭐
**独立测试**:
```typescript
// 可以单独测试各系统的组件
describe('WaveformToolbar', () => { ... })
describe('WaveformAnnotationLayer', () => { ... })
describe('WaveformTrack', () => { ... })
```
**未来可以添加**:
- `interaction/useInteraction.test.ts` - 测试交互逻辑
- `annotation/useAnnotation.test.ts` - 测试标注管理
- `rendering/WaveformTrack.test.ts` - 测试轨道渲染
---
## 📈 代码统计
| 指标 | 数值 |
| ---------------------- | -------------------------------------- |
| **系统数量** | 5 个 |
| **Core System** | 3 个文件 |
| **Data System** | 2 个文件 |
| **Rendering System** | 2 个文件 (1 组件) |
| **Interaction System** | 3 个文件 (2 组件) |
| **Annotation System** | 5 个文件 (2 组件) |
| **向后兼容文件** | 2 个 (waveform.ts, waveform-markup.ts) |
| **总文件数** | 17 个 |
---
## ✅ 验证结果
### 所有检查通过
```bash
✅ TypeScript 类型检查通过
✅ ESLint 代码规范通过
✅ 所有单元测试通过 (24/24)
✅ 向后兼容性验证通过
```
### 测试详情
```
Test Files 1 passed (1)
Tests 24 passed (24)
Duration 1.74s
```
所有现有测试无需修改即可通过,证明重构保持了完全的向后兼容性。
---
## 🚀 后续优化建议
### 1. 提取组合式函数 ⭐⭐⭐⭐⭐
将主组件中的逻辑提取为组合式函数:
```typescript
// zoom/useZoom.ts
export function useZoom(options: ZoomOptions) {
const sharedTransform = shallowRef<ZoomTransform>(zoomIdentity)
const independentTransforms = shallowRef<ZoomTransform[]>([])
// ...
return { sharedTransform, independentTransforms, ... }
}
// interaction/useHover.ts
export function useHover(options: HoverOptions) {
const hoveredSeriesPoints = ref<HoveredSeriesPoint[]>([])
const hoverPosition = ref({ x: 0, y: 0 })
// ...
return { hoveredSeriesPoints, hoverPosition, ... }
}
// annotation/useAnnotation.ts
export function useAnnotation(options: AnnotationOptions) {
const selection = ref<WaveformMarkupSelection>(null)
const editingDraft = ref<EditingDraft | null>(null)
// ...
return { selection, editingDraft, ... }
}
```
然后在主组件中使用:
```typescript
// WaveformChart.vue
const { sharedTransform, independentTransforms, ... } = useZoom(...)
const { hoveredSeriesPoints, hoverPosition, ... } = useHover(...)
const { selection, editingDraft, ... } = useAnnotation(...)
```
**收益**:
- 逻辑更清晰,职责更单一
- 易于测试(不需要挂载组件)
- 可复用在其他组件中
### 2. 添加系统级文档 ⭐⭐⭐⭐
为每个系统添加 README.md
```
interaction/
├── README.md # 交互系统说明
├── WaveformToolbar.vue
├── WaveformTooltip.vue
└── index.ts
annotation/
├── README.md # 标注系统说明
├── WaveformAnnotationLayer.vue
├── WaveformEditor.vue
├── markup.ts
└── index.ts
```
### 3. 创建系统级测试 ⭐⭐⭐⭐
```
interaction/
├── WaveformToolbar.test.ts
├── WaveformTooltip.test.ts
└── useInteraction.test.ts
annotation/
├── WaveformAnnotationLayer.test.ts
├── WaveformEditor.test.ts
├── markup.test.ts
└── useAnnotation.test.ts
```
### 4. 进一步拆分大组件 ⭐⭐⭐
**WaveformTrack.vue** (317 行) 可以拆分为:
```
rendering/
├── WaveformTrack.vue # 轨道容器
├── Grid.vue # 网格组件
├── Axis.vue # 坐标轴组件
├── WaveformLine.vue # 波形线组件
└── Crosshair.vue # 十字线组件
```
**WaveformAnnotationLayer.vue** (281 行) 可以拆分为:
```
annotation/
├── WaveformAnnotationLayer.vue # 标注层容器
├── AnnotationItem.vue # 单个标注
├── ShapeItem.vue # 单个图形
└── RangePreview.vue # 区间预览
```
---
## 🎯 重构对比
### 重构前
```
components/
├── [7 个组件文件平铺]
├── [2 个 TS 文件平铺]
└── index.ts
❌ 文件平铺,职责不清晰
❌ 难以定位相关代码
❌ 新人需要猜测文件关系
```
### 重构后
```
components/
├── core/ # 核心系统
├── data/ # 数据系统
├── rendering/ # 渲染系统
├── interaction/ # 交互系统
├── annotation/ # 标注系统
└── index.ts # 统一导出
✅ 按系统组织,职责清晰
✅ 易于定位相关代码
✅ 从目录结构就能理解架构
✅ 保持向后兼容
```
---
## 📝 迁移指南
### 对外部使用者
**无需任何修改!**
所有原有的导入方式都保持兼容:
```typescript
// ✅ 原有代码继续工作
import { WaveformChart, type WaveformData } from '@/components'
```
### 对内部开发者
**推荐使用新的导入路径**
```typescript
// ✅ 新的推荐方式(更清晰)
import { WaveformToolbar } from './interaction'
import { WaveformAnnotationLayer } from './annotation'
import { WaveformTrack } from './rendering'
import type { WaveformData } from './data/types'
import { channelColors } from './core/constants'
```
### 添加新功能时
**遵循系统划分原则**
1. 确定功能属于哪个系统
2. 在对应系统目录下创建文件
3. 在系统的 `index.ts` 中导出
4. 在主组件中导入使用
---
## 🎉 总结
### 完成情况
**系统拆分成功完成**
- 创建 5 个功能系统目录
- 移动 5 个组件到对应系统
- 提取共享常量和类型
- 保持完全向后兼容
- 所有测试通过
### 核心价值
| 维度 | 改善 |
| -------- | ----------------------------- |
| 可维护性 | ✅ 按系统组织,易于定位和修改 |
| 可理解性 | ✅ 目录即文档,架构清晰 |
| 可扩展性 | ✅ 易于添加新功能和替换实现 |
| 可测试性 | ✅ 系统独立,支持单独测试 |
| 向后兼容 | ✅ 完全兼容现有代码 |
### 项目里程碑
```
2026-07-17: 工具栏和编辑器组件拆分完成
2026-07-18: Tooltip、Track、AnnotationLayer 拆分完成
2026-07-18: 按系统重新组织完成 ✅
```
---
**完成时间**: 2026-07-18
**影响范围**: 重组 `src/components/` 目录结构
**破坏性变更**: 无
**向后兼容**: ✅ 完全兼容
**测试结果**: ✅ 24/24 通过
**重构方式**: 渐进式、非破坏性