From 3692e21dbc823d706b5bca694f9ba1e7e2f932ff 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 10:14:44 +0800 Subject: [PATCH] =?UTF-8?q?feat(chart):=20=E5=A2=9E=E5=8A=A0=E7=82=AE?= =?UTF-8?q?=E5=8F=B7=E5=B9=B6=E4=BC=98=E5=8C=96=20Tooltip=20=E5=B1=95?= =?UTF-8?q?=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增 WaveformSeries.shotNo 字段,Tooltip 展示炮号及坐标信息,并同步示例与测试。 --- README.md | 8 +- package.json | 2 +- src/components/core/types.ts | 2 + .../interaction/WaveformTooltip.test.ts | 26 ++++-- .../interaction/WaveformTooltip.vue | 86 +++++++++---------- .../interaction/useWaveformHover.ts | 1 + .../compactAndSharedHover.test.ts | 8 +- .../dataAndHoverPerformance.test.ts | 4 +- src/core/data.test.ts | 22 +++++ src/core/data.ts | 1 + src/data/simulatedWaveforms.test.ts | 1 + src/data/simulatedWaveforms.ts | 8 +- src/types/data.ts | 3 + src/views/FixedYDomainDemo.vue | 2 + 14 files changed, 110 insertions(+), 64 deletions(-) diff --git a/README.md b/README.md index 091df4e..c0f5c25 100644 --- a/README.md +++ b/README.md @@ -163,8 +163,8 @@ const points: WaveformData = { const chartData: WaveformData = { kind: 'series', series: [ - { id: 'ch-a', name: '通道 A', trackId: 'group-1', data: samples }, - { id: 'ch-b', name: '通道 B', trackId: 'group-1', data: points }, + { id: 'ch-a', shotNo: '13300', name: '通道 A', trackId: 'group-1', data: samples }, + { id: 'ch-b', shotNo: '13300', name: '通道 B', trackId: 'group-1', data: points }, ], } ``` @@ -281,6 +281,9 @@ X 轴且包含多个轨道时使用按稳定 track ID 索引的 `yRanges`。平 多通道数据应为每个 `WaveformSeries` 提供稳定的 `id`。内部时间坐标始终使用秒, `timeUnit` 只控制坐标轴和 tooltip 的显示单位。 +Tooltip 每个系列按 `炮号:通道 (x:值 y:值)` 格式显示。`WaveformSeries.shotNo` 为空或未提供时, +炮号显示为“未配置炮号”;Tooltip 不显示单位和误差附加文本。 + ### 线型、点型与误差棒 每条序列可以独立设置连线方式、数据点符号和误差棒: @@ -288,6 +291,7 @@ X 轴且包含多个轨道时使用按稳定 track ID 索引的 `yRanges`。平 ```ts const series = { id: 'temperature', + shotNo: '13300', name: '温度', lineType: 'step-end', lineStyle: 'dashed', diff --git a/package.json b/package.json index 4684dd4..ab26692 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "waveform-analysis", - "version": "0.1.35", + "version": "0.1.36", "main": "./dist/index.cjs", "module": "./dist/index.js", "types": "./dist/types/index.d.ts", diff --git a/src/components/core/types.ts b/src/components/core/types.ts index e962798..6999b59 100644 --- a/src/components/core/types.ts +++ b/src/components/core/types.ts @@ -13,6 +13,7 @@ import type { NormalizedWaveformGridLineOptions } from './grid' */ export interface DisplaySeries { id: string + shotNo?: string trackId?: string name: string unit?: string @@ -63,6 +64,7 @@ export interface WaveformYAxisLayout { */ export interface HoveredSeriesPoint { id: string + shotNo?: string name: string unit?: string color: string diff --git a/src/components/interaction/WaveformTooltip.test.ts b/src/components/interaction/WaveformTooltip.test.ts index 4dbf71c..ce6cccd 100644 --- a/src/components/interaction/WaveformTooltip.test.ts +++ b/src/components/interaction/WaveformTooltip.test.ts @@ -80,7 +80,7 @@ describe('WaveformTooltip', () => { expect(tooltip.attributes('style')).toContain('max-width: 280px') }) - it('shows resolved asymmetric errors beside the hovered value', () => { + it('omits units and errors from the strict x/y value format', () => { const pointWithErrors = { x: 1, y: 12, error: 1, upperError: 2 } const wrapper = mount(WaveformTooltip, { props: { @@ -102,10 +102,12 @@ describe('WaveformTooltip', () => { }, }) - expect(wrapper.get('.waveform-tooltip__series small').text()).toBe('(+2 / -1)') + expect(wrapper.get('.waveform-tooltip__value').text()).toBe('(x:1 y:12)') + expect(wrapper.get('.waveform-tooltip__value').text()).not.toContain('C') + expect(wrapper.get('.waveform-tooltip__value').text()).not.toContain('+2') }) - it('keeps a formatted value and its unit in one value container', () => { + it('renders the configured shot number, channel, and formatted coordinates', () => { const hoveredPoint = { x: 1, y: -1405.4932 } const wrapper = mount(WaveformTooltip, { props: { @@ -117,6 +119,7 @@ describe('WaveformTooltip', () => { { trackIndex: 0, name: 'ENG8KJXAc(10001)', + shotNo: '炮 7', color: '#ffb43b', unit: 'A', point: hoveredPoint, @@ -127,26 +130,31 @@ describe('WaveformTooltip', () => { }, }) - expect(wrapper.get('.waveform-tooltip__value').text()).toBe('-1,405.4932 A') + expect(wrapper.get('.waveform-tooltip__series-label').text()).toBe('炮 7: ENG8KJXAc(10001)(A)') + expect(wrapper.get('.waveform-tooltip__value').text()).toBe('(x:1,000 y:-1,405.4932)') }) - it('formats tooltip time with at most four decimal places', () => { + it('renders each series row with the formatted x coordinate and series label', () => { const wrapper = mount(WaveformTooltip, { props: { visible: true, position: { x: 10, y: 10 }, timeUnit: 's', hoveredPoint: { x: 1.234567, y: 12 }, - seriesPoints: [], + seriesPoints: [ + { trackIndex: 0, name: '温度', color: '#f00', point: { x: 1.234567, y: 12 } }, + ], containerWidth: 400, containerHeight: 300, }, }) - expect(wrapper.get('.waveform-tooltip__time').text()).toBe('s: 1.2346') + expect(wrapper.find('.waveform-tooltip__time').exists()).toBe(false) + expect(wrapper.get('.waveform-tooltip__series-label').text()).toBe('未配置炮号: 温度') + expect(wrapper.get('.waveform-tooltip__value').text()).toBe('(x:1.2346 y:12)') }) - it('omits the error label when both resolved errors are zero', () => { + it('uses the fallback shot number when shotNo is blank', () => { const point = { x: 1, y: 12 } const wrapper = mount(WaveformTooltip, { props: { @@ -160,6 +168,6 @@ describe('WaveformTooltip', () => { }, }) - expect(wrapper.find('.waveform-tooltip__series small').exists()).toBe(false) + expect(wrapper.get('.waveform-tooltip__series-label').text()).toBe('未配置炮号: 温度') }) }) diff --git a/src/components/interaction/WaveformTooltip.vue b/src/components/interaction/WaveformTooltip.vue index 9bd7a5f..8ae6e45 100644 --- a/src/components/interaction/WaveformTooltip.vue +++ b/src/components/interaction/WaveformTooltip.vue @@ -1,12 +1,12 @@