From dda87f7508a780ee5035dd2949810c0adc15e0d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=90=AF=E6=BA=90?= Date: Mon, 17 Aug 2026 12:16:12 +0800 Subject: [PATCH] =?UTF-8?q?feat(annotation):=20=E4=BC=98=E5=8C=96=E6=A0=87?= =?UTF-8?q?=E6=B3=A8=E7=BC=96=E8=BE=91=E4=B8=8E=E4=BA=A4=E4=BA=92=E4=BD=93?= =?UTF-8?q?=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 标注编辑器支持时间输入与采样点吸附,完善标注交互、默认配色和示例图框样式。 --- README.md | 6 +- package.json | 2 +- src/App.test.ts | 5 +- src/App.vue | 2 +- src/components/WaveformChartView.vue | 11 +- .../annotation/WaveformAnnotationEditor.css | 139 ++++------------ .../annotation/WaveformAnnotationEditor.vue | 124 +++++++++----- src/components/annotation/components.test.ts | 154 +++++++++++++++--- src/components/annotation/markup.test.ts | 20 ++- src/components/annotation/markup.ts | 33 ++++ .../annotation/useWaveformChartAnnotations.ts | 65 ++++++-- src/components/core/constants.test.ts | 29 ++++ src/components/core/constants.ts | 40 ++++- .../annotationEditingAndReprojection.test.ts | 16 +- .../dataAndHoverPerformance.test.ts | 40 +++++ .../interactionAndAnnotationCreation.test.ts | 38 +++-- .../legendVisibility.test.ts | 12 +- .../multiAxisAndPagination.test.ts | 2 +- .../presentationMode.test.ts | 12 +- .../renderingStyles.test.ts | 2 +- .../xDomainStrategy.test.ts | 60 +++++++ 21 files changed, 597 insertions(+), 215 deletions(-) create mode 100644 src/components/core/constants.test.ts diff --git a/README.md b/README.md index c0f5c25..2d79b11 100644 --- a/README.md +++ b/README.md @@ -109,8 +109,8 @@ const data = ref({ | `pannable` | `boolean` | `false` | 空格拖拽平移开关 | | `minZoomSpan` | `number` | 未设置 | 最小缩放跨度,使用原始 X 数据单位 | | `minVisiblePoints` | `number` | `0` | 缩放后至少保留的不同 X 坐标数 | -| `initialXDomain` | `[number, number]` | 未设置 | 所有图框的初始 X 范围 | -| `initialXDomains` | `Record` | 未设置 | 按 track/series ID 配置初始范围 | +| `initialXDomain` | `[number, number]` | 未设置 | 所有图框的初始 X 范围(可超出数据,空白显示) | +| `initialXDomains` | `Record` | 未设置 | 按 track/series ID 配置初始范围(可超出数据) | | `xDomainStrategy` | `WaveformXDomainStrategy` | `{ type: 'data' }` | 自动 X 轴视口范围策略 | | `yDomain` | `[number, number]` | 未设置 | 所有波形的固定 Y 轴范围 | | `yDomains` | `Record` | 未设置 | 按 track/series ID 配置固定范围 | @@ -247,7 +247,7 @@ X 轴且包含多个轨道时使用按稳定 track ID 索引的 `yRanges`。平 调用方应处理加载失败的情况(网络错误、超时等),并保持旧数据或显示加载状态。生产环境建议使用 `AbortController` 取消过时的请求。 -`initialXDomain` 固定首次完整数据的 X 轴缩放边界,不要将它改成后端返回的当前窗口;独立图框有不同时间范围时,可通过 +`initialXDomain` 固定首次及重置时的 X 轴视口范围,不要将它改成后端返回的当前窗口;范围可以超出数据的实际时间,超出部分保留空白。独立图框有不同时间范围时,可通过 `initialXDomains` 按 track ID 或 series ID 分别配置。`minZoomSpan` 使用原始 X 数据单位, 可防止每次区间数据回填后重新累计放大。双击图框会 重置组件内部缩放并触发 `zoom-reset`;调用方应在事件中取消区间请求并恢复首次完整数据。 diff --git a/package.json b/package.json index ab26692..f12e3cd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "waveform-analysis", - "version": "0.1.36", + "version": "0.1.37", "main": "./dist/index.cjs", "module": "./dist/index.js", "types": "./dist/types/index.d.ts", diff --git a/src/App.test.ts b/src/App.test.ts index 0b45151..bcf783d 100644 --- a/src/App.test.ts +++ b/src/App.test.ts @@ -321,8 +321,9 @@ describe('App workspace layout', { timeout: 20_000 }, () => { const styleSelect = frameControls.findAllComponents(Select)[0] expect(colorPickers).toHaveLength(2) - expect(widthInput).toBeDefined() - expect(styleSelect).toBeDefined() + + const initialFrames = wrapper.findAll('.waveform-chart__plot-frame') + expect(initialFrames.length > 1 && initialFrames.every((frame) => frame.attributes('stroke-width') === '2')).toBe(true) colorPickers[0].vm.$emit('update:pureColor', 'rgba(220, 38, 38, 0.8)') colorPickers[1].vm.$emit('update:pureColor', 'rgba(14, 165, 233, 0.25)') diff --git a/src/App.vue b/src/App.vue index 6c7ae6c..3dfee86 100644 --- a/src/App.vue +++ b/src/App.vue @@ -32,7 +32,7 @@ const overlayMode = ref('single-axis') const rowCount = ref(4) const columnCount = ref(1) const frameBorderColor = ref('#1f2937') -const frameBorderWidth = ref(1) +const frameBorderWidth = ref(2) const frameBorderStyle = ref>('solid') const frameBackgroundColor = ref('rgba(255, 255, 255, 0)') const frameWatermarkVisible = ref(true) diff --git a/src/components/WaveformChartView.vue b/src/components/WaveformChartView.vue index 0008247..749b900 100644 --- a/src/components/WaveformChartView.vue +++ b/src/components/WaveformChartView.vue @@ -87,9 +87,11 @@ const { contextMenu, editorSeries, editorSeriesOptions, + timeError, confirmAnnotation, cancelAnnotation, changeDraftSeries, + changeDraftTime, editContextAnnotation, deleteContextAnnotation, chartHeight, @@ -98,6 +100,11 @@ const { setTitleMeasureElement, setSharedOverlayElement, } = toRefs(props.controller) + +function handleChartPointerLeave() { + pointerInsideChart.value = false + handlePointerLeave.value() +}