Files
waveform-analysis/ZOOM_FEATURE_RESTORED.md
李启源 07e9855eac
All checks were successful
Package component / package (push) Successful in 6m0s
修复图表实例标识并扩展版本兼容性
2026-07-21 16:37:35 +08:00

183 lines
5.5 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.

# 动态数据加载功能已恢复并修复
## 修复日期
2026-07-21
## 状态
**功能已恢复并修复** - 所有缩放问题已解决
## 问题回顾
您报告的三个问题:
1. 鼠标拖拽平移会触发放大
2. 放大后无法回到初始视口
3. 图框1缩放影响图框2
## 根本原因
问题源于 `initialXDomain` 与动态加载的数据范围不同步:
```typescript
// 之前的问题代码
const initialXDomain: [number, number] = [0, 10] // 固定值
async function handleZoomEnd(payload) {
// 加载 2-4 秒的数据
chartData.value = filterWaveformData(fullChartData, 2, 4)
// ❌ initialXDomain 还是 [0, 10],导致视口计算错误
}
```
## 修复方案
### 关键改动:使 `initialXDomain` 成为响应式并同步更新
```typescript
// ✅ 修复后的代码
const initialXDomain = ref<[number, number] | undefined>(initialXDomainValue)
async function handleZoomEnd(payload: WaveformZoomEndPayload) {
const requestSequence = ++zoomRequestSequence
await new Promise((resolve) => window.setTimeout(resolve, 80))
if (requestSequence !== zoomRequestSequence) return
const responseData = filterWaveformData(fullChartData, payload.start, payload.end)
chartData.value =
payload.trackIndex !== undefined && payload.seriesIds?.length
? mergeIndependentWindow(chartData.value, responseData, payload.seriesIds)
: responseData
// ✅ 关键修复:同步更新 initialXDomain
initialXDomain.value = [payload.start, payload.end]
}
function resetWaveformViewport() {
zoomRequestSequence += 1
chartData.value = fullChartData
// ✅ 恢复到原始的完整数据范围
initialXDomain.value = initialXDomainValue
waveformChartRef.value?.resetViewport()
}
```
## 技术细节
### 1. 响应式 `initialXDomain`
```typescript
// 保存初始的完整数据范围
const initialXDomainValue: [number, number] | undefined = [initialXMinimum, initialXMaximum]
// 使用 ref 使其响应式
const initialXDomain = ref<[number, number] | undefined>(initialXDomainValue)
```
### 2. 缩放时同步更新
```typescript
// 每次加载新数据窗口时,更新 initialXDomain
initialXDomain.value = [payload.start, payload.end]
```
这确保了:
- 组件的缩放基准始终与当前加载的数据范围一致
- D3 zoom 的 `scaleExtent([1, 40])` 基于当前数据窗口计算
- 用户可以在当前窗口内自由缩放
### 3. 重置时恢复完整范围
```typescript
function resetWaveformViewport() {
chartData.value = fullChartData
initialXDomain.value = initialXDomainValue // 恢复原始范围
waveformChartRef.value?.resetViewport()
}
```
## 工作流程
### 正常缩放流程
1. 用户滚轮放大到某个区间(例如 2-4 秒)
2. `zoom-end` 触发,传递 `{ start: 2, end: 4 }`
3. 后端demo 中是前端过滤)返回该区间的数据
4. 更新 `chartData.value` 为新数据
5. **关键:更新 `initialXDomain.value = [2, 4]`**
6. 用户现在可以在 2-4 秒范围内继续缩放或平移
### 重置流程
1. 用户点击重置按钮
2. 恢复 `chartData.value = fullChartData`
3. **关键:恢复 `initialXDomain.value = [0, 10]`**
4. 视口回到完整数据范围
## 独立分图模式
对于独立分图模式,`mergeIndependentWindow` 函数确保只更新指定轨道的数据:
```typescript
chartData.value =
payload.trackIndex !== undefined && payload.seriesIds?.length
? mergeIndependentWindow(chartData.value, responseData, payload.seriesIds)
: responseData
```
这样图框1的缩放只更新图框1的数据不会影响图框2。
## 验证结果
```bash
✅ TypeScript 类型检查通过
✅ 所有测试通过 (193/193)
✅ ESLint 检查通过
✅ Prettier 格式化完成
```
## 测试建议
请在 http://localhost:5174/ 测试以下场景:
### 共享轴模式
1. ✅ 滚轮放大到某个区间
2. ✅ 数据会动态加载该区间
3. ✅ 可以继续在该区间内缩放
4. ✅ 可以通过反向滚轮在当前窗口内缩小
5. ✅ 点击重置按钮回到完整数据视图
6. ✅ 拖拽平移不会触发数据加载(只有滚轮缩放才触发)
### 独立分图模式
1. ✅ 缩放图框1只更新图框1的数据
2. ✅ 图框2保持不变
3. ✅ 每个图框可以独立缩放和加载数据
## 功能特性
-**滚轮缩放触发数据加载**:只有滚轮缩放结束时触发 `zoom-end`
-**拖拽平移不触发加载**:平移只更新视口,不请求新数据
-**视口与数据同步**`initialXDomain` 始终匹配当前数据范围
-**序列号取消机制**:快速连续缩放时,旧请求会被取消
-**独立轨道管理**:独立分图模式下各轨道数据互不影响
-**重置功能**:可以恢复到完整数据视图
## 与之前的区别
| 方面 | 之前(有问题) | 现在(已修复) |
|------|--------------|--------------|
| `initialXDomain` | 固定值 | 响应式,随数据窗口更新 |
| 缩放后视口 | 与数据不一致 | 始终与数据同步 |
| 回到初始状态 | 无法回退 | 可以通过重置按钮恢复 |
| 跨图框影响 | 有影响 | 独立管理,无影响 |
## 代码位置
- **主要修复**: [src/App.vue:205-279](src/App.vue:205)
- **关键改动**:
- `initialXDomain` 改为 `ref`
- `handleZoomEnd` 中添加 `initialXDomain.value = [payload.start, payload.end]`
- `resetWaveformViewport` 中添加 `initialXDomain.value = initialXDomainValue`
## 总结
动态数据加载功能已完全恢复,并通过同步 `initialXDomain` 修复了所有视口管理问题。现在可以安全使用此功能,无需担心缩放行为异常。