waveform-analysis 0.1.70 → 0.1.72
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 +244 -45
- package/dist/assets/workerRuntime-5p-EI-GL.js +1 -0
- package/dist/index.cjs +2 -1
- package/dist/index.js +2924 -1915
- package/dist/style.css +1 -1
- package/dist/types/components/WaveformChart.vue.d.ts +24 -6
- package/dist/types/components/annotation/WaveformAnnotationLayer.vue.d.ts +2 -0
- package/dist/types/components/controls/WaveformToolbar.vue.d.ts +7 -0
- package/dist/types/components/controls/chartExportOptions.d.ts +5 -0
- package/dist/types/components/controls/chartSnapshot.d.ts +2 -0
- package/dist/types/components/controls/snapshotTitle.d.ts +2 -0
- package/dist/types/components/controls/toolbarRegistry.d.ts +21 -0
- package/dist/types/components/controls/useChartCommands.d.ts +42 -0
- package/dist/types/components/controls/useChartImageExport.d.ts +17 -0
- package/dist/types/components/controls/useControlMode.d.ts +8 -0
- package/dist/types/components/core/latestTaskScheduler.d.ts +1 -1
- package/dist/types/components/core/layout.d.ts +5 -3
- package/dist/types/components/core/niceScale.d.ts +34 -0
- package/dist/types/components/core/pagination.d.ts +2 -2
- package/dist/types/components/core/trackLayoutBuilder.d.ts +4 -1
- package/dist/types/components/core/trackPagination.d.ts +1 -1
- package/dist/types/components/core/types.d.ts +3 -0
- package/dist/types/components/core/useWaveformChartController.d.ts +24 -5
- package/dist/types/components/core/useWaveformChartLifecycle.d.ts +2 -2
- package/dist/types/components/core/useWaveformData.d.ts +1 -0
- package/dist/types/components/core/useWaveformLayout.d.ts +4 -1
- package/dist/types/components/core/useWaveformMeasurements.d.ts +2 -0
- package/dist/types/components/core/useWaveformRenderSampling.d.ts +1 -0
- package/dist/types/components/core/useWaveformViewportRestore.d.ts +5 -0
- package/dist/types/components/core/waveformChartTypes.d.ts +5 -0
- package/dist/types/components/core/waveformSamplingSession.d.ts +24 -0
- package/dist/types/components/core/yAxisLabelStyle.d.ts +3 -0
- package/dist/types/components/core/yAxisLayoutMetrics.d.ts +2 -1
- package/dist/types/components/core/yAxisPadding.d.ts +7 -0
- package/dist/types/components/core/yAxisTitleLayout.d.ts +2 -0
- package/dist/types/components/interaction/useWaveformViewport.d.ts +1 -0
- package/dist/types/components/rendering/WaveformLegend.vue.d.ts +2 -2
- package/dist/types/components/rendering/WaveformTrack.vue.d.ts +2 -3
- package/dist/types/components/rendering/WaveformTrackAxes.vue.d.ts +0 -1
- package/dist/types/components/rendering/WaveformTrackBackdrop.vue.d.ts +1 -0
- package/dist/types/components/rendering/compactFrame.d.ts +5 -0
- package/dist/types/components/rendering/yAxisTickVisibility.d.ts +11 -0
- package/dist/types/core/lineBoundary.d.ts +4 -0
- package/dist/types/core/rendering.d.ts +4 -0
- package/dist/types/core/renderingStrategies.d.ts +2 -0
- package/dist/types/core/workerSampling/outputBoundaries.d.ts +4 -0
- package/dist/types/data/simulatedWaveforms.d.ts +1 -1
- package/dist/types/demo/DemoYAxisPaddingControls.vue.d.ts +11 -0
- package/dist/types/demo/types.d.ts +6 -0
- package/dist/types/index.d.ts +2 -1
- package/dist/types/types/chart.d.ts +30 -8
- package/dist/types/types/controls.d.ts +69 -0
- package/dist/types/types/index.d.ts +2 -1
- package/dist/types/utils/formatters.d.ts +1 -0
- package/package.json +7 -6
- package/src/App.vue +58 -14
- package/src/components/WaveformChart.css +10 -1
- package/src/components/WaveformChart.vue +6 -0
- package/src/components/WaveformChartView.vue +27 -23
- package/src/components/annotation/WaveformAnnotationLayer.vue +6 -1
- package/src/components/annotation/useWaveformChartAnnotations.ts +6 -1
- package/src/components/controls/WaveformToolbar.vue +248 -0
- package/src/components/controls/chartExportOptions.ts +32 -0
- package/src/components/controls/chartSnapshot.ts +132 -0
- package/src/components/controls/snapshotTitle.ts +73 -0
- package/src/components/controls/toolbarRegistry.ts +92 -0
- package/src/components/controls/useChartCommands.ts +294 -0
- package/src/components/controls/useChartImageExport.ts +155 -0
- package/src/components/controls/useControlMode.ts +30 -0
- package/src/components/core/latestTaskScheduler.ts +14 -2
- package/src/components/core/layout.ts +35 -34
- package/src/components/core/niceScale.ts +151 -0
- package/src/components/core/pagination.ts +3 -16
- package/src/components/core/trackLayoutBuilder.ts +34 -17
- package/src/components/core/trackPagination.ts +3 -3
- package/src/components/core/types.ts +3 -0
- package/src/components/core/useWaveformChartController.ts +95 -10
- package/src/components/core/useWaveformChartLifecycle.ts +11 -111
- package/src/components/core/useWaveformData.ts +2 -0
- package/src/components/core/useWaveformLayout.ts +17 -5
- package/src/components/core/useWaveformMeasurements.ts +63 -0
- package/src/components/core/useWaveformRenderSampling.ts +80 -59
- package/src/components/core/useWaveformViewportRestore.ts +105 -0
- package/src/components/core/useWaveformYAxisLayout.ts +3 -2
- package/src/components/core/waveformChartTypes.ts +5 -0
- package/src/components/core/waveformSamplingSession.ts +49 -0
- package/src/components/core/workerSamplingClient.ts +38 -6
- package/src/components/core/yAxisLabelStyle.ts +10 -0
- package/src/components/core/yAxisLayoutMetrics.ts +10 -9
- package/src/components/core/yAxisPadding.ts +45 -0
- package/src/components/core/yAxisTitleLayout.ts +11 -12
- package/src/components/interaction/useWaveformViewport.ts +11 -2
- package/src/components/rendering/WaveformTrack.css +1 -2
- package/src/components/rendering/WaveformTrack.vue +4 -12
- package/src/components/rendering/WaveformTrackAxes.vue +48 -19
- package/src/components/rendering/WaveformTrackBackdrop.vue +8 -3
- package/src/components/rendering/compactFrame.ts +31 -0
- package/src/components/rendering/yAxisTickVisibility.ts +95 -0
- package/src/core/lineBoundary.ts +24 -0
- package/src/core/rendering.ts +48 -25
- package/src/core/renderingStrategies.ts +19 -13
- package/src/core/waveformPointSource.ts +23 -1
- package/src/core/workerSampling/outputBoundaries.ts +32 -0
- package/src/core/workerSampling/repository.ts +26 -18
- package/src/core/workerSampling/repositoryDataset.ts +33 -1
- package/src/core/workerSampling/workerRuntime.ts +13 -3
- package/src/data/simulatedWaveforms.ts +57 -2
- package/src/demo/DemoChartHost.vue +5 -1
- package/src/demo/DemoGridFrameControls.vue +2 -0
- package/src/demo/DemoViewControls.vue +5 -2
- package/src/demo/DemoYAxisPaddingControls.vue +46 -0
- package/src/demo/embedBridge.ts +85 -0
- package/src/demo/types.ts +6 -0
- package/src/index.ts +18 -0
- package/src/types/chart.ts +32 -8
- package/src/types/controls.ts +80 -0
- package/src/types/index.ts +18 -0
- package/src/utils/formatters.ts +2 -1
- package/src/views/WasmSamplingDemo.vue +8 -1
- package/dist/assets/workerRuntime-BcYng9TR.js +0 -1
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { Router } from 'vue-router'
|
|
2
|
+
|
|
3
|
+
type EmbedMessage =
|
|
4
|
+
| { type: 'ready'; appKey: string }
|
|
5
|
+
| { type: 'route-change'; appKey: string; route: string }
|
|
6
|
+
| { type: 'resize'; appKey: string; height: number }
|
|
7
|
+
|
|
8
|
+
const routeLimit = 2048
|
|
9
|
+
|
|
10
|
+
export function installDemoEmbedBridge(router: Router) {
|
|
11
|
+
const hostOrigin = trustedHostOrigin()
|
|
12
|
+
if (!hostOrigin) return () => undefined
|
|
13
|
+
|
|
14
|
+
const post = (message: EmbedMessage) => window.parent.postMessage(message, hostOrigin)
|
|
15
|
+
const requestedRoute = safeRoute(new URLSearchParams(window.location.search).get('childRoute'))
|
|
16
|
+
let active = false
|
|
17
|
+
|
|
18
|
+
const removeRouteHook = router.afterEach((route) => {
|
|
19
|
+
if (!active) return
|
|
20
|
+
post({
|
|
21
|
+
type: 'route-change',
|
|
22
|
+
appKey: appKey(),
|
|
23
|
+
route: route.fullPath,
|
|
24
|
+
})
|
|
25
|
+
})
|
|
26
|
+
const observer = new ResizeObserver(() =>
|
|
27
|
+
post({
|
|
28
|
+
type: 'resize',
|
|
29
|
+
appKey: appKey(),
|
|
30
|
+
height: Math.ceil(document.documentElement.scrollHeight),
|
|
31
|
+
}),
|
|
32
|
+
)
|
|
33
|
+
observer.observe(document.documentElement)
|
|
34
|
+
void router.isReady().then(async () => {
|
|
35
|
+
if (requestedRoute && requestedRoute !== router.currentRoute.value.fullPath)
|
|
36
|
+
await router.replace(requestedRoute)
|
|
37
|
+
active = true
|
|
38
|
+
post({ type: 'ready', appKey: appKey() })
|
|
39
|
+
post({ type: 'route-change', appKey: appKey(), route: router.currentRoute.value.fullPath })
|
|
40
|
+
post({
|
|
41
|
+
type: 'resize',
|
|
42
|
+
appKey: appKey(),
|
|
43
|
+
height: Math.ceil(document.documentElement.scrollHeight),
|
|
44
|
+
})
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
return () => {
|
|
48
|
+
removeRouteHook()
|
|
49
|
+
observer.disconnect()
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function appKey() {
|
|
54
|
+
return import.meta.env.VITE_EMBED_APP_KEY || 'waveform-analysis'
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function trustedHostOrigin() {
|
|
58
|
+
const configured = import.meta.env.VITE_EMBED_HOST_ORIGIN
|
|
59
|
+
if (!configured || window.parent === window) return null
|
|
60
|
+
try {
|
|
61
|
+
const expected = new URL(configured).origin
|
|
62
|
+
return new URL(document.referrer).origin === expected ? expected : null
|
|
63
|
+
} catch {
|
|
64
|
+
return null
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function safeRoute(value: string | null) {
|
|
69
|
+
if (
|
|
70
|
+
!value ||
|
|
71
|
+
value.length > routeLimit ||
|
|
72
|
+
!value.startsWith('/') ||
|
|
73
|
+
Array.from(value).some(
|
|
74
|
+
(character) => character.charCodeAt(0) < 32 || character.charCodeAt(0) === 127,
|
|
75
|
+
)
|
|
76
|
+
)
|
|
77
|
+
return null
|
|
78
|
+
try {
|
|
79
|
+
return new URL(value, 'https://waveform.invalid').origin === 'https://waveform.invalid'
|
|
80
|
+
? value
|
|
81
|
+
: null
|
|
82
|
+
} catch {
|
|
83
|
+
return null
|
|
84
|
+
}
|
|
85
|
+
}
|
package/src/demo/types.ts
CHANGED
|
@@ -23,6 +23,7 @@ interface SelectOption<T> {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
export interface DemoControlPanelModel {
|
|
26
|
+
toolbarVisible: boolean
|
|
26
27
|
controlsOpen: boolean
|
|
27
28
|
displayMode: WaveformDisplayMode
|
|
28
29
|
overlayMode: WaveformOverlayMode
|
|
@@ -50,6 +51,10 @@ export interface DemoControlPanelModel {
|
|
|
50
51
|
verticalGridColor: string
|
|
51
52
|
xAxisLineVisible: boolean
|
|
52
53
|
yAxisLineVisible: boolean
|
|
54
|
+
upperPaddingEnabled: boolean
|
|
55
|
+
lowerPaddingEnabled: boolean
|
|
56
|
+
upperPaddingPercent: number
|
|
57
|
+
lowerPaddingPercent: number
|
|
53
58
|
xAxisLabelFormatterEnabled: boolean
|
|
54
59
|
xAxisLabelFormat: DemoXAxisLabelFormat
|
|
55
60
|
xAxisLabelFormatOptions: Array<SelectOption<DemoXAxisLabelFormat>>
|
|
@@ -87,6 +92,7 @@ export interface DemoControlPanelModel {
|
|
|
87
92
|
}
|
|
88
93
|
|
|
89
94
|
export interface DemoChartModel {
|
|
95
|
+
toolbarVisible: boolean
|
|
90
96
|
data: WaveformData
|
|
91
97
|
initialXDomain?: [number, number]
|
|
92
98
|
displayMode: WaveformDisplayMode
|
package/src/index.ts
CHANGED
|
@@ -41,6 +41,7 @@ export type {
|
|
|
41
41
|
WaveformXAxisLabelFormatterContext,
|
|
42
42
|
WaveformXAxisLabelFormatter,
|
|
43
43
|
WaveformAxesOptions,
|
|
44
|
+
WaveformYAxisLabelTextStyle,
|
|
44
45
|
WaveformZeroLineOptions,
|
|
45
46
|
// 数据类型
|
|
46
47
|
SingleWaveformData,
|
|
@@ -97,3 +98,20 @@ export {
|
|
|
97
98
|
} from './core'
|
|
98
99
|
|
|
99
100
|
export { parseWaveformAnnotations, serializeWaveformAnnotations } from './components/annotation'
|
|
101
|
+
|
|
102
|
+
export type {
|
|
103
|
+
WaveformToolbarItem,
|
|
104
|
+
WaveformToolbarOptions,
|
|
105
|
+
WaveformControlTarget,
|
|
106
|
+
WaveformControlAction,
|
|
107
|
+
WaveformCommandMetadata,
|
|
108
|
+
WaveformTargetStatus,
|
|
109
|
+
WaveformViewportSnapshot,
|
|
110
|
+
WaveformTargetResult,
|
|
111
|
+
WaveformControlResult,
|
|
112
|
+
WaveformControlState,
|
|
113
|
+
WaveformImageExportOptions,
|
|
114
|
+
WaveformImageExportErrorCode,
|
|
115
|
+
WaveformImageExportError,
|
|
116
|
+
WaveformChartHandle,
|
|
117
|
+
} from './types/controls'
|
package/src/types/chart.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { WaveformCommandMetadata } from './controls'
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* 波形数据点
|
|
3
5
|
*/
|
|
@@ -19,6 +21,8 @@ export type WaveformLayoutPreset = 'default' | 'edge-compact'
|
|
|
19
21
|
export type WaveformUnitDisplayMode =
|
|
20
22
|
| 'axis'
|
|
21
23
|
| 'legend-single-series'
|
|
24
|
+
/** Append units to Y-axis names while retaining names on multi-series pages. */
|
|
25
|
+
| 'channel-label'
|
|
22
26
|
/** Label and legend units; hide all channel titles on pages containing a multi-series track. */
|
|
23
27
|
| 'channel-label-or-legend'
|
|
24
28
|
|
|
@@ -34,7 +38,7 @@ export type WaveformDisplayMode = 'independent' | 'separated' | 'compact'
|
|
|
34
38
|
export type WaveformOverlayMode = 'single-axis' | 'multi-axis'
|
|
35
39
|
|
|
36
40
|
/** 标注工具模式 */
|
|
37
|
-
export type WaveformInteractionMode = 'zoom' | 'annotation'
|
|
41
|
+
export type WaveformInteractionMode = 'zoom' | 'annotation' | 'pan' | 'none'
|
|
38
42
|
|
|
39
43
|
/** Controls how the initial X viewport is derived when no explicit domain is configured. */
|
|
40
44
|
export interface WaveformXDomainStrategy {
|
|
@@ -49,7 +53,7 @@ export interface WaveformXDomainStrategy {
|
|
|
49
53
|
}
|
|
50
54
|
|
|
51
55
|
/** Describes the X-axis viewport after a zoom gesture completes. */
|
|
52
|
-
export interface WaveformZoomEndPayload {
|
|
56
|
+
export interface WaveformZoomEndPayload extends WaveformCommandMetadata {
|
|
53
57
|
start: number
|
|
54
58
|
end: number
|
|
55
59
|
yStart?: number
|
|
@@ -57,7 +61,7 @@ export interface WaveformZoomEndPayload {
|
|
|
57
61
|
yRanges?: Record<string, [number, number]>
|
|
58
62
|
trackIndex?: number
|
|
59
63
|
seriesIds?: string[]
|
|
60
|
-
gesture?: 'wheel' | 'box'
|
|
64
|
+
gesture?: 'wheel' | 'box' | 'command'
|
|
61
65
|
}
|
|
62
66
|
|
|
63
67
|
/** Final horizontal viewport after a pan; endpoints are always seconds. */
|
|
@@ -69,16 +73,16 @@ export interface WaveformPanEndPayload {
|
|
|
69
73
|
}
|
|
70
74
|
|
|
71
75
|
/** Describes the X-axis viewport targeted by a user zoom gesture before rendering settles. */
|
|
72
|
-
export interface WaveformZoomIntentPayload {
|
|
76
|
+
export interface WaveformZoomIntentPayload extends WaveformCommandMetadata {
|
|
73
77
|
start: number
|
|
74
78
|
end: number
|
|
75
|
-
gesture: 'wheel' | 'box'
|
|
79
|
+
gesture: 'wheel' | 'box' | 'command'
|
|
76
80
|
trackIndex?: number
|
|
77
81
|
seriesIds?: string[]
|
|
78
82
|
}
|
|
79
83
|
|
|
80
84
|
/** Identifies the viewport reset by a double-click gesture. */
|
|
81
|
-
export interface WaveformZoomResetPayload {
|
|
85
|
+
export interface WaveformZoomResetPayload extends WaveformCommandMetadata {
|
|
82
86
|
trackIndex?: number
|
|
83
87
|
seriesIds?: string[]
|
|
84
88
|
}
|
|
@@ -258,7 +262,19 @@ export type WaveformXAxisLabelFormatter = (
|
|
|
258
262
|
context: WaveformXAxisLabelFormatterContext,
|
|
259
263
|
) => string
|
|
260
264
|
|
|
261
|
-
/**
|
|
265
|
+
/** Styling for Y-axis series names, separate from numeric tick labels. */
|
|
266
|
+
export interface WaveformYAxisLabelTextStyle {
|
|
267
|
+
/** Positive font size in pixels. Defaults to 12. */
|
|
268
|
+
fontSize?: number
|
|
269
|
+
/** CSS font weight; use 'normal' or 400 to disable bold. Defaults to 600. */
|
|
270
|
+
fontWeight?: number | string
|
|
271
|
+
fontFamily?: string
|
|
272
|
+
fontStyle?: 'normal' | 'italic'
|
|
273
|
+
/** CSS color. Defaults to the corresponding series color. */
|
|
274
|
+
color?: string
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/** Controls axis baselines, labels, and Y-axis range calculation. */
|
|
262
278
|
export interface WaveformAxesOptions {
|
|
263
279
|
x?: {
|
|
264
280
|
lineVisible?: boolean
|
|
@@ -267,12 +283,20 @@ export interface WaveformAxesOptions {
|
|
|
267
283
|
}
|
|
268
284
|
y?: {
|
|
269
285
|
lineVisible?: boolean
|
|
286
|
+
/** Styles series names on both left and right Y axes, without changing tick labels. */
|
|
287
|
+
labelTextStyle?: WaveformYAxisLabelTextStyle
|
|
270
288
|
/** Target total number of equal Y-axis ticks, including endpoints. Defaults to 5. */
|
|
271
289
|
splitNumber?: number
|
|
272
290
|
/** Expands Y-axis domains to equal, human-friendly intervals. Defaults to true. */
|
|
273
291
|
nice?: boolean
|
|
274
|
-
/**
|
|
292
|
+
/** Fraction of the automatic Y span added above its maximum. Defaults to 0. */
|
|
275
293
|
upperPaddingRatio?: number
|
|
294
|
+
/** Fraction of the automatic Y span added below its minimum. Defaults to 0. */
|
|
295
|
+
lowerPaddingRatio?: number
|
|
296
|
+
/** False disables upper padding; true defaults an omitted ratio to 0.1. */
|
|
297
|
+
upperPaddingEnabled?: boolean
|
|
298
|
+
/** False disables lower padding; true defaults an omitted ratio to 0.1. */
|
|
299
|
+
lowerPaddingEnabled?: boolean
|
|
276
300
|
}
|
|
277
301
|
}
|
|
278
302
|
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { WaveformInteractionMode } from './chart'
|
|
2
|
+
|
|
3
|
+
export type WaveformToolbarItem =
|
|
4
|
+
'zoom-box' | 'pan' | 'annotate' | 'zoom-in' | 'zoom-out' | 'reset' | 'fit' | 'export'
|
|
5
|
+
export interface WaveformToolbarOptions {
|
|
6
|
+
visible?: boolean
|
|
7
|
+
display?: 'hover' | 'always'
|
|
8
|
+
position?: 'top-right' | 'top-left'
|
|
9
|
+
items?: WaveformToolbarItem[]
|
|
10
|
+
}
|
|
11
|
+
export interface WaveformControlTarget {
|
|
12
|
+
trackId?: string
|
|
13
|
+
}
|
|
14
|
+
export type WaveformControlAction = 'zoom-in' | 'zoom-out' | 'set-domain' | 'fit' | 'reset'
|
|
15
|
+
export interface WaveformCommandMetadata {
|
|
16
|
+
commandId?: string
|
|
17
|
+
source?: 'toolbar' | 'api'
|
|
18
|
+
action?: WaveformControlAction
|
|
19
|
+
}
|
|
20
|
+
export type WaveformTargetStatus = 'applied' | 'unchanged' | 'disabled' | 'empty-data'
|
|
21
|
+
export interface WaveformViewportSnapshot {
|
|
22
|
+
xDomain: [number, number]
|
|
23
|
+
yDomains: Record<string, [number, number]>
|
|
24
|
+
}
|
|
25
|
+
export interface WaveformTargetResult {
|
|
26
|
+
trackId: string
|
|
27
|
+
status: WaveformTargetStatus
|
|
28
|
+
before?: WaveformViewportSnapshot
|
|
29
|
+
after?: WaveformViewportSnapshot
|
|
30
|
+
}
|
|
31
|
+
export type WaveformControlResult =
|
|
32
|
+
| {
|
|
33
|
+
kind: 'viewport'
|
|
34
|
+
status: WaveformTargetStatus | 'invalid-target' | 'invalid-domain'
|
|
35
|
+
targets: WaveformTargetResult[]
|
|
36
|
+
}
|
|
37
|
+
| {
|
|
38
|
+
kind: 'mode'
|
|
39
|
+
status: 'applied' | 'requested' | 'unchanged' | 'disabled'
|
|
40
|
+
targets: []
|
|
41
|
+
}
|
|
42
|
+
export interface WaveformControlState {
|
|
43
|
+
mode: WaveformInteractionMode
|
|
44
|
+
independent: boolean
|
|
45
|
+
targets: Array<{
|
|
46
|
+
trackId: string
|
|
47
|
+
label: string
|
|
48
|
+
viewport: WaveformViewportSnapshot
|
|
49
|
+
available: Record<WaveformControlAction, boolean>
|
|
50
|
+
}>
|
|
51
|
+
available: Record<WaveformToolbarItem, boolean>
|
|
52
|
+
}
|
|
53
|
+
export interface WaveformImageExportOptions {
|
|
54
|
+
format?: 'png' | 'svg'
|
|
55
|
+
scale?: number
|
|
56
|
+
backgroundColor?: string
|
|
57
|
+
}
|
|
58
|
+
export type WaveformImageExportErrorCode =
|
|
59
|
+
| 'export-invalid-options'
|
|
60
|
+
| 'export-unavailable'
|
|
61
|
+
| 'export-busy'
|
|
62
|
+
| 'export-cancelled'
|
|
63
|
+
| 'export-render-failed'
|
|
64
|
+
| 'export-stale'
|
|
65
|
+
| 'export-timeout'
|
|
66
|
+
export interface WaveformImageExportError extends Error {
|
|
67
|
+
code: WaveformImageExportErrorCode
|
|
68
|
+
}
|
|
69
|
+
export interface WaveformChartHandle {
|
|
70
|
+
zoomIn(target?: WaveformControlTarget): WaveformControlResult
|
|
71
|
+
zoomOut(target?: WaveformControlTarget): WaveformControlResult
|
|
72
|
+
fitToData(target?: WaveformControlTarget): WaveformControlResult
|
|
73
|
+
resetViewport(trackIndex?: number): void
|
|
74
|
+
resetViewport(target: WaveformControlTarget): WaveformControlResult
|
|
75
|
+
setViewportDomain(domain: [number, number], trackIndex?: number): void
|
|
76
|
+
setViewportDomain(domain: [number, number], target: WaveformControlTarget): WaveformControlResult
|
|
77
|
+
setInteractionMode(mode: WaveformInteractionMode): WaveformControlResult
|
|
78
|
+
getControlState(): WaveformControlState
|
|
79
|
+
exportImage(options?: WaveformImageExportOptions): Promise<Blob>
|
|
80
|
+
}
|
package/src/types/index.ts
CHANGED
|
@@ -35,6 +35,7 @@ export type {
|
|
|
35
35
|
WaveformXAxisLabelFormatterContext,
|
|
36
36
|
WaveformXAxisLabelFormatter,
|
|
37
37
|
WaveformAxesOptions,
|
|
38
|
+
WaveformYAxisLabelTextStyle,
|
|
38
39
|
WaveformZeroLineOptions,
|
|
39
40
|
} from './chart'
|
|
40
41
|
|
|
@@ -53,3 +54,20 @@ export type {
|
|
|
53
54
|
WaveformData,
|
|
54
55
|
NormalizedWaveformSeries,
|
|
55
56
|
} from './data'
|
|
57
|
+
|
|
58
|
+
export type {
|
|
59
|
+
WaveformToolbarItem,
|
|
60
|
+
WaveformToolbarOptions,
|
|
61
|
+
WaveformControlTarget,
|
|
62
|
+
WaveformControlAction,
|
|
63
|
+
WaveformCommandMetadata,
|
|
64
|
+
WaveformTargetStatus,
|
|
65
|
+
WaveformViewportSnapshot,
|
|
66
|
+
WaveformTargetResult,
|
|
67
|
+
WaveformControlResult,
|
|
68
|
+
WaveformControlState,
|
|
69
|
+
WaveformImageExportOptions,
|
|
70
|
+
WaveformImageExportErrorCode,
|
|
71
|
+
WaveformImageExportError,
|
|
72
|
+
WaveformChartHandle,
|
|
73
|
+
} from './controls'
|
package/src/utils/formatters.ts
CHANGED
|
@@ -11,6 +11,7 @@ export interface ScientificAxisLabelOptions {
|
|
|
11
11
|
axisMin?: number
|
|
12
12
|
axisMax?: number
|
|
13
13
|
topTickValue?: number
|
|
14
|
+
/** Unit prefix for ordinary top ticks; scientific ticks omit it. */
|
|
14
15
|
unit?: string
|
|
15
16
|
}
|
|
16
17
|
|
|
@@ -75,7 +76,7 @@ export function formatScientificAxisLabel(
|
|
|
75
76
|
const topTickValue = options.topTickValue ?? options.axisMax
|
|
76
77
|
if (value !== topTickValue) return formattedValue
|
|
77
78
|
const unit = options.unit?.trim()
|
|
78
|
-
const unitLabel = unit ? `(${unit}) ` : ''
|
|
79
|
+
const unitLabel = exponent === null && unit ? `(${unit}) ` : ''
|
|
79
80
|
const exponentLabel = exponent === null ? '' : `${formatExponent(exponent)} `
|
|
80
81
|
return `${exponentLabel}${unitLabel}${formattedValue}`
|
|
81
82
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { computed, reactive, ref } from 'vue'
|
|
3
|
-
import { InputNumber, RadioButton, RadioGroup, Select } from 'ant-design-vue'
|
|
3
|
+
import { InputNumber, RadioButton, RadioGroup, Select, Switch } from 'ant-design-vue'
|
|
4
4
|
|
|
5
5
|
import { WaveformChart } from '../components'
|
|
6
6
|
import type {
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
usesFixedPointCount,
|
|
18
18
|
} from './wasmSamplingDemoSampling'
|
|
19
19
|
|
|
20
|
+
const toolbarVisible = ref(true)
|
|
20
21
|
const SERIES_COUNT = 10
|
|
21
22
|
const POINTS_PER_SERIES = 100_000
|
|
22
23
|
|
|
@@ -120,6 +121,10 @@ function pointCount(value: number | undefined) {
|
|
|
120
121
|
</header>
|
|
121
122
|
|
|
122
123
|
<section class="sampling-demo__controls" aria-label="采样参数">
|
|
124
|
+
<label
|
|
125
|
+
><span>内置工具栏</span
|
|
126
|
+
><Switch v-model:checked="toolbarVisible" aria-label="显示内置工具栏" size="small"
|
|
127
|
+
/></label>
|
|
123
128
|
<label>
|
|
124
129
|
<span>策略</span>
|
|
125
130
|
<Select v-model:value="strategy" :options="strategyOptions" size="small" />
|
|
@@ -164,6 +169,8 @@ function pointCount(value: number | undefined) {
|
|
|
164
169
|
<section class="sampling-demo__workspace">
|
|
165
170
|
<div class="sampling-demo__chart">
|
|
166
171
|
<WaveformChart
|
|
172
|
+
:toolbar="toolbarVisible"
|
|
173
|
+
pannable
|
|
167
174
|
:data="data"
|
|
168
175
|
v-model:annotations="annotations"
|
|
169
176
|
:rendering="rendering"
|