waveform-analysis 0.1.37 → 0.1.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -30
- package/package.json +1 -1
- package/src/App.test.ts +2 -2
- package/src/components/waveformChartCases/legendVisibility.test.ts +34 -17
- package/src/components/waveformChartCases/multiAxisAndPagination.test.ts +29 -3
- package/src/components/waveformChartCases/presentationMode.test.ts +16 -3
- package/src/data/simulatedWaveforms.test.ts +7 -3
- package/src/data/simulatedWaveforms.ts +14 -1
- package/src/test/waveformChart.ts +12 -0
package/README.md
CHANGED
|
@@ -96,37 +96,37 @@ const data = ref<WaveformData>({
|
|
|
96
96
|
|
|
97
97
|
### Props
|
|
98
98
|
|
|
99
|
-
| Prop | 类型 | 默认值 | 说明
|
|
100
|
-
| --------------------------------- | ------------------------------------------- | ------------------------------------------------------- |
|
|
101
|
-
| `data` | `WaveformData` | 必填 | 波形数据
|
|
102
|
-
| `displayMode` | `'independent' \| 'separated' \| 'compact'` | `'independent'` | 图框布局
|
|
103
|
-
| `overlayMode` | `'single-axis' \| 'multi-axis'` | `'single-axis'` | 叠加曲线的 Y 轴模式
|
|
104
|
-
| `timeUnit` | `'s' \| 'ms'` | `'ms'` | 坐标轴和 tooltip 展示单位
|
|
105
|
-
| `xLabel` / `yLabel` | `string` | `时间(timeUnit)` / `'幅值'` | 坐标轴名称
|
|
106
|
-
| `lineColor` | `string` | `'#0960bd'` | 单波形默认颜色
|
|
107
|
-
| `width` / `height` | `number` | 自适应 | 组件总尺寸,单位为 CSS 像素
|
|
108
|
-
| `zoomable` / `showTooltip` | `boolean` | `true` / `true` | 缩放和数值 tooltip 开关
|
|
109
|
-
| `pannable` | `boolean` | `false` | 空格拖拽平移开关
|
|
110
|
-
| `minZoomSpan` | `number` | 未设置 | 最小缩放跨度,使用原始 X 数据单位
|
|
111
|
-
| `minVisiblePoints` | `number` | `0` | 缩放后至少保留的不同 X 坐标数
|
|
99
|
+
| Prop | 类型 | 默认值 | 说明 |
|
|
100
|
+
| --------------------------------- | ------------------------------------------- | ------------------------------------------------------- | --------------------------------------------- |
|
|
101
|
+
| `data` | `WaveformData` | 必填 | 波形数据 |
|
|
102
|
+
| `displayMode` | `'independent' \| 'separated' \| 'compact'` | `'independent'` | 图框布局 |
|
|
103
|
+
| `overlayMode` | `'single-axis' \| 'multi-axis'` | `'single-axis'` | 叠加曲线的 Y 轴模式 |
|
|
104
|
+
| `timeUnit` | `'s' \| 'ms'` | `'ms'` | 坐标轴和 tooltip 展示单位 |
|
|
105
|
+
| `xLabel` / `yLabel` | `string` | `时间(timeUnit)` / `'幅值'` | 坐标轴名称 |
|
|
106
|
+
| `lineColor` | `string` | `'#0960bd'` | 单波形默认颜色 |
|
|
107
|
+
| `width` / `height` | `number` | 自适应 | 组件总尺寸,单位为 CSS 像素 |
|
|
108
|
+
| `zoomable` / `showTooltip` | `boolean` | `true` / `true` | 缩放和数值 tooltip 开关 |
|
|
109
|
+
| `pannable` | `boolean` | `false` | 空格拖拽平移开关 |
|
|
110
|
+
| `minZoomSpan` | `number` | 未设置 | 最小缩放跨度,使用原始 X 数据单位 |
|
|
111
|
+
| `minVisiblePoints` | `number` | `0` | 缩放后至少保留的不同 X 坐标数 |
|
|
112
112
|
| `initialXDomain` | `[number, number]` | 未设置 | 所有图框的初始 X 范围(可超出数据,空白显示) |
|
|
113
113
|
| `initialXDomains` | `Record<string, [number, number]>` | 未设置 | 按 track/series ID 配置初始范围(可超出数据) |
|
|
114
|
-
| `xDomainStrategy` | `WaveformXDomainStrategy` | `{ type: 'data' }` | 自动 X 轴视口范围策略
|
|
115
|
-
| `yDomain` | `[number, number]` | 未设置 | 所有波形的固定 Y 轴范围
|
|
116
|
-
| `yDomains` | `Record<string, [number, number]>` | 未设置 | 按 track/series ID 配置固定范围
|
|
117
|
-
| `grid` | `WaveformGridOptions` | `{ rowCount: 2, columnCount: 1, showPagination: true }` | 网格和分页
|
|
118
|
-
| `axes` | `WaveformAxesOptions` | 轴线均显示 | X/Y 轴基线显隐与 X 轴 label 格式化
|
|
119
|
-
| `rendering` | `WaveformRenderingOptions` | `{}` | 降采样与点/误差棒间距
|
|
120
|
-
| `title` / `legend` / `frameStyle` | 对应公开类型 | 未设置 | 标题、图例和图框样式
|
|
121
|
-
| `frameNumber` | `string \| number` | 未设置 | 图框水印内容
|
|
122
|
-
| `zeroLine` | `WaveformZeroLineOptions` | `{ visible: false }` | 零值参考线显隐与样式
|
|
123
|
-
| `cleanView` | `boolean` | `false` | 保留波形、图框和刻度的净图模式
|
|
124
|
-
| `presentationMode` | `boolean` | `false` | 禁用绘图区交互的展示模式
|
|
125
|
-
| `annotations` | `WaveformAnnotation[]` | `[]` | 受控标注数据
|
|
126
|
-
| `annotationsVisible` | `boolean` | `true` | 标注图层显隐
|
|
127
|
-
| `interactionMode` | `'zoom' \| 'annotation'` | `'zoom'` | 左键交互模式
|
|
128
|
-
| `hiddenSeriesIds` | `string[]` | 未设置 | 受控隐藏系列 ID
|
|
129
|
-
| `defaultHiddenSeriesIds` | `string[]` | `[]` | 非受控模式的初始隐藏系列
|
|
114
|
+
| `xDomainStrategy` | `WaveformXDomainStrategy` | `{ type: 'data' }` | 自动 X 轴视口范围策略 |
|
|
115
|
+
| `yDomain` | `[number, number]` | 未设置 | 所有波形的固定 Y 轴范围 |
|
|
116
|
+
| `yDomains` | `Record<string, [number, number]>` | 未设置 | 按 track/series ID 配置固定范围 |
|
|
117
|
+
| `grid` | `WaveformGridOptions` | `{ rowCount: 2, columnCount: 1, showPagination: true }` | 网格和分页 |
|
|
118
|
+
| `axes` | `WaveformAxesOptions` | 轴线均显示 | X/Y 轴基线显隐与 X 轴 label 格式化 |
|
|
119
|
+
| `rendering` | `WaveformRenderingOptions` | `{}` | 降采样与点/误差棒间距 |
|
|
120
|
+
| `title` / `legend` / `frameStyle` | 对应公开类型 | 未设置 | 标题、图例和图框样式 |
|
|
121
|
+
| `frameNumber` | `string \| number` | 未设置 | 图框水印内容 |
|
|
122
|
+
| `zeroLine` | `WaveformZeroLineOptions` | `{ visible: false }` | 零值参考线显隐与样式 |
|
|
123
|
+
| `cleanView` | `boolean` | `false` | 保留波形、图框和刻度的净图模式 |
|
|
124
|
+
| `presentationMode` | `boolean` | `false` | 禁用绘图区交互的展示模式 |
|
|
125
|
+
| `annotations` | `WaveformAnnotation[]` | `[]` | 受控标注数据 |
|
|
126
|
+
| `annotationsVisible` | `boolean` | `true` | 标注图层显隐 |
|
|
127
|
+
| `interactionMode` | `'zoom' \| 'annotation'` | `'zoom'` | 左键交互模式 |
|
|
128
|
+
| `hiddenSeriesIds` | `string[]` | 未设置 | 受控隐藏系列 ID |
|
|
129
|
+
| `defaultHiddenSeriesIds` | `string[]` | `[]` | 非受控模式的初始隐藏系列 |
|
|
130
130
|
|
|
131
131
|
所有公开类型均可从包入口导入,例如 `WaveformData`、`WaveformSeries`、
|
|
132
132
|
`WaveformAnnotation`、`WaveformLineStyle`、`WaveformRenderingOptions`、
|
|
@@ -415,7 +415,8 @@ Demo 左侧控制面板提供标题实时预览,可配置标题名称、显隐
|
|
|
415
415
|
|
|
416
416
|
### 图例与曲线显隐
|
|
417
417
|
|
|
418
|
-
|
|
418
|
+
每个图框独立管理自己的图例:图框内有两条或更多曲线时显示图例,只有一条曲线时不显示。
|
|
419
|
+
`legend.backgroundColor` 设置图例的背景颜色。该字段接受任意有效 CSS 颜色值,
|
|
419
420
|
可通过 `rgba(...)` 或 `hsla(...)` 中的 alpha 通道调整透明度:
|
|
420
421
|
|
|
421
422
|
```vue
|
package/package.json
CHANGED
package/src/App.test.ts
CHANGED
|
@@ -235,7 +235,7 @@ describe('App workspace layout', { timeout: 20_000 }, () => {
|
|
|
235
235
|
tracks.map((track) =>
|
|
236
236
|
track.findAll('.waveform-chart__series').map((item) => item.attributes('data-series-name')),
|
|
237
237
|
),
|
|
238
|
-
).toEqual([['正弦基波'], ['谐波扰动'], ['阻尼振荡'], ['阶跃响应']])
|
|
238
|
+
).toEqual([['正弦基波'], ['谐波扰动', '谐波对比'], ['阻尼振荡'], ['阶跃响应']])
|
|
239
239
|
expect(
|
|
240
240
|
tracks
|
|
241
241
|
.slice(1)
|
|
@@ -253,6 +253,7 @@ describe('App workspace layout', { timeout: 20_000 }, () => {
|
|
|
253
253
|
expect(simulatedSeries.map((item) => item.name)).toEqual([
|
|
254
254
|
'正弦基波',
|
|
255
255
|
'谐波扰动',
|
|
256
|
+
'谐波对比',
|
|
256
257
|
'阻尼振荡',
|
|
257
258
|
'阶跃响应',
|
|
258
259
|
'脉冲响应',
|
|
@@ -321,7 +322,6 @@ describe('App workspace layout', { timeout: 20_000 }, () => {
|
|
|
321
322
|
const styleSelect = frameControls.findAllComponents(Select)[0]
|
|
322
323
|
|
|
323
324
|
expect(colorPickers).toHaveLength(2)
|
|
324
|
-
|
|
325
325
|
const initialFrames = wrapper.findAll('.waveform-chart__plot-frame')
|
|
326
326
|
expect(initialFrames.length > 1 && initialFrames.every((frame) => frame.attributes('stroke-width') === '2')).toBe(true)
|
|
327
327
|
|
|
@@ -16,13 +16,30 @@ function annotationEditorExists() {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
describe('WaveformChart', () => {
|
|
19
|
+
it('shows legends when a track contains at least two series', async () => {
|
|
20
|
+
const oneSeries = visibilitySeries()
|
|
21
|
+
if (oneSeries.kind === 'series') oneSeries.series = oneSeries.series.slice(0, 1)
|
|
22
|
+
const withoutLegend = await mountSizedChart(oneSeries, {
|
|
23
|
+
grid: { rowCount: 1, columnCount: 1 },
|
|
24
|
+
})
|
|
25
|
+
expect(withoutLegend.findAll('.waveform-chart__legend')).toHaveLength(0)
|
|
26
|
+
|
|
27
|
+
const twoSeries = visibilitySeries()
|
|
28
|
+
if (twoSeries.kind === 'series') twoSeries.series = twoSeries.series.slice(0, 2)
|
|
29
|
+
const withLegend = await mountSizedChart(twoSeries, {
|
|
30
|
+
grid: { rowCount: 1, columnCount: 1 },
|
|
31
|
+
})
|
|
32
|
+
expect(withLegend.findAll('.waveform-chart__legend')).toHaveLength(1)
|
|
33
|
+
expect(withLegend.find('.waveform-chart__legend').attributes('data-position')).toBe('top-right')
|
|
34
|
+
})
|
|
35
|
+
|
|
19
36
|
it('resolves legend positions by stable track id across pages', async () => {
|
|
20
37
|
const wrapper = await mountSizedChart(
|
|
21
38
|
{
|
|
22
39
|
kind: 'series',
|
|
23
|
-
series: Array.from({ length:
|
|
40
|
+
series: Array.from({ length: 12 }, (_, index) => ({
|
|
24
41
|
id: `series-${index}`,
|
|
25
|
-
trackId: `frame-${Math.floor(index /
|
|
42
|
+
trackId: `frame-${Math.floor(index / 3)}`,
|
|
26
43
|
name: `series ${index}`,
|
|
27
44
|
data: {
|
|
28
45
|
kind: 'points' as const,
|
|
@@ -75,9 +92,9 @@ describe('WaveformChart', () => {
|
|
|
75
92
|
const wrapper = await mountSizedChart(
|
|
76
93
|
{
|
|
77
94
|
kind: 'series',
|
|
78
|
-
series: Array.from({ length:
|
|
95
|
+
series: Array.from({ length: 6 }, (_, index) => ({
|
|
79
96
|
id: `series-${index}`,
|
|
80
|
-
trackId: `frame-${Math.floor(index /
|
|
97
|
+
trackId: `frame-${Math.floor(index / 3)}`,
|
|
81
98
|
name: `series ${index}`,
|
|
82
99
|
data: {
|
|
83
100
|
kind: 'points',
|
|
@@ -112,7 +129,7 @@ describe('WaveformChart', () => {
|
|
|
112
129
|
})
|
|
113
130
|
|
|
114
131
|
const items = wrapper.findAll('.waveform-chart__legend-item')
|
|
115
|
-
expect(items).toHaveLength(
|
|
132
|
+
expect(items).toHaveLength(3)
|
|
116
133
|
expect(items.every((item) => item.attributes('disabled') !== undefined)).toBe(true)
|
|
117
134
|
expect(wrapper.get('.waveform-legend__panel').classes()).not.toContain(
|
|
118
135
|
'waveform-legend__panel--interactive',
|
|
@@ -128,7 +145,7 @@ describe('WaveformChart', () => {
|
|
|
128
145
|
overlayMode: 'multi-axis',
|
|
129
146
|
})
|
|
130
147
|
|
|
131
|
-
expect(wrapper.findAll('.waveform-chart__axis--y')).toHaveLength(
|
|
148
|
+
expect(wrapper.findAll('.waveform-chart__axis--y')).toHaveLength(3)
|
|
132
149
|
expect(wrapper.find('[data-annotation-id="high-note"]').exists()).toBe(true)
|
|
133
150
|
const annotationLayer = wrapper.get('.waveform-annotation-layer').element
|
|
134
151
|
const legendLayer = wrapper.get('.waveform-chart__legend-layer').element
|
|
@@ -143,8 +160,8 @@ describe('WaveformChart', () => {
|
|
|
143
160
|
|
|
144
161
|
expect(
|
|
145
162
|
wrapper.findAll('.waveform-chart__line').map((line) => line.attributes('data-series-id')),
|
|
146
|
-
).toEqual(['low'])
|
|
147
|
-
expect(wrapper.findAll('.waveform-chart__axis--y')).toHaveLength(
|
|
163
|
+
).toEqual(['low', 'mid'])
|
|
164
|
+
expect(wrapper.findAll('.waveform-chart__axis--y')).toHaveLength(2)
|
|
148
165
|
expect(wrapper.find('[data-annotation-id="high-note"]').exists()).toBe(false)
|
|
149
166
|
expect(wrapper.findAll('.waveform-chart__legend-item')[1].classes()).toContain('is-hidden')
|
|
150
167
|
expect(wrapper.findAll('.waveform-chart__legend-item')[1].attributes('aria-pressed')).toBe(
|
|
@@ -170,12 +187,12 @@ describe('WaveformChart', () => {
|
|
|
170
187
|
)
|
|
171
188
|
flushAnimationFrames()
|
|
172
189
|
await flushPromises()
|
|
173
|
-
expect(wrapper.findAll('.waveform-chart__tooltip-series')).toHaveLength(
|
|
190
|
+
expect(wrapper.findAll('.waveform-chart__tooltip-series')).toHaveLength(2)
|
|
174
191
|
expect(wrapper.get('.waveform-chart__tooltip-series').text()).toContain('低量程')
|
|
175
192
|
|
|
176
193
|
await wrapper.findAll('.waveform-chart__legend-item')[1].trigger('click')
|
|
177
194
|
await flushPromises()
|
|
178
|
-
expect(wrapper.findAll('.waveform-chart__line')).toHaveLength(
|
|
195
|
+
expect(wrapper.findAll('.waveform-chart__line')).toHaveLength(3)
|
|
179
196
|
expect(wrapper.find('[data-annotation-id="high-note"]').exists()).toBe(true)
|
|
180
197
|
expect(wrapper.emitted('series-visibility-change')?.at(-1)).toEqual([
|
|
181
198
|
{ seriesId: 'high', visible: true, hiddenSeriesIds: [] },
|
|
@@ -191,20 +208,20 @@ describe('WaveformChart', () => {
|
|
|
191
208
|
|
|
192
209
|
expect(
|
|
193
210
|
wrapper.findAll('.waveform-chart__line').map((line) => line.attributes('data-series-id')),
|
|
194
|
-
).toEqual(['low'])
|
|
211
|
+
).toEqual(['low', 'mid'])
|
|
195
212
|
await wrapper.findAll('.waveform-chart__legend-item')[0].trigger('click')
|
|
196
213
|
expect(wrapper.emitted('update:hidden-series-ids')?.at(-1)).toEqual([
|
|
197
214
|
['high', 'temporarily-absent', 'low'],
|
|
198
215
|
])
|
|
199
216
|
expect(
|
|
200
217
|
wrapper.findAll('.waveform-chart__line').map((line) => line.attributes('data-series-id')),
|
|
201
|
-
).toEqual(['low'])
|
|
218
|
+
).toEqual(['low', 'mid'])
|
|
202
219
|
|
|
203
220
|
await wrapper.setProps({ hiddenSeriesIds: ['low'] })
|
|
204
221
|
await flushPromises()
|
|
205
222
|
expect(
|
|
206
223
|
wrapper.findAll('.waveform-chart__line').map((line) => line.attributes('data-series-id')),
|
|
207
|
-
).toEqual(['high'])
|
|
224
|
+
).toEqual(['high', 'mid'])
|
|
208
225
|
})
|
|
209
226
|
|
|
210
227
|
it('retains uncontrolled visibility by stable ID and clears removed IDs', async () => {
|
|
@@ -223,7 +240,7 @@ describe('WaveformChart', () => {
|
|
|
223
240
|
await flushPromises()
|
|
224
241
|
expect(
|
|
225
242
|
wrapper.findAll('.waveform-chart__line').map((line) => line.attributes('data-series-id')),
|
|
226
|
-
).toEqual(['low'])
|
|
243
|
+
).toEqual(['mid', 'low'])
|
|
227
244
|
|
|
228
245
|
await wrapper.setProps({
|
|
229
246
|
data: {
|
|
@@ -234,12 +251,12 @@ describe('WaveformChart', () => {
|
|
|
234
251
|
await flushPromises()
|
|
235
252
|
await wrapper.setProps({ data: original })
|
|
236
253
|
await flushPromises()
|
|
237
|
-
expect(wrapper.findAll('.waveform-chart__line')).toHaveLength(
|
|
254
|
+
expect(wrapper.findAll('.waveform-chart__line')).toHaveLength(3)
|
|
238
255
|
})
|
|
239
256
|
|
|
240
257
|
it('keeps a recoverable legend and stops chart interaction when every series is hidden', async () => {
|
|
241
258
|
const wrapper = await mountSizedChart(visibilitySeries(), {
|
|
242
|
-
defaultHiddenSeriesIds: ['low', 'high'],
|
|
259
|
+
defaultHiddenSeriesIds: ['low', 'high', 'mid'],
|
|
243
260
|
grid: { rowCount: 1, columnCount: 1 },
|
|
244
261
|
legend: { interactive: true },
|
|
245
262
|
overlayMode: 'multi-axis',
|
|
@@ -248,7 +265,7 @@ describe('WaveformChart', () => {
|
|
|
248
265
|
expect(wrapper.findAll('.waveform-chart__line')).toHaveLength(0)
|
|
249
266
|
expect(wrapper.findAll('.waveform-chart__axis')).toHaveLength(0)
|
|
250
267
|
expect(wrapper.findAll('.waveform-chart__overlay')).toHaveLength(0)
|
|
251
|
-
expect(wrapper.findAll('.waveform-chart__legend-item')).toHaveLength(
|
|
268
|
+
expect(wrapper.findAll('.waveform-chart__legend-item')).toHaveLength(3)
|
|
252
269
|
expect(wrapper.get('.waveform-track__no-visible-series').text()).toBe('暂无可见曲线')
|
|
253
270
|
|
|
254
271
|
await wrapper.findAll('.waveform-chart__legend-item')[0].trigger('click')
|
|
@@ -177,6 +177,18 @@ describe('WaveformChart', () => {
|
|
|
177
177
|
],
|
|
178
178
|
},
|
|
179
179
|
},
|
|
180
|
+
{
|
|
181
|
+
id: 'reference',
|
|
182
|
+
trackId: 'frame-1',
|
|
183
|
+
name: 'REF_CH_1',
|
|
184
|
+
data: {
|
|
185
|
+
kind: 'points',
|
|
186
|
+
points: [
|
|
187
|
+
{ x: 0, y: 0.25 },
|
|
188
|
+
{ x: 1, y: 1.25 },
|
|
189
|
+
],
|
|
190
|
+
},
|
|
191
|
+
},
|
|
180
192
|
],
|
|
181
193
|
},
|
|
182
194
|
{ frameNumber: 1, grid: { rowCount: 2, columnCount: 1 } },
|
|
@@ -186,7 +198,7 @@ describe('WaveformChart', () => {
|
|
|
186
198
|
expect(tracks).toHaveLength(2)
|
|
187
199
|
expect(
|
|
188
200
|
tracks[0].findAll('.waveform-chart__line').map((line) => line.attributes('data-series-id')),
|
|
189
|
-
).toEqual(['primary', 'comparison'])
|
|
201
|
+
).toEqual(['primary', 'comparison', 'reference'])
|
|
190
202
|
expect(
|
|
191
203
|
tracks[1].findAll('.waveform-chart__line').map((line) => line.attributes('data-series-id')),
|
|
192
204
|
).toEqual(['second-frame'])
|
|
@@ -203,12 +215,13 @@ describe('WaveformChart', () => {
|
|
|
203
215
|
expect(legend.findAll('.waveform-chart__legend-item').map((item) => item.text())).toEqual([
|
|
204
216
|
'BT2_2M',
|
|
205
217
|
'TEST_CH_1',
|
|
218
|
+
'REF_CH_1',
|
|
206
219
|
])
|
|
207
220
|
expect(
|
|
208
221
|
legend
|
|
209
222
|
.findAll('.waveform-legend__swatch')
|
|
210
223
|
.map((swatch) => swatch.get('path').attributes('stroke')),
|
|
211
|
-
).toEqual(['#0960bd', '#2ca02c'])
|
|
224
|
+
).toEqual(['#0960bd', '#2ca02c', '#d62728'])
|
|
212
225
|
expect(wrapper.findAll('.waveform-chart__watermark').map((item) => item.text())).toEqual([
|
|
213
226
|
'1',
|
|
214
227
|
'2',
|
|
@@ -232,10 +245,11 @@ describe('WaveformChart', () => {
|
|
|
232
245
|
await flushPromises()
|
|
233
246
|
|
|
234
247
|
const tooltipSeries = wrapper.findAll('.waveform-chart__tooltip-series')
|
|
235
|
-
expect(tooltipSeries).toHaveLength(
|
|
248
|
+
expect(tooltipSeries).toHaveLength(3)
|
|
236
249
|
expect(tooltipSeries.map((item) => item.text())).toEqual([
|
|
237
250
|
expect.stringContaining('BT2_2M'),
|
|
238
251
|
expect.stringContaining('TEST_CH_1'),
|
|
252
|
+
expect.stringContaining('REF_CH_1'),
|
|
239
253
|
])
|
|
240
254
|
})
|
|
241
255
|
|
|
@@ -268,6 +282,18 @@ describe('WaveformChart', () => {
|
|
|
268
282
|
],
|
|
269
283
|
},
|
|
270
284
|
},
|
|
285
|
+
{
|
|
286
|
+
id: 'third',
|
|
287
|
+
trackId: 'shared',
|
|
288
|
+
name: 'third',
|
|
289
|
+
data: {
|
|
290
|
+
kind: 'points',
|
|
291
|
+
points: [
|
|
292
|
+
{ x: 0, y: 2 },
|
|
293
|
+
{ x: 1, y: 3 },
|
|
294
|
+
],
|
|
295
|
+
},
|
|
296
|
+
},
|
|
271
297
|
],
|
|
272
298
|
},
|
|
273
299
|
{ grid: { rowCount: 1, columnCount: 1 } },
|
|
@@ -42,6 +42,19 @@ const presentationData: WaveformData = {
|
|
|
42
42
|
],
|
|
43
43
|
},
|
|
44
44
|
},
|
|
45
|
+
{
|
|
46
|
+
id: 'mid',
|
|
47
|
+
trackId: 'shared',
|
|
48
|
+
name: '中量程',
|
|
49
|
+
data: {
|
|
50
|
+
kind: 'points',
|
|
51
|
+
points: [
|
|
52
|
+
{ x: 0, y: 50 },
|
|
53
|
+
{ x: 1, y: 100 },
|
|
54
|
+
{ x: 2, y: 75 },
|
|
55
|
+
],
|
|
56
|
+
},
|
|
57
|
+
},
|
|
45
58
|
{
|
|
46
59
|
id: 'other',
|
|
47
60
|
name: '其他通道',
|
|
@@ -150,9 +163,9 @@ describe('WaveformChart presentation mode', () => {
|
|
|
150
163
|
cancelable: true,
|
|
151
164
|
}),
|
|
152
165
|
)
|
|
153
|
-
wrapper
|
|
154
|
-
|
|
155
|
-
|
|
166
|
+
wrapper
|
|
167
|
+
.get('.waveform-chart__svg')
|
|
168
|
+
.element.dispatchEvent(new MouseEvent('dblclick', { bubbles: true, cancelable: true }))
|
|
156
169
|
await wrapper.get('[data-annotation-id="note"]').trigger('contextmenu', {
|
|
157
170
|
clientX: width / 2,
|
|
158
171
|
clientY: height / 2,
|
|
@@ -3,7 +3,7 @@ import { describe, expect, it } from 'vitest'
|
|
|
3
3
|
import { createSimulatedWaveformData } from './simulatedWaveforms'
|
|
4
4
|
|
|
5
5
|
describe('simulated waveform data', () => {
|
|
6
|
-
it('creates deterministic, finite
|
|
6
|
+
it('creates deterministic, finite seven-channel data with a two-series second frame', () => {
|
|
7
7
|
const first = createSimulatedWaveformData()
|
|
8
8
|
const second = createSimulatedWaveformData()
|
|
9
9
|
|
|
@@ -11,8 +11,12 @@ describe('simulated waveform data', () => {
|
|
|
11
11
|
expect(first.kind).toBe('series')
|
|
12
12
|
if (first.kind !== 'series') return
|
|
13
13
|
|
|
14
|
-
expect(first.series).toHaveLength(
|
|
15
|
-
expect(new Set(first.series.map((series) => series.id)).size).toBe(
|
|
14
|
+
expect(first.series).toHaveLength(7)
|
|
15
|
+
expect(new Set(first.series.map((series) => series.id)).size).toBe(7)
|
|
16
|
+
const secondFrame = first.series.filter(
|
|
17
|
+
(series) => series.trackId === 'simulated-harmonic-frame',
|
|
18
|
+
)
|
|
19
|
+
expect(secondFrame).toHaveLength(2)
|
|
16
20
|
expect(new Set(first.series.map((series) => series.shotNo))).toEqual(new Set(['13300']))
|
|
17
21
|
first.series.forEach((series) => {
|
|
18
22
|
expect(series.data.kind).toBe('points')
|
|
@@ -13,7 +13,7 @@ type ErrorGenerator = (
|
|
|
13
13
|
|
|
14
14
|
interface SimulatedSeriesDefinition extends Pick<
|
|
15
15
|
WaveformSeries,
|
|
16
|
-
'id' | 'shotNo' | 'name' | 'unit' | 'lineType' | 'pointType' | 'errorBar'
|
|
16
|
+
'id' | 'trackId' | 'shotNo' | 'name' | 'unit' | 'color' | 'lineType' | 'pointType' | 'errorBar'
|
|
17
17
|
> {
|
|
18
18
|
signal: SignalGenerator
|
|
19
19
|
errors?: ErrorGenerator
|
|
@@ -60,6 +60,7 @@ const seriesDefinitions: SimulatedSeriesDefinition[] = [
|
|
|
60
60
|
},
|
|
61
61
|
{
|
|
62
62
|
id: 'simulated-harmonic',
|
|
63
|
+
trackId: 'simulated-harmonic-frame',
|
|
63
64
|
shotNo: '13300',
|
|
64
65
|
name: '谐波扰动',
|
|
65
66
|
unit: 'V',
|
|
@@ -68,6 +69,18 @@ const seriesDefinitions: SimulatedSeriesDefinition[] = [
|
|
|
68
69
|
signal: (time) =>
|
|
69
70
|
0.9 * Math.sin(TWO_PI * 0.55 * time) + 0.28 * Math.sin(TWO_PI * 2.2 * time + 0.4),
|
|
70
71
|
},
|
|
72
|
+
{
|
|
73
|
+
id: 'simulated-harmonic-reference',
|
|
74
|
+
trackId: 'simulated-harmonic-frame',
|
|
75
|
+
shotNo: '13300',
|
|
76
|
+
name: '谐波对比',
|
|
77
|
+
unit: 'V',
|
|
78
|
+
color: '#2ca02c',
|
|
79
|
+
lineType: 'linear',
|
|
80
|
+
pointType: 'none',
|
|
81
|
+
signal: (time) =>
|
|
82
|
+
0.62 * Math.sin(TWO_PI * 0.55 * time + 0.55) + 0.18 * Math.sin(TWO_PI * 2.2 * time - 0.2),
|
|
83
|
+
},
|
|
71
84
|
{
|
|
72
85
|
id: 'simulated-damped',
|
|
73
86
|
shotNo: '13300',
|
|
@@ -58,6 +58,18 @@ export function visibilitySeries(): WaveformData {
|
|
|
58
58
|
],
|
|
59
59
|
},
|
|
60
60
|
},
|
|
61
|
+
{
|
|
62
|
+
id: 'mid',
|
|
63
|
+
trackId: 'shared-frame',
|
|
64
|
+
name: '中量程',
|
|
65
|
+
data: {
|
|
66
|
+
kind: 'points',
|
|
67
|
+
points: [
|
|
68
|
+
{ x: 0, y: 100 },
|
|
69
|
+
{ x: 1, y: 200 },
|
|
70
|
+
],
|
|
71
|
+
},
|
|
72
|
+
},
|
|
61
73
|
],
|
|
62
74
|
}
|
|
63
75
|
}
|