Files
waveform-analysis/ANNOTATION_DRAG_MIGRATION.md
2026-07-21 11:25:19 +08:00

4.6 KiB
Raw Blame History

标注拖动功能迁移指南

概述

版本更新添加了标注标签拖动功能,允许用户手动调整重叠标签的位置。此功能引入了接口变更和行为变化。

接口变更

WaveformAnnotation 接口新增字段

interface WaveformAnnotation {
  // ... 现有字段

  // 新增:标签偏移量(像素)
  labelOffsetX?: number
  labelOffsetY?: number
}

影响范围

  • 序列化/反序列化代码
  • 标注验证逻辑
  • 类型检查工具

迁移步骤

1. 更新序列化代码

如果您有过滤已知字段的序列化代码,请添加新字段:

// 修改前
function serializeAnnotation(annotation: WaveformAnnotation) {
  return {
    id: annotation.id,
    seriesId: annotation.seriesId,
    x: annotation.x,
    y: annotation.y,
    label: annotation.label,
  }
}

// 修改后
function serializeAnnotation(annotation: WaveformAnnotation) {
  return {
    id: annotation.id,
    seriesId: annotation.seriesId,
    x: annotation.x,
    y: annotation.y,
    label: annotation.label,
    // 添加新字段(如果存在)
    ...(annotation.labelOffsetX !== undefined && { labelOffsetX: annotation.labelOffsetX }),
    ...(annotation.labelOffsetY !== undefined && { labelOffsetY: annotation.labelOffsetY }),
  }
}

2. 更新验证逻辑

如果使用严格的对象键检查,请允许新字段:

// 修改前
const ALLOWED_KEYS = ['id', 'seriesId', 'x', 'y', 'label']

// 修改后
const ALLOWED_KEYS = ['id', 'seriesId', 'x', 'y', 'label', 'labelOffsetX', 'labelOffsetY']

3. 更新 JSON Schema如果使用

{
  "type": "object",
  "properties": {
    "id": { "type": "string" },
    "seriesId": { "type": "string" },
    "x": { "type": "number" },
    "y": { "type": "number" },
    "label": { "type": "string" },
    "labelOffsetX": { "type": "number" },
    "labelOffsetY": { "type": "number" }
  },
  "required": ["id", "seriesId", "x", "y"]
}

行为变更

1. 自动碰撞检测已移除

之前:标注标签会自动避免重叠,系统尝试 8 种放置位置(上/下/左/右及对角线)。

现在:标注标签默认放置在数据点上方,重叠时需要手动拖动调整。

原因:手动拖动提供了更精确的控制,避免了自动布局可能产生的意外位置。

迁移建议

  • 如果您的应用依赖自动避让,请在文档中告知用户现在需要手动调整
  • 可以通过监听 @move 事件来实现自定义的自动布局逻辑

2. 标注系列切换使用最近采样点

之前在编辑器中切换标注所属系列时Y 坐标通过插值计算。

现在Y 坐标捕捉到最近的实际采样点。

影响:对于阶梯线或稀疏数据,切换系列时 Y 值可能会跳变到不同的采样点位置。

用户体验建议

  • 在 UI 中添加提示:"切换系列将捕捉到最近的数据点"
  • 考虑在切换前保存原始坐标,提供"恢复"功能

向后兼容性

完全向后兼容

  • 新字段是可选的
  • 未设置偏移量时,行为与之前相同
  • 旧数据可以无需修改直接使用

可能不兼容的场景

  1. 严格类型检查:使用 Object.keys().length 检查精确键数量
  2. JSON Schema 验证additionalProperties: false 会拒绝新字段
  3. 序列化白名单:只序列化已知字段会丢失偏移量

测试建议

单元测试

describe('Annotation serialization', () => {
  it('should preserve labelOffset fields', () => {
    const annotation: WaveformAnnotation = {
      id: 'test',
      seriesId: 'series-1',
      x: 100,
      y: 50,
      label: 'Test',
      labelOffsetX: 10,
      labelOffsetY: -20,
    }

    const serialized = JSON.parse(JSON.stringify(annotation))
    expect(serialized.labelOffsetX).toBe(10)
    expect(serialized.labelOffsetY).toBe(-20)
  })

  it('should handle annotations without offsets', () => {
    const annotation: WaveformAnnotation = {
      id: 'test',
      seriesId: 'series-1',
      x: 100,
      y: 50,
      label: 'Test',
    }

    // 应该不会抛出错误
    expect(() => renderAnnotation(annotation)).not.toThrow()
  })
})

集成测试

  1. 加载旧数据文件,验证标注正常显示
  2. 拖动标注,验证偏移量正确保存
  3. 重新加载,验证偏移量持久化

支持

如有问题,请查看:

  • 示例代码:src/components/WaveformChart.test.ts (行 942-1020)
  • 类型定义:src/types/chart.ts (行 928-932)
  • API 文档:README.md

更新日期

2026-07-21