waveform-analysis 0.1.65 → 0.1.67
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 +146 -5
- package/dist/index.cjs +1 -1
- package/dist/index.js +1326 -1118
- package/dist/style.css +1 -1
- package/dist/types/components/WaveformChart.vue.d.ts +7 -2
- package/dist/types/components/core/constants.d.ts +2 -0
- package/dist/types/components/core/grid.d.ts +1 -1
- package/dist/types/components/core/layout.d.ts +2 -2
- package/dist/types/components/core/pagination.d.ts +2 -0
- package/dist/types/components/core/title.d.ts +2 -1
- package/dist/types/components/core/trackLayoutBuilder.d.ts +5 -0
- package/dist/types/components/core/types.d.ts +2 -1
- package/dist/types/components/core/useWaveformChartController.d.ts +9 -0
- package/dist/types/components/core/useWaveformLayout.d.ts +1 -0
- package/dist/types/components/core/useWaveformPresentation.d.ts +3 -0
- package/dist/types/components/core/useWaveformYAxisLayout.d.ts +31 -0
- package/dist/types/components/core/waveformChartTypes.d.ts +11 -2
- package/dist/types/components/core/yAxisLayoutMetrics.d.ts +1 -1
- package/dist/types/components/core/yAxisTitleLayout.d.ts +4 -0
- package/dist/types/components/data/types.d.ts +1 -1
- package/dist/types/components/interaction/integerZoom.d.ts +12 -0
- package/dist/types/components/interaction/interactionTarget.d.ts +1 -0
- package/dist/types/components/interaction/remoteViewport.d.ts +8 -0
- package/dist/types/components/interaction/useWaveformViewport.d.ts +1 -2
- package/dist/types/components/interaction/viewportDomain.d.ts +1 -1
- package/dist/types/components/interaction/viewportPan.d.ts +4 -0
- package/dist/types/components/interaction/zoomConstraints.d.ts +2 -1
- package/dist/types/components/rendering/WaveformLegend.vue.d.ts +2 -0
- package/dist/types/components/rendering/WaveformTrack.vue.d.ts +6 -6
- package/dist/types/components/rendering/WaveformTrackAxes.vue.d.ts +5 -1
- package/dist/types/components/rendering/WaveformTrackBackdrop.vue.d.ts +0 -4
- package/dist/types/components/rendering/WaveformZeroLines.vue.d.ts +12 -0
- package/dist/types/data/recordedDampedWaveform.d.ts +1 -0
- package/dist/types/demo/types.d.ts +3 -0
- package/dist/types/index.d.ts +2 -1
- package/dist/types/types/chart.d.ts +17 -0
- package/dist/types/types/index.d.ts +1 -1
- package/package.json +1 -1
- package/src/App.vue +6 -0
- package/src/components/WaveformChart.css +5 -0
- package/src/components/WaveformChart.vue +3 -0
- package/src/components/WaveformChartView.vue +14 -3
- package/src/components/core/constants.ts +2 -0
- package/src/components/core/grid.ts +4 -1
- package/src/components/core/layout.ts +16 -2
- package/src/components/core/pagination.ts +17 -0
- package/src/components/core/title.ts +7 -3
- package/src/components/core/trackLayoutBuilder.ts +39 -59
- package/src/components/core/types.ts +2 -0
- package/src/components/core/useWaveformChartController.ts +17 -1
- package/src/components/core/useWaveformChartLifecycle.ts +11 -17
- package/src/components/core/useWaveformLayout.ts +67 -107
- package/src/components/core/useWaveformPresentation.ts +27 -3
- package/src/components/core/useWaveformYAxisLayout.ts +140 -0
- package/src/components/core/waveformChartTypes.ts +15 -0
- package/src/components/core/yAxisLayoutMetrics.ts +11 -2
- package/src/components/core/yAxisTitleLayout.ts +78 -0
- package/src/components/data/types.ts +3 -0
- package/src/components/interaction/integerZoom.ts +64 -0
- package/src/components/interaction/interactionTarget.ts +10 -0
- package/src/components/interaction/remoteViewport.ts +53 -0
- package/src/components/interaction/useWaveformViewport.ts +16 -58
- package/src/components/interaction/useWaveformZoom.ts +13 -11
- package/src/components/interaction/viewportDomain.ts +11 -3
- package/src/components/interaction/viewportPan.ts +82 -0
- package/src/components/interaction/zoomConstraints.ts +7 -5
- package/src/components/rendering/WaveformLegend.vue +10 -1
- package/src/components/rendering/WaveformTrack.vue +24 -6
- package/src/components/rendering/WaveformTrackAxes.vue +16 -5
- package/src/components/rendering/WaveformTrackBackdrop.vue +2 -34
- package/src/components/rendering/WaveformZeroLines.vue +53 -0
- package/src/data/recordedDampedWaveform.ts +3 -0
- package/src/data/simulatedWaveforms.ts +12 -10
- package/src/demo/DemoChartHost.vue +1 -0
- package/src/demo/DemoGridFrameControls.vue +12 -0
- package/src/demo/DemoViewControls.vue +4 -0
- package/src/demo/types.ts +3 -0
- package/src/index.ts +4 -0
- package/src/styles.css +3 -3
- package/src/types/chart.ts +20 -0
- package/src/types/index.ts +3 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { TrackLayout } from '../core/types'
|
|
2
|
+
import { hasFixedYDomainForTrack } from '../core/yDomain'
|
|
3
|
+
import type { ViewportSelectionState } from '../core/waveformChartTypes'
|
|
4
|
+
import type { ViewportContext } from './useWaveformViewport'
|
|
5
|
+
import { clampViewportDomain as clampDomain } from './viewportDomain'
|
|
6
|
+
import { alignIntegerPanDomain } from './integerZoom'
|
|
7
|
+
import { remotePanBoundary } from './remoteViewport'
|
|
8
|
+
import { transformForDomain } from './zoomConstraints'
|
|
9
|
+
|
|
10
|
+
export function createViewportPan(context: ViewportContext) {
|
|
11
|
+
const {
|
|
12
|
+
props,
|
|
13
|
+
emit,
|
|
14
|
+
resolveInitialTrackDomain,
|
|
15
|
+
initialXDomain,
|
|
16
|
+
independentTransforms,
|
|
17
|
+
sharedTransform,
|
|
18
|
+
innerWidth,
|
|
19
|
+
trackLayouts,
|
|
20
|
+
chartTracks,
|
|
21
|
+
independentYDomains,
|
|
22
|
+
sharedYDomains,
|
|
23
|
+
} = context
|
|
24
|
+
const applyPan = (active: ViewportSelectionState, track: TrackLayout) => {
|
|
25
|
+
const width = track.width || 1
|
|
26
|
+
const height = track.height || 1
|
|
27
|
+
const dx = active.currentX - active.startX
|
|
28
|
+
const dy = active.currentY - active.startY
|
|
29
|
+
const xSpan = active.xDomain[1] - active.xDomain[0]
|
|
30
|
+
const sourceXDomain = active.independent
|
|
31
|
+
? resolveInitialTrackDomain(track)
|
|
32
|
+
: initialXDomain.value
|
|
33
|
+
const boundary = remotePanBoundary(props) ?? sourceXDomain
|
|
34
|
+
const nextX = clampDomain(
|
|
35
|
+
alignIntegerPanDomain(
|
|
36
|
+
clampDomain(
|
|
37
|
+
[active.xDomain[0] - (dx / width) * xSpan, active.xDomain[1] - (dx / width) * xSpan],
|
|
38
|
+
boundary,
|
|
39
|
+
),
|
|
40
|
+
props,
|
|
41
|
+
),
|
|
42
|
+
boundary,
|
|
43
|
+
)
|
|
44
|
+
if (active.independent) {
|
|
45
|
+
const nextTransforms = [...independentTransforms.value]
|
|
46
|
+
nextTransforms[track.index] = transformForDomain(nextX, sourceXDomain, width)
|
|
47
|
+
independentTransforms.value = nextTransforms
|
|
48
|
+
} else {
|
|
49
|
+
sharedTransform.value = transformForDomain(nextX, sourceXDomain, innerWidth.value)
|
|
50
|
+
}
|
|
51
|
+
if (remotePanBoundary(props)) {
|
|
52
|
+
emit('zoom-change', nextX)
|
|
53
|
+
return nextX
|
|
54
|
+
}
|
|
55
|
+
const targets = active.independent
|
|
56
|
+
? [track]
|
|
57
|
+
: trackLayouts.value.filter((target) => target.hasVisibleSeries)
|
|
58
|
+
const nextIndependentDomains = { ...independentYDomains.value }
|
|
59
|
+
const nextSharedDomains = { ...sharedYDomains.value }
|
|
60
|
+
targets.forEach((target) => {
|
|
61
|
+
const chartTrack = chartTracks.value.find((item) => item.id === target.id)
|
|
62
|
+
if (chartTrack && hasFixedYDomainForTrack(chartTrack, props.yDomain, props.yDomains)) {
|
|
63
|
+
return
|
|
64
|
+
}
|
|
65
|
+
const key = target.series?.trackId ?? target.series?.id ?? target.id
|
|
66
|
+
const source = active.yDomains[key] ?? (target.yScale.domain() as [number, number])
|
|
67
|
+
const boundary = chartTrack?.yDomain ?? source
|
|
68
|
+
const ySpan = source[1] - source[0]
|
|
69
|
+
const nextY = clampDomain(
|
|
70
|
+
[source[0] + (dy / height) * ySpan, source[1] + (dy / height) * ySpan],
|
|
71
|
+
boundary,
|
|
72
|
+
)
|
|
73
|
+
if (active.independent) nextIndependentDomains[target.index] = nextY
|
|
74
|
+
else nextSharedDomains[key] = nextY
|
|
75
|
+
})
|
|
76
|
+
if (active.independent) independentYDomains.value = nextIndependentDomains
|
|
77
|
+
else sharedYDomains.value = nextSharedDomains
|
|
78
|
+
emit('zoom-change', nextX)
|
|
79
|
+
return nextX
|
|
80
|
+
}
|
|
81
|
+
return applyPan
|
|
82
|
+
}
|
|
@@ -3,6 +3,7 @@ import { scaleLinear, zoomIdentity, type ZoomTransform } from 'd3'
|
|
|
3
3
|
import type { WaveformPoint } from '../../types'
|
|
4
4
|
import { pointSourceFromPoints, type WaveformPointSource } from '../../core/waveformPointSource'
|
|
5
5
|
import { ZOOM_CONSTRAINTS } from '../core/constants'
|
|
6
|
+
import { alignIntegerZoomDomain, type IntegerZoomOptions } from './integerZoom'
|
|
6
7
|
|
|
7
8
|
interface PointSeriesSource {
|
|
8
9
|
points: WaveformPoint[]
|
|
@@ -11,7 +12,7 @@ interface PointSeriesSource {
|
|
|
11
12
|
|
|
12
13
|
export type ZoomSeriesGroup = readonly PointSeriesSource[]
|
|
13
14
|
|
|
14
|
-
interface ZoomConstraintOptions {
|
|
15
|
+
interface ZoomConstraintOptions extends IntegerZoomOptions {
|
|
15
16
|
minZoomSpan?: number
|
|
16
17
|
minVisiblePoints?: number
|
|
17
18
|
maxZoomScale?: number | null
|
|
@@ -72,7 +73,7 @@ export function resolveMinimumZoomSpan(
|
|
|
72
73
|
groups: readonly ZoomSeriesGroup[],
|
|
73
74
|
options: ZoomConstraintOptions,
|
|
74
75
|
): number {
|
|
75
|
-
const normalized = normalizedBoundary(boundary)
|
|
76
|
+
const normalized = alignIntegerZoomDomain(normalizedBoundary(boundary), options)
|
|
76
77
|
const boundarySpan = normalized[1] - normalized[0]
|
|
77
78
|
if (!Number.isFinite(boundarySpan) || boundarySpan <= 0) return 0
|
|
78
79
|
const configuredSpan =
|
|
@@ -88,7 +89,8 @@ export function resolveMinimumZoomSpan(
|
|
|
88
89
|
: options.maxZoomScale !== null && configuredSpan === 0 && required === 0
|
|
89
90
|
? boundarySpan / ZOOM_CONSTRAINTS.DEFAULT_MAX_SCALE
|
|
90
91
|
: 0
|
|
91
|
-
|
|
92
|
+
const integerSpan = options.integerZoom ? (options.timeUnit === 's' ? 1 : 0.001) : 0
|
|
93
|
+
return Math.max(configuredSpan, pointSpan, scaleSpan, integerSpan)
|
|
92
94
|
}
|
|
93
95
|
|
|
94
96
|
function expandToMinimumPoints(
|
|
@@ -139,7 +141,7 @@ export function constrainZoomDomain(
|
|
|
139
141
|
groups: readonly ZoomSeriesGroup[],
|
|
140
142
|
options: ZoomConstraintOptions,
|
|
141
143
|
): [number, number] {
|
|
142
|
-
const normalized = normalizedBoundary(boundary)
|
|
144
|
+
const normalized = alignIntegerZoomDomain(normalizedBoundary(boundary), options)
|
|
143
145
|
const boundarySpan = normalized[1] - normalized[0]
|
|
144
146
|
if (!Number.isFinite(boundarySpan) || boundarySpan <= 0) return normalized
|
|
145
147
|
if (Math.abs(domain[1] - domain[0]) >= boundarySpan * (1 - 1e-12)) return normalized
|
|
@@ -157,7 +159,7 @@ export function constrainZoomDomain(
|
|
|
157
159
|
const span = Math.max(minimumSpan, Math.min(boundarySpan, expanded[1] - expanded[0]))
|
|
158
160
|
const center = (expanded[0] + expanded[1]) / 2
|
|
159
161
|
const start = Math.max(normalized[0], Math.min(center - span / 2, normalized[1] - span))
|
|
160
|
-
return [start, start + span]
|
|
162
|
+
return alignIntegerZoomDomain([start, start + span], options)
|
|
161
163
|
}
|
|
162
164
|
|
|
163
165
|
export function transformForDomain(
|
|
@@ -18,11 +18,13 @@ interface Props {
|
|
|
18
18
|
width: number
|
|
19
19
|
height: number
|
|
20
20
|
interactive?: boolean
|
|
21
|
+
showUnits?: boolean
|
|
21
22
|
hiddenSeriesIds?: string[]
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
const props = withDefaults(defineProps<Props>(), {
|
|
25
26
|
interactive: false,
|
|
27
|
+
showUnits: false,
|
|
26
28
|
hiddenSeriesIds: () => [],
|
|
27
29
|
})
|
|
28
30
|
const emit = defineEmits<{
|
|
@@ -30,6 +32,11 @@ const emit = defineEmits<{
|
|
|
30
32
|
}>()
|
|
31
33
|
const hiddenSeriesIdSet = computed(() => new Set(props.hiddenSeriesIds))
|
|
32
34
|
|
|
35
|
+
function legendLabel(series: DisplaySeries): string {
|
|
36
|
+
const unit = series.unit?.trim()
|
|
37
|
+
return props.showUnits && unit && unit !== '--' ? `${series.name} (${unit})` : series.name
|
|
38
|
+
}
|
|
39
|
+
|
|
33
40
|
function isHidden(seriesId: string): boolean {
|
|
34
41
|
return hiddenSeriesIdSet.value.has(seriesId)
|
|
35
42
|
}
|
|
@@ -113,7 +120,9 @@ function toggleSeries(seriesId: string) {
|
|
|
113
120
|
transform="translate(13 8)"
|
|
114
121
|
/>
|
|
115
122
|
</svg>
|
|
116
|
-
<span class="waveform-legend__label" :title="item
|
|
123
|
+
<span class="waveform-legend__label" :title="legendLabel(item)">{{
|
|
124
|
+
legendLabel(item)
|
|
125
|
+
}}</span>
|
|
117
126
|
</button>
|
|
118
127
|
</div>
|
|
119
128
|
</div>
|
|
@@ -6,6 +6,7 @@ import type { WaveformAxesOptions, WaveformFrameStyle, WaveformZeroLineOptions }
|
|
|
6
6
|
import type { TrackLayout } from '../core/types'
|
|
7
7
|
import type { WaveformDisplayMode, WaveformInteractionMode } from '../data/types'
|
|
8
8
|
import WaveformSeriesLayer from './WaveformSeriesLayer.vue'
|
|
9
|
+
import WaveformZeroLines from './WaveformZeroLines.vue'
|
|
9
10
|
import WaveformTrackAxes from './WaveformTrackAxes.vue'
|
|
10
11
|
import WaveformTrackBackdrop from './WaveformTrackBackdrop.vue'
|
|
11
12
|
|
|
@@ -22,10 +23,11 @@ interface Props {
|
|
|
22
23
|
axes?: WaveformAxesOptions
|
|
23
24
|
timeUnit: 's' | 'ms'
|
|
24
25
|
yLabel?: string
|
|
26
|
+
showAxisUnits?: boolean
|
|
27
|
+
containYAxisEndpoints?: boolean
|
|
28
|
+
containFrameStroke?: boolean
|
|
25
29
|
cleanView?: boolean
|
|
26
|
-
zeroLine?: Required<
|
|
27
|
-
visible: boolean
|
|
28
|
-
}
|
|
30
|
+
zeroLine?: Required<WaveformZeroLineOptions>
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
interface Emits {
|
|
@@ -42,11 +44,14 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
42
44
|
interactionMode: 'zoom',
|
|
43
45
|
interactive: true,
|
|
44
46
|
cleanView: false,
|
|
47
|
+
showAxisUnits: true,
|
|
45
48
|
zeroLine: () => ({
|
|
46
49
|
visible: true,
|
|
47
50
|
color: ZERO_LINE_DEFAULTS.COLOR,
|
|
48
51
|
width: ZERO_LINE_DEFAULTS.WIDTH,
|
|
49
52
|
dash: ZERO_LINE_DEFAULTS.DASH,
|
|
53
|
+
opacity: ZERO_LINE_DEFAULTS.OPACITY,
|
|
54
|
+
boundaryThreshold: ZERO_LINE_DEFAULTS.BOUNDARY_THRESHOLD,
|
|
50
55
|
}),
|
|
51
56
|
})
|
|
52
57
|
const emit = defineEmits<Emits>()
|
|
@@ -66,6 +71,9 @@ const resolvedFrameStyle = computed(() => {
|
|
|
66
71
|
backgroundColor: props.frameStyle?.backgroundColor || 'transparent',
|
|
67
72
|
}
|
|
68
73
|
})
|
|
74
|
+
const frameInset = computed(() =>
|
|
75
|
+
props.containFrameStroke ? resolvedFrameStyle.value.borderWidth / 2 : 0,
|
|
76
|
+
)
|
|
69
77
|
</script>
|
|
70
78
|
|
|
71
79
|
<template>
|
|
@@ -89,7 +97,6 @@ const resolvedFrameStyle = computed(() => {
|
|
|
89
97
|
:clean-view="cleanView"
|
|
90
98
|
:frame-number="frameNumber"
|
|
91
99
|
:frame-style="resolvedFrameStyle"
|
|
92
|
-
:zero-line="zeroLine"
|
|
93
100
|
/>
|
|
94
101
|
<WaveformTrackAxes
|
|
95
102
|
:track="track"
|
|
@@ -98,13 +105,17 @@ const resolvedFrameStyle = computed(() => {
|
|
|
98
105
|
:axes="axes"
|
|
99
106
|
:time-unit="timeUnit"
|
|
100
107
|
:y-label="yLabel"
|
|
108
|
+
:show-units="showAxisUnits"
|
|
109
|
+
:contain-y-axis-endpoints="containYAxisEndpoints"
|
|
101
110
|
/>
|
|
102
111
|
|
|
103
112
|
<rect
|
|
104
113
|
v-if="!track.isEmpty"
|
|
105
114
|
class="waveform-track__plot-frame waveform-chart__plot-frame"
|
|
106
|
-
:
|
|
107
|
-
:
|
|
115
|
+
:x="containFrameStroke ? frameInset : undefined"
|
|
116
|
+
:y="containFrameStroke ? frameInset : undefined"
|
|
117
|
+
:width="Math.max(0, (track.width ?? innerWidth) - frameInset * 2)"
|
|
118
|
+
:height="Math.max(0, track.height - frameInset * 2)"
|
|
108
119
|
fill="none"
|
|
109
120
|
:stroke="resolvedFrameStyle.borderColor"
|
|
110
121
|
:stroke-width="resolvedFrameStyle.borderWidth"
|
|
@@ -120,6 +131,13 @@ const resolvedFrameStyle = computed(() => {
|
|
|
120
131
|
/>
|
|
121
132
|
|
|
122
133
|
<WaveformSeriesLayer :track="track" :clip-path-id="clipPathId" />
|
|
134
|
+
<WaveformZeroLines
|
|
135
|
+
:track="track"
|
|
136
|
+
:clip-path-id="clipPathId"
|
|
137
|
+
:inner-width="innerWidth"
|
|
138
|
+
:clean-view="cleanView"
|
|
139
|
+
:zero-line="zeroLine"
|
|
140
|
+
/>
|
|
123
141
|
|
|
124
142
|
<rect
|
|
125
143
|
v-if="!track.isEmpty && track.hasVisibleSeries && displayMode === 'independent'"
|
|
@@ -15,9 +15,11 @@ interface Props {
|
|
|
15
15
|
axes?: WaveformAxesOptions
|
|
16
16
|
timeUnit: 's' | 'ms'
|
|
17
17
|
yLabel?: string
|
|
18
|
+
showUnits?: boolean
|
|
19
|
+
containYAxisEndpoints?: boolean
|
|
18
20
|
}
|
|
19
21
|
|
|
20
|
-
const props = defineProps<Props>()
|
|
22
|
+
const props = withDefaults(defineProps<Props>(), { showUnits: true })
|
|
21
23
|
const xAxisElement = ref<SVGGElement>()
|
|
22
24
|
const yAxisElements = ref<SVGGElement[]>([])
|
|
23
25
|
|
|
@@ -44,7 +46,7 @@ function renderAxes() {
|
|
|
44
46
|
props.track.yAxes.forEach((axis, index) => {
|
|
45
47
|
const element = yAxisElements.value[index]
|
|
46
48
|
if (!element) return
|
|
47
|
-
const unit = axis.seriesList[0]?.unit
|
|
49
|
+
const unit = props.showUnits ? axis.seriesList[0]?.unit : undefined
|
|
48
50
|
const yAxis = (axis.side === 'left' ? axisLeft(axis.scale) : axisRight(axis.scale))
|
|
49
51
|
.tickFormat((value) =>
|
|
50
52
|
formatYAxisTickLabel(
|
|
@@ -62,11 +64,18 @@ function renderAxes() {
|
|
|
62
64
|
const selection = select(element)
|
|
63
65
|
selection.call(yAxis)
|
|
64
66
|
const lowestTick = Math.min(...axis.tickValues)
|
|
67
|
+
const highestTick = props.containYAxisEndpoints ? Math.max(...axis.tickValues) : undefined
|
|
65
68
|
selection
|
|
66
69
|
.selectAll<SVGTextElement, number>('.tick text')
|
|
67
70
|
.attr('y', null)
|
|
68
|
-
.attr('dy', (value) => (value === lowestTick ? '0' : '0.32em'))
|
|
69
|
-
.attr('dominant-baseline', (value) =>
|
|
71
|
+
.attr('dy', (value) => (value === lowestTick || value === highestTick ? '0' : '0.32em'))
|
|
72
|
+
.attr('dominant-baseline', (value) =>
|
|
73
|
+
value === lowestTick
|
|
74
|
+
? 'text-after-edge'
|
|
75
|
+
: value === highestTick
|
|
76
|
+
? 'text-before-edge'
|
|
77
|
+
: null,
|
|
78
|
+
)
|
|
70
79
|
selection
|
|
71
80
|
.selectAll('path.domain')
|
|
72
81
|
.attr('display', props.axes?.y?.lineVisible === false ? 'none' : null)
|
|
@@ -83,7 +92,7 @@ function renderAxes() {
|
|
|
83
92
|
props.track.xScale.domain() as [number, number],
|
|
84
93
|
props.timeUnit,
|
|
85
94
|
'tick',
|
|
86
|
-
props.axes?.x?.labelFormatter,
|
|
95
|
+
props.axes?.x?.labelFormatter ?? props.track.xAxisLabelFormatter,
|
|
87
96
|
),
|
|
88
97
|
)
|
|
89
98
|
.tickSize(-4)
|
|
@@ -107,6 +116,8 @@ watch(
|
|
|
107
116
|
() => props.track.xAxisTickValues,
|
|
108
117
|
() => props.track.yAxisTickValues,
|
|
109
118
|
() => props.timeUnit,
|
|
119
|
+
() => props.showUnits,
|
|
120
|
+
() => props.containYAxisEndpoints,
|
|
110
121
|
() => props.axes?.x?.labelFormatter,
|
|
111
122
|
() => props.axes?.x?.lineVisible,
|
|
112
123
|
() => props.axes?.y?.lineVisible,
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import type {
|
|
3
|
-
import type { TrackLayout, WaveformYAxisLayout } from '../core/types'
|
|
2
|
+
import type { TrackLayout } from '../core/types'
|
|
4
3
|
|
|
5
4
|
interface Props {
|
|
6
5
|
track: TrackLayout
|
|
@@ -11,18 +10,9 @@ interface Props {
|
|
|
11
10
|
frameStyle: {
|
|
12
11
|
backgroundColor: string
|
|
13
12
|
}
|
|
14
|
-
zeroLine: Required<Pick<WaveformZeroLineOptions, 'color' | 'width' | 'dash'>> & {
|
|
15
|
-
visible: boolean
|
|
16
|
-
}
|
|
17
13
|
}
|
|
18
14
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
function zeroLineY(axis: WaveformYAxisLayout): number | null {
|
|
22
|
-
const [minimum, maximum] = axis.scale.domain()
|
|
23
|
-
if (!props.zeroLine.visible || minimum > 0 || maximum < 0) return null
|
|
24
|
-
return axis.scale(0)
|
|
25
|
-
}
|
|
15
|
+
defineProps<Props>()
|
|
26
16
|
</script>
|
|
27
17
|
|
|
28
18
|
<template>
|
|
@@ -98,28 +88,6 @@ function zeroLineY(axis: WaveformYAxisLayout): number | null {
|
|
|
98
88
|
</g>
|
|
99
89
|
</g>
|
|
100
90
|
|
|
101
|
-
<g
|
|
102
|
-
v-if="!track.isEmpty && track.hasVisibleSeries && zeroLine.visible && !cleanView"
|
|
103
|
-
class="waveform-track__zero-lines waveform-chart__zero-lines"
|
|
104
|
-
:clip-path="`url(#${clipPathId}-${track.index})`"
|
|
105
|
-
aria-hidden="true"
|
|
106
|
-
>
|
|
107
|
-
<template v-for="axis in track.yAxes" :key="`zero-line-${track.index}-${axis.index}`">
|
|
108
|
-
<line
|
|
109
|
-
v-if="zeroLineY(axis) !== null"
|
|
110
|
-
class="waveform-track__zero-line waveform-chart__zero-line"
|
|
111
|
-
:data-y-axis-index="axis.index"
|
|
112
|
-
x1="0"
|
|
113
|
-
:x2="track.width ?? innerWidth"
|
|
114
|
-
:y1="zeroLineY(axis) ?? 0"
|
|
115
|
-
:y2="zeroLineY(axis) ?? 0"
|
|
116
|
-
:stroke="zeroLine.color"
|
|
117
|
-
:stroke-width="zeroLine.width"
|
|
118
|
-
:stroke-dasharray="zeroLine.dash || undefined"
|
|
119
|
-
/>
|
|
120
|
-
</template>
|
|
121
|
-
</g>
|
|
122
|
-
|
|
123
91
|
<text
|
|
124
92
|
v-if="!track.isEmpty && track.hasVisibleSeries && frameNumber !== undefined && !cleanView"
|
|
125
93
|
class="waveform-track__watermark waveform-chart__watermark"
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { WaveformZeroLineOptions } from '../../types'
|
|
3
|
+
import type { TrackLayout, WaveformYAxisLayout } from '../core/types'
|
|
4
|
+
|
|
5
|
+
const props = defineProps<{
|
|
6
|
+
track: TrackLayout
|
|
7
|
+
clipPathId: string
|
|
8
|
+
innerWidth: number
|
|
9
|
+
cleanView: boolean
|
|
10
|
+
zeroLine: Required<WaveformZeroLineOptions>
|
|
11
|
+
}>()
|
|
12
|
+
|
|
13
|
+
function zeroLineY(axis: WaveformYAxisLayout): number | null {
|
|
14
|
+
const [minimum, maximum] = axis.scale.domain()
|
|
15
|
+
const tickInterval = Math.abs(axis.tickValues[1] - axis.tickValues[0])
|
|
16
|
+
const margin = tickInterval * props.zeroLine.boundaryThreshold
|
|
17
|
+
if (
|
|
18
|
+
!props.zeroLine.visible ||
|
|
19
|
+
minimum >= 0 ||
|
|
20
|
+
maximum <= 0 ||
|
|
21
|
+
-minimum < margin ||
|
|
22
|
+
maximum < margin
|
|
23
|
+
)
|
|
24
|
+
return null
|
|
25
|
+
return axis.scale(0)
|
|
26
|
+
}
|
|
27
|
+
</script>
|
|
28
|
+
|
|
29
|
+
<template>
|
|
30
|
+
<g
|
|
31
|
+
v-if="!track.isEmpty && track.hasVisibleSeries && zeroLine.visible && !cleanView"
|
|
32
|
+
class="waveform-track__zero-lines waveform-chart__zero-lines"
|
|
33
|
+
:clip-path="`url(#${clipPathId}-${track.index})`"
|
|
34
|
+
aria-hidden="true"
|
|
35
|
+
pointer-events="none"
|
|
36
|
+
>
|
|
37
|
+
<template v-for="axis in track.yAxes" :key="`zero-line-${track.index}-${axis.index}`">
|
|
38
|
+
<line
|
|
39
|
+
v-if="zeroLineY(axis) !== null"
|
|
40
|
+
class="waveform-track__zero-line waveform-chart__zero-line"
|
|
41
|
+
:data-y-axis-index="axis.index"
|
|
42
|
+
x1="0"
|
|
43
|
+
:x2="track.width ?? innerWidth"
|
|
44
|
+
:y1="zeroLineY(axis) ?? 0"
|
|
45
|
+
:y2="zeroLineY(axis) ?? 0"
|
|
46
|
+
:stroke="zeroLine.color"
|
|
47
|
+
:stroke-opacity="zeroLine.opacity"
|
|
48
|
+
:stroke-width="zeroLine.width"
|
|
49
|
+
:stroke-dasharray="zeroLine.dash || undefined"
|
|
50
|
+
/>
|
|
51
|
+
</template>
|
|
52
|
+
</g>
|
|
53
|
+
</template>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// Source: 13921.txt, X(ms), 2M:13921:V22ca_TFN(V). Preserve all 1,000 samples.
|
|
2
|
+
// prettier-ignore
|
|
3
|
+
export const recordedDampedPoints: number[][] = [[-4000,184.7562],[-3989.99,-189.8833],[-3979.98,181.4603],[-3969.97,-186.9535],[-3959.96,178.8968],[-3949.95,-188.6625],[-3939.941,188.5405],[-3929.931,-190.4936],[-3919.921,183.9017],[-3909.911,-181.4603],[-3899.901,183.0472],[-3889.891,-187.4418],[-3879.881,193.4234],[-3869.871,-192.813],[-3859.861,186.4652],[-3849.851,-194.0337],[-3839.841,186.099],[-3829.832,-184.6342],[-3819.822,181.4603],[-3809.812,-187.3198],[-3799.802,183.2914],[-3789.792,-185.977],[-3779.782,184.6342],[-3769.772,-188.2963],[-3759.762,190.4936],[-3749.752,-185.0004],[-3739.742,194.8882],[-3729.732,-186.8315],[-3719.723,178.6526],[-3709.713,-186.7094],[-3699.703,185.6107],[-3689.693,-190.8598],[-3679.683,188.1743],[-3669.673,-190.8598],[-3659.663,191.4702],[-3649.653,-191.104],[-3639.643,190.4936],[-3629.633,-187.0756],[-3619.623,185.8549],[-3609.614,-191.104],[-3599.604,191.9585],[-3589.594,-191.104],[-3579.584,192.3247],[-3569.574,-186.7094],[-3559.564,176.5774],[-3549.554,-190.3716],[-3539.544,185.3666],[-3529.534,-191.2261],[-3519.524,193.5454],[-3509.514,-192.2026],[-3499.505,192.4468],[-3489.495,-193.5454],[-3479.485,189.395],[-3469.475,-192.0806],[-3459.465,178.4085],[-3449.455,-187.808],[-3439.445,184.1459],[-3429.435,-198.3062],[-3419.425,180.972],[-3409.415,-191.2261],[-3399.405,192.2026],[-3389.396,-194.1558],[-3379.386,195.2544],[-3369.376,-188.6625],[-3359.366,183.1693],[-3349.356,-178.5306],[-3339.346,182.8031],[-3329.336,-204.1657],[-3319.326,188.9067],[-3309.316,-192.813],[-3299.306,193.0571],[-3289.296,-189.5171],[-3279.286,184.5121],[-3269.277,-185.1225],[-3259.267,177.4319],[-3249.257,-186.4652],[-3239.247,185.4887],[-3229.237,-195.8648],[-3219.227,187.3198],[-3209.217,-189.8833],[-3199.207,192.3247],[-3189.197,-188.0522],[-3179.187,189.1508],[-3169.177,-189.7612],[-3159.168,193.5454],[-3149.158,-191.7144],[-3139.148,187.4418],[-3129.138,-202.5788],[-3119.128,191.5923],[-3109.118,-189.395],[-3099.108,191.7144],[-3089.098,-200.7477],[-3079.088,194.0337],[-3069.078,-197.2076],[-3059.068,196.9635],[-3049.059,-198.6725],[-3039.049,202.2126],[-3029.039,-195.2544],[-3019.029,196.3531],[-3009.019,-189.0288],[-2999.009,195.8648],[-2988.999,-206.363],[-2978.989,197.5738],[-2968.979,-191.5923],[-2958.969,198.1842],[-2948.959,-198.1842],[-2938.95,204.0436],[-2928.94,-193.3013],[-2918.93,193.0571],[-2908.92,-195.3765],[-2898.91,195.4986],[-2888.9,-196.231],[-2878.89,191.5923],[-2868.88,-192.6909],[-2858.87,193.9117],[-2848.86,-200.1373],[-2838.85,196.231],[-2828.841,-184.1459],[-2818.831,190.3716],[-2808.821,-196.231],[-2798.811,196.5972],[-2788.801,-202.3346],[-2778.791,182.8031],[-2768.781,-192.813],[-2758.771,196.231],[-2748.761,-198.5504],[-2738.751,206.8513],[-2728.741,-197.6959],[-2718.732,191.104],[-2708.722,-194.7662],[-2698.712,192.9351],[-2688.702,-199.1608],[-2678.692,188.7846],[-2668.682,-197.6959],[-2658.672,204.7761],[-2648.662,-203.5554],[-2638.652,208.4382],[-2628.642,-193.0571],[-2618.632,189.6391],[-2608.623,-196.7193],[-2598.613,201.8463],[-2588.603,-203.4333],[-2578.593,195.3765],[-2568.583,-195.7427],[-2558.573,193.6675],[-2548.563,-205.0202],[-2538.553,197.2076],[-2528.543,-199.2828],[-2518.533,186.2211],[-2508.523,-198.1842],[-2498.514,202.945],[-2488.504,-200.9918],[-2478.494,193.3013],[-2468.484,-197.2076],[-2458.474,197.818],[-2448.464,-205.1423],[-2438.454,195.0103],[-2428.444,-203.7995],[-2418.434,194.2779],[-2408.424,-196.8414],[-2398.414,205.0202],[-2388.405,-192.9351],[-2378.395,190.9819],[-2368.385,-198.3062],[-2358.375,209.781],[-2348.365,-205.1423],[-2338.355,201.7243],[-2328.345,-194.6441],[-2318.335,193.5454],[-2308.325,-196.7193],[-2298.315,193.7896],[-2288.305,-193.0571],[-2278.296,196.7193],[-2268.286,-199.1608],[-2258.276,201.3581],[-2248.266,-209.4148],[-2238.256,203.7995],[-2228.246,-199.527],[-2218.236,195.4986],[-2208.226,-194.6441],[-2198.216,199.8932],[-2188.206,-194.0337],[-2178.196,208.3162],[-2168.187,-201.6022],[-2158.177,209.4148],[-2148.167,-209.4148],[-2138.157,198.4283],[-2128.147,-217.3495],[-2118.137,194.3999],[-2108.127,-200.5035],[-2098.117,205.7527],[-2088.107,-198.7945],[-2078.097,214.1756],[-2068.087,-213.1991],[-2058.077,211.368],[-2048.068,-208.8045],[-2038.058,203.0671],[-2028.048,-196.8414],[-2018.038,207.95],[-2008.028,-212.5887],[-1998.018,204.654],[-1988.008,-204.1657],[-1977.998,222.7207],[-1967.988,-203.4333],[-1957.978,210.7576],[-1947.968,-211.0018],[-1937.959,195.3765],[-1927.949,-195.8648],[-1917.939,198.0621],[-1907.929,-205.2644],[-1897.919,195.2544],[-1887.909,-197.818],[-1877.899,201.7243],[-1867.889,-208.4382],[-1857.879,210.7576],[-1847.869,-205.9968],[-1837.859,200.9918],[-1827.85,-198.6725],[-1817.84,200.2594],[-1807.83,-205.8747],[-1797.82,203.3112],[-1787.81,-203.4333],[-1777.8,214.4198],[-1767.79,-212.4666],[-1757.78,209.1707],[-1747.77,-203.4333],[-1737.76,201.7243],[-1727.75,-197.4517],[-1717.741,201.9684],[-1707.731,-206.363],[-1697.721,209.9031],[-1687.711,-201.8463],[-1677.701,203.9216],[-1667.691,-210.8797],[-1657.681,209.0486],[-1647.671,-204.654],[-1637.661,203.3112],[-1627.651,-195.2544],[-1617.641,213.1991],[-1607.632,-201.9684],[-1597.622,204.0436],[-1587.612,-197.5738],[-1577.602,214.4198],[-1567.592,-214.9081],[-1557.582,205.7527],[-1547.572,-206.8513],[-1537.562,206.7292],[-1527.552,-201.7243],[-1517.542,210.6355],[-1507.532,-207.95],[-1497.523,204.7761],[-1487.513,-202.4567],[-1477.503,215.8846],[-1467.493,-217.1054],[-1457.483,209.4148],[-1447.473,-209.5369],[-1437.463,206.7292],[-1427.453,-209.781],[-1417.443,216.9833],[-1407.433,-212.2225],[-1397.423,208.072],[-1387.414,-209.781],[-1377.404,206.8513],[-1367.394,-208.072],[-1357.384,207.4617],[-1347.374,-208.4382],[-1337.364,196.7193],[-1327.354,-213.4432],[-1317.344,207.3396],[-1307.334,-205.1423],[-1297.324,210.6355],[-1287.314,-204.5319],[-1277.305,210.0252],[-1267.295,-211.1238],[-1257.285,210.1472],[-1247.275,-205.6306],[-1237.265,202.2126],[-1227.255,-208.9265],[-1217.245,208.8045],[-1207.235,-206.4851],[-1197.225,219.5468],[-1187.215,-215.0301],[-1177.205,213.1991],[-1167.196,-214.6639],[-1157.186,208.6824],[-1147.176,-205.7527],[-1137.166,210.5135],[-1127.156,-205.3864],[-1117.146,209.659],[-1107.136,-208.5603],[-1097.126,224.918],[-1087.116,-212.1004],[-1077.106,214.6639],[-1067.096,-215.1522],[-1057.087,207.4617],[-1047.077,-203.7995],[-1037.067,211.6121],[-1027.057,-215.0301],[-1017.047,223.331],[-1007.037,-213.9315],[-997.0271,225.2842],[-987.0171,-217.2274],[-977.0072,205.3864],[-966.9973,-215.3964],[-956.9874,205.9968],[-946.9775,-198.4283],[-936.9676,203.5554],[-926.9577,-216.495],[-916.9478,210.3914],[-906.9379,-217.8378],[-896.928,218.8144],[-886.918,-221.5],[-876.9081,197.6959],[-866.8982,-205.2644],[-856.8883,202.8229],[-846.8784,-211.0018],[-836.8685,214.5418],[-826.8586,-222.2324],[-816.8487,227.1153],[-806.8388,-216.8612],[-796.8289,218.4482],[-786.819,-215.6405],[-776.809,209.659],[-766.7991,-209.1707],[-756.7892,200.7477],[-746.7793,-210.6355],[-736.7694,214.5418],[-726.7595,-217.7157],[-716.7496,219.791],[-706.7397,-213.1991],[-696.7298,221.7441],[-686.7199,-222.1103],[-676.7099,198.7945],[-666.7,-210.7576],[-656.6901,212.9549],[-646.6802,-215.7626],[-636.6703,225.5283],[-626.6604,-217.2274],[-616.6505,230.5333],[-606.6406,-218.3261],[-596.6307,221.622],[-586.6208,-218.9364],[-576.6108,205.7527],[-566.6009,-213.077],[-556.591,216.495],[-546.5811,-218.8144],[-536.5712,223.4531],[-526.5613,-216.495],[-516.5514,222.8428],[-506.5415,-212.1004],[-496.5316,214.2977],[-486.5217,-224.1855],[-476.5117,207.2175],[-466.5018,-219.0585],[-456.4919,214.1756],[-446.482,-217.5937],[-436.4721,229.0684],[-426.4622,-211.6121],[-416.4523,221.5],[-406.4424,-217.2274],[-396.4325,208.6824],[-386.4226,-211.8563],[-376.4126,210.5135],[-366.4027,-210.7576],[-356.3928,216.7391],[-346.3829,-213.8094],[-336.373,220.7675],[-326.3631,-212.9549],[-316.3532,216.8612],[-306.3433,-212.3445],[-296.3334,204.7761],[-286.3235,-211.7342],[-276.3135,208.6824],[-266.3036,-219.4247],[-256.2937,216.2509],[-246.2838,-218.204],[-236.2739,219.913],[-226.264,-218.5702],[-216.2541,222.1103],[-206.2442,-224.5518],[-196.2343,222.5986],[-186.2244,-212.7108],[-176.2145,229.3126],[-166.2045,-220.0351],[-156.1946,216.495],[-146.1847,-218.9364],[-136.1748,220.5234],[-126.1649,-214.786],[-116.155,215.6405],[-106.1451,-225.0401],[-96.13517,227.2374],[-86.12526,-217.1054],[-76.11535,208.4382],[-66.10544,-217.4716],[-56.09553,223.6973],[-46.08562,-224.7959],[-36.07571,228.9464],[-26.0658,-222.1103],[-16.05589,224.5518],[-6.045985,-224.0635],[3.963925,222.3545],[13.97383,-211.368],[23.98374,212.4666],[33.99365,-210.7576],[44.00356,226.5049],[54.01347,-222.8428],[64.02338,230.5333],[74.03329,-222.2324],[84.0432,220.4013],[94.05311,-227.8477],[104.063,214.0536],[114.0729,-215.1522],[124.0828,223.8193],[134.0928,-221.7441],[144.1027,224.5518],[154.1126,-221.3779],[164.1225,228.8243],[174.1324,-224.3076],[184.1423,232.6085],[194.1522,-223.209],[204.1621,222.7207],[214.172,-217.8378],[224.1819,219.4247],[234.1919,-219.6689],[244.2018,228.0919],[254.2117,-224.4297],[264.2216,226.9932],[274.2315,-222.5986],[284.2414,227.7256],[294.2513,-219.913],[304.2612,223.331],[314.2711,-213.4432],[324.281,215.3964],[334.2909,-220.5234],[344.3009,228.5801],[354.3108,-220.4013],[364.3207,225.4063],[374.3306,-229.3126],[384.3405,232.1202],[394.3504,-220.4013],[404.3603,221.8662],[414.3702,-215.3964],[424.3801,221.9883],[434.39,-223.4531],[444.4,230.045],[454.4099,-228.2139],[464.4198,226.7491],[474.4297,-226.3828],[484.4396,223.8193],[494.4495,-222.9648],[504.4594,225.1621],[514.4693,-218.3261],[524.4792,221.8662],[534.4891,-227.6036],[544.4991,237.8576],[554.509,-229.4347],[564.5189,219.6689],[574.5288,-228.4581],[584.5387,213.077],[594.5486,-216.0067],[604.5585,221.9883],[614.5684,-207.3396],[624.5783,220.1572],[634.5882,-229.1905],[644.5982,230.1671],[654.6081,-231.9982],[664.618,224.7959],[674.6279,-228.9464],[684.6378,222.1103],[694.6477,-221.0117],[704.6576,233.5851],[714.6675,-217.4716],[724.6774,222.3545],[734.6873,-226.2608],[744.6973,232.4865],[754.7072,-233.9513],[764.7171,228.336],[774.727,-231.1437],[784.7369,227.6036],[794.7468,-224.918],[804.7567,230.045],[814.7666,-219.1806],[824.7765,227.7256],[834.7864,-225.5283],[844.7963,228.9464],[854.8063,-227.1153],[864.8162,224.6738],[874.8261,-230.1671],[884.836,228.5801],[894.8459,-225.7725],[904.8558,233.9513],[914.8657,-217.5937],[924.8756,230.8995],[934.8855,-232.6085],[944.8954,240.6653],[954.9054,-228.9464],[964.9153,234.9279],[974.9252,-227.2374],[984.9351,231.8761],[994.945,-232.4865],[1004.955,229.1905],[1014.965,-224.1855],[1024.975,231.3878],[1034.985,-235.05],[1044.995,236.8811],[1055.004,-227.4815],[1065.014,231.2657],[1075.024,-227.4815],[1085.034,228.4581],[1095.044,-233.463],[1105.054,238.1018],[1115.064,-220.0351],[1125.074,228.0919],[1135.084,-233.2189],[1145.094,233.2189],[1155.104,-224.6738],[1165.113,231.754],[1175.123,-226.0166],[1185.133,230.4112],[1195.143,-237.0031],[1205.153,230.045],[1215.163,-227.1153],[1225.173,236.6369],[1235.183,-242.8626],[1245.193,231.754],[1255.203,-229.6788],[1265.213,230.7774],[1275.222,-230.1671],[1285.232,231.5099],[1295.242,-230.7774],[1305.252,228.9464],[1315.262,-230.2892],[1325.272,232.9747],[1335.282,-239.5666],[1345.292,228.336],[1355.302,-227.7256],[1365.312,228.8243],[1375.322,-227.4815],[1385.331,232.2423],[1395.341,-240.4211],[1405.351,239.4446],[1415.361,-226.7491],[1425.371,234.8058],[1435.381,-240.5432],[1445.391,228.8243],[1455.401,-226.7491],[1465.411,4.577707],[1475.421,-1.770047],[1485.431,0.7934691],[1495.44,0.671397],[1505.45,0.4272526],[1515.46,0.7934691],[1525.47,1.281758],[1535.48,1.281758],[1545.49,1.281758],[1555.5,0.671397],[1565.51,0.9155413],[1575.52,0.7934691],[1585.53,0.4272526],[1595.54,0.7934691],[1605.549,1.281758],[1615.559,0.5493248],[1625.569,0.671397],[1635.579,0.7934691],[1645.589,0.9155413],[1655.599,1.281758],[1665.609,0.7934691],[1675.619,0.5493248],[1685.629,0.7934691],[1695.639,0.7934691],[1705.649,0.5493248],[1715.659,0.7934691],[1725.668,0.671397],[1735.678,0.671397],[1745.688,0.7934691],[1755.698,0.671397],[1765.708,0.671397],[1775.718,1.159686],[1785.728,0.7934691],[1795.738,0.9155413],[1805.748,0.4272526],[1815.758,0.7934691],[1825.768,1.281758],[1835.777,0.7934691],[1845.787,0.671397],[1855.797,0.7934691],[1865.807,0.5493248],[1875.817,0.1831083],[1885.827,1.037613],[1895.837,1.037613],[1905.847,0.3051804],[1915.857,1.037613],[1925.867,0.4272526],[1935.877,0.3051804],[1945.886,0.5493248],[1955.896,0.9155413],[1965.906,0.5493248],[1975.916,0.9155413],[1985.926,0.9155413],[1995.936,1.037613],[2005.946,0.671397],[2015.956,0.7934691],[2025.966,0.9155413],[2035.976,0.4272526],[2045.986,0.5493248],[2055.995,0.7934691],[2066.005,0.5493248],[2076.015,1.037613],[2086.025,0.7934691],[2096.035,0.7934691],[2106.045,0.5493248],[2116.055,0.7934691],[2126.065,0.671397],[2136.075,0.671397],[2146.085,0.671397],[2156.095,1.159686],[2166.104,1.037613],[2176.114,0.671397],[2186.124,0.671397],[2196.134,0.9155413],[2206.144,0.671397],[2216.154,0.4272526],[2226.164,0.671397],[2236.174,0.3051804],[2246.184,0.4272526],[2256.194,0.671397],[2266.204,0.9155413],[2276.213,0.5493248],[2286.223,0.671397],[2296.233,0.5493248],[2306.243,0.7934691],[2316.253,1.037613],[2326.263,0.5493248],[2336.273,1.159686],[2346.283,1.037613],[2356.293,0.5493248],[2366.303,0.3051804],[2376.313,0.671397],[2386.322,1.40383],[2396.332,0.5493248],[2406.342,0.5493248],[2416.352,0.3051804],[2426.362,1.037613],[2436.372,1.037613],[2446.382,0.671397],[2456.392,1.40383],[2466.402,0.7934691],[2476.412,0.671397],[2486.422,0.4272526],[2496.431,1.037613],[2506.441,0.9155413],[2516.451,1.40383],[2526.461,0.671397],[2536.471,0.671397],[2546.481,1.037613],[2556.491,1.037613],[2566.501,0.9155413],[2576.511,1.281758],[2586.521,0.7934691],[2596.531,0.3051804],[2606.54,1.281758],[2616.55,0.7934691],[2626.56,1.037613],[2636.57,0.671397],[2646.58,1.037613],[2656.59,0.3051804],[2666.6,0.671397],[2676.61,0.4272526],[2686.62,0.9155413],[2696.63,1.037613],[2706.64,1.159686],[2716.649,0.9155413],[2726.659,0.9155413],[2736.669,1.281758],[2746.679,0.1831083],[2756.689,0.671397],[2766.699,0.1831083],[2776.709,0.4272526],[2786.719,0.3051804],[2796.729,0.3051804],[2806.739,0.7934691],[2816.749,0.671397],[2826.758,0.3051804],[2836.768,1.037613],[2846.778,1.281758],[2856.788,0.5493248],[2866.798,0.5493248],[2876.808,0.4272526],[2886.818,1.40383],[2896.828,0.1831083],[2906.838,0.671397],[2916.848,0.1831083],[2926.858,1.281758],[2936.867,0.3051804],[2946.877,0.4272526],[2956.887,0.3051804],[2966.897,0.5493248],[2976.907,0.4272526],[2986.917,0.7934691],[2996.927,0.7934691],[3006.937,1.281758],[3016.947,0.4272526],[3026.957,1.037613],[3036.967,0.9155413],[3046.977,0.4272526],[3056.986,0.7934691],[3066.996,0.7934691],[3077.006,0.4272526],[3087.016,0.7934691],[3097.026,1.037613],[3107.036,0.3051804],[3117.046,0.9155413],[3127.056,0.5493248],[3137.066,0.671397],[3147.076,0.7934691],[3157.086,0.671397],[3167.095,1.159686],[3177.105,0.671397],[3187.115,0.7934691],[3197.125,0.3051804],[3207.135,0.9155413],[3217.145,0.9155413],[3227.155,1.281758],[3237.165,1.037613],[3247.175,0.7934691],[3257.185,0.671397],[3267.195,0.1831083],[3277.204,0.9155413],[3287.214,0.9155413],[3297.224,1.281758],[3307.234,1.281758],[3317.244,0.7934691],[3327.254,0.3051804],[3337.264,0.5493248],[3347.274,0.4272526],[3357.284,1.159686],[3367.294,0.7934691],[3377.304,0.3051804],[3387.313,1.037613],[3397.323,0.671397],[3407.333,0.1831083],[3417.343,0.5493248],[3427.353,0.7934691],[3437.363,0.671397],[3447.373,0.7934691],[3457.383,0.671397],[3467.393,0.5493248],[3477.403,0.5493248],[3487.413,0.7934691],[3497.422,0.3051804],[3507.432,0.3051804],[3517.442,1.525902],[3527.452,0.671397],[3537.462,0.7934691],[3547.472,0.9155413],[3557.482,1.281758],[3567.492,1.281758],[3577.502,0.671397],[3587.512,0.5493248],[3597.522,0.9155413],[3607.531,0.3051804],[3617.541,0.7934691],[3627.551,0.5493248],[3637.561,1.281758],[3647.571,0.5493248],[3657.581,1.40383],[3667.591,0.5493248],[3677.601,0.671397],[3687.611,0.671397],[3697.621,1.037613],[3707.631,1.037613],[3717.64,0.671397],[3727.65,0.5493248],[3737.66,1.159686],[3747.67,0.7934691],[3757.68,0.9155413],[3767.69,0.1831083],[3777.7,1.159686],[3787.71,1.525902],[3797.72,0.7934691],[3807.73,1.037613],[3817.74,0.671397],[3827.749,0.671397],[3837.759,1.281758],[3847.769,0.7934691],[3857.779,0.5493248],[3867.789,0.7934691],[3877.799,0.5493248],[3887.809,1.037613],[3897.819,1.037613],[3907.829,0.5493248],[3917.839,0.7934691],[3927.849,1.281758],[3937.858,0.671397],[3947.868,0.5493248],[3957.878,0.671397],[3967.888,1.159686],[3977.898,1.037613],[3987.908,1.159686],[3997.918,0.7934691],[4007.928,0.9155413],[4017.938,0.9155413],[4027.948,0.7934691],[4037.958,0.671397],[4047.967,0.3051804],[4057.977,0.9155413],[4067.987,0.671397],[4077.997,1.037613],[4088.007,0.4272526],[4098.017,0.671397],[4108.027,0.671397],[4118.037,0.9155413],[4128.047,0.5493248],[4138.057,1.281758],[4148.067,1.037613],[4158.076,0.671397],[4168.086,1.037613],[4178.096,0.671397],[4188.106,0.5493248],[4198.116,1.159686],[4208.126,1.159686],[4218.136,1.037613],[4228.146,1.037613],[4238.156,0.4272526],[4248.166,0.9155413],[4258.176,0.5493248],[4268.186,0.7934691],[4278.195,0.5493248],[4288.205,1.037613],[4298.215,1.525902],[4308.225,0.5493248],[4318.235,0.671397],[4328.245,0.9155413],[4338.255,0.1831083],[4348.265,0.5493248],[4358.275,0.1831083],[4368.285,0.9155413],[4378.295,0.671397],[4388.304,1.40383],[4398.314,0.3051804],[4408.324,0.5493248],[4418.334,0.7934691],[4428.344,0.5493248],[4438.354,0.671397],[4448.364,0.5493248],[4458.374,0.4272526],[4468.384,0.7934691],[4478.394,0.7934691],[4488.404,0.3051804],[4498.413,0.671397],[4508.423,0.7934691],[4518.433,1.40383],[4528.443,0.7934691],[4538.453,1.037613],[4548.463,0.5493248],[4558.473,0.671397],[4568.483,1.159686],[4578.493,1.037613],[4588.503,0.5493248],[4598.513,1.159686],[4608.522,1.159686],[4618.532,0.3051804],[4628.542,0.7934691],[4638.552,0.671397],[4648.562,0.4272526],[4658.572,0.9155413],[4668.582,0.7934691],[4678.592,0.9155413],[4688.602,0.4272526],[4698.612,1.037613],[4708.622,0.671397],[4718.631,0.7934691],[4728.641,0.7934691],[4738.651,0.3051804],[4748.661,0.5493248],[4758.671,0.7934691],[4768.681,0.3051804],[4778.691,0.9155413],[4788.701,0.9155413],[4798.711,0.4272526],[4808.721,0.4272526],[4818.731,0.9155413],[4828.74,1.037613],[4838.75,0.7934691],[4848.76,1.40383],[4858.77,1.159686],[4868.78,0.9155413],[4878.79,0.06103609],[4888.8,0.7934691],[4898.81,0.671397],[4908.82,1.037613],[4918.83,1.037613],[4928.84,0.9155413],[4938.849,0.5493248],[4948.859,0.3051804],[4958.869,0.7934691],[4968.879,0.671397],[4978.889,0.671397],[4988.899,0.4272526],[4998.909,0.671397],[5008.919,0.5493248],[5018.929,0.9155413],[5028.939,0.7934691],[5038.949,1.037613],[5048.958,0.5493248],[5058.968,0.671397],[5068.978,1.159686],[5078.988,0.5493248],[5088.998,0.1831083],[5099.008,1.647974],[5109.018,0.9155413],[5119.028,1.037613],[5129.038,0.7934691],[5139.048,1.037613],[5149.058,0.671397],[5159.067,0.671397],[5169.077,1.037613],[5179.087,1.037613],[5189.097,0.06103609],[5199.107,1.40383],[5209.117,0.9155413],[5219.127,1.037613],[5229.137,0.3051804],[5239.147,1.037613],[5249.157,0.5493248],[5259.167,0.9155413],[5269.176,1.037613],[5279.186,0.7934691],[5289.196,0.5493248],[5299.206,0.671397],[5309.216,1.037613],[5319.226,1.647974],[5329.236,1.037613],[5339.246,0.9155413],[5349.256,0.671397],[5359.266,1.159686],[5369.276,1.037613],[5379.285,0.671397],[5389.295,0.9155413],[5399.305,0.5493248],[5409.315,1.159686],[5419.325,1.281758],[5429.335,0.5493248],[5439.345,0.7934691],[5449.355,0.671397],[5459.365,0.4272526],[5469.375,0.7934691],[5479.385,0.3051804],[5489.395,0.3051804],[5499.404,0.5493248],[5509.414,1.037613],[5519.424,1.037613],[5529.434,1.037613],[5539.444,1.281758],[5549.454,0.671397],[5559.464,1.159686],[5569.474,0.9155413],[5579.484,0.9155413],[5589.494,0.9155413],[5599.504,1.159686],[5609.513,0.9155413],[5619.523,1.281758],[5629.533,0.4272526],[5639.543,0.7934691],[5649.553,0.06103609],[5659.563,1.037613],[5669.573,0.671397],[5679.583,0.7934691],[5689.593,0.5493248],[5699.603,0.1831083],[5709.613,0.3051804],[5719.622,1.281758],[5729.632,0.7934691],[5739.642,0.671397],[5749.652,1.037613],[5759.662,1.159686],[5769.672,1.281758],[5779.682,0.4272526],[5789.692,0.4272526],[5799.702,0.5493248],[5809.712,0.5493248],[5819.722,1.159686],[5829.731,0.1831083],[5839.741,0.9155413],[5849.751,0.7934691],[5859.761,1.037613],[5869.771,0.5493248],[5879.781,0.9155413],[5889.791,0.5493248],[5899.801,0.5493248],[5909.811,0.7934691],[5919.821,0.4272526],[5929.831,1.037613],[5939.84,0.9155413],[5949.85,0.7934691],[5959.86,0.9155413],[5969.87,0.1831083],[5979.88,1.159686],[5989.89,0.5493248],[5999.9,1.037613]]
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { WaveformData, WaveformPoint, WaveformSeries } from '../types'
|
|
2
|
+
import { recordedDampedPoints } from './recordedDampedWaveform'
|
|
2
3
|
|
|
3
4
|
const POINT_COUNT = 1_000
|
|
4
5
|
const START_TIME = -5
|
|
@@ -6,6 +7,7 @@ const END_TIME = 5
|
|
|
6
7
|
const TWO_PI = Math.PI * 2
|
|
7
8
|
|
|
8
9
|
type SignalGenerator = (time: number, noise: number) => number
|
|
10
|
+
type SignalSource = SignalGenerator | number[][]
|
|
9
11
|
type ErrorGenerator = (
|
|
10
12
|
time: number,
|
|
11
13
|
value: number,
|
|
@@ -16,7 +18,7 @@ interface SimulatedSeriesDefinition extends Pick<
|
|
|
16
18
|
WaveformSeries,
|
|
17
19
|
'id' | 'trackId' | 'shotNo' | 'name' | 'unit' | 'color' | 'lineType' | 'pointType' | 'errorBar'
|
|
18
20
|
> {
|
|
19
|
-
signal:
|
|
21
|
+
signal: SignalSource
|
|
20
22
|
errors?: ErrorGenerator
|
|
21
23
|
minimumX?: number
|
|
22
24
|
}
|
|
@@ -30,14 +32,17 @@ function createSeededNoise(seed: number) {
|
|
|
30
32
|
}
|
|
31
33
|
|
|
32
34
|
function createPoints(
|
|
33
|
-
signal:
|
|
35
|
+
signal: SignalSource,
|
|
34
36
|
noise: () => number,
|
|
35
37
|
errors?: ErrorGenerator,
|
|
36
38
|
errorNoise: () => number = noise,
|
|
37
39
|
): WaveformPoint[] {
|
|
38
|
-
return Array.from({ length: POINT_COUNT }, (_, index) => {
|
|
40
|
+
return Array.from({ length: Array.isArray(signal) ? signal.length : POINT_COUNT }, (_, index) => {
|
|
39
41
|
const time = START_TIME + (index * (END_TIME - START_TIME)) / (POINT_COUNT - 1)
|
|
40
|
-
const
|
|
42
|
+
const sampleNoise = noise()
|
|
43
|
+
// The recorded TXT uses milliseconds; chart coordinates are always seconds.
|
|
44
|
+
if (Array.isArray(signal)) return { x: signal[index][0] / 1_000, y: signal[index][1] }
|
|
45
|
+
const value = signal(time, sampleNoise)
|
|
41
46
|
return {
|
|
42
47
|
x: time,
|
|
43
48
|
y: value,
|
|
@@ -98,15 +103,12 @@ const seriesDefinitions: SimulatedSeriesDefinition[] = [
|
|
|
98
103
|
},
|
|
99
104
|
{
|
|
100
105
|
id: 'simulated-damped',
|
|
101
|
-
shotNo: '
|
|
106
|
+
shotNo: '13921',
|
|
102
107
|
name: '阻尼振荡',
|
|
103
|
-
unit: '
|
|
108
|
+
unit: 'V',
|
|
104
109
|
lineType: 'linear',
|
|
105
110
|
pointType: 'none',
|
|
106
|
-
signal:
|
|
107
|
-
const elapsed = time + 5
|
|
108
|
-
return 2.4 * Math.exp(-elapsed * 0.28) * Math.sin(TWO_PI * 1.25 * elapsed)
|
|
109
|
-
},
|
|
111
|
+
signal: recordedDampedPoints,
|
|
110
112
|
},
|
|
111
113
|
{
|
|
112
114
|
id: 'simulated-step',
|
|
@@ -23,6 +23,7 @@ defineExpose({ resetViewport })
|
|
|
23
23
|
v-model:hidden-series-ids="model.hiddenSeriesIds"
|
|
24
24
|
:data="model.data"
|
|
25
25
|
:min-visible-points="2"
|
|
26
|
+
:integer-zoom="model.integerZoom"
|
|
26
27
|
:initial-x-domain="model.initialXDomain"
|
|
27
28
|
:x-domain-strategy="{ type: 'integer-ms', includeExplicit: true }"
|
|
28
29
|
:display-mode="model.displayMode"
|
|
@@ -66,6 +66,18 @@ const model = defineModel<DemoControlPanelModel>('model', { required: true })
|
|
|
66
66
|
aria-label="零值参考线线宽"
|
|
67
67
|
/>
|
|
68
68
|
</label>
|
|
69
|
+
<label class="frame-style-control">
|
|
70
|
+
<span>透明度</span>
|
|
71
|
+
<InputNumber
|
|
72
|
+
v-model:value="model.zeroLineOpacity"
|
|
73
|
+
:min="0"
|
|
74
|
+
:max="1"
|
|
75
|
+
:step="0.05"
|
|
76
|
+
:precision="2"
|
|
77
|
+
size="small"
|
|
78
|
+
aria-label="零值参考线透明度"
|
|
79
|
+
/>
|
|
80
|
+
</label>
|
|
69
81
|
<label class="frame-style-control">
|
|
70
82
|
<span>线型</span>
|
|
71
83
|
<Select
|
|
@@ -38,6 +38,10 @@ const model = defineModel<DemoControlPanelModel>('model', { required: true })
|
|
|
38
38
|
<h2>视图</h2>
|
|
39
39
|
<Button block aria-label="重置波形视图" @click="model.resetWaveformViewport"> 重置视图 </Button>
|
|
40
40
|
<div class="auxiliary-style-controls" style="margin-top: 10px">
|
|
41
|
+
<label class="frame-style-control frame-style-control--switch">
|
|
42
|
+
<span>整数缩放</span>
|
|
43
|
+
<Switch v-model:checked="model.integerZoom" size="small" aria-label="整数缩放" />
|
|
44
|
+
</label>
|
|
41
45
|
<label class="frame-style-control frame-style-control--switch">
|
|
42
46
|
<span>数值 Tooltip</span>
|
|
43
47
|
<Switch v-model:checked="model.showTooltip" size="small" aria-label="显示数值 Tooltip" />
|
package/src/demo/types.ts
CHANGED
|
@@ -27,6 +27,7 @@ export interface DemoControlPanelModel {
|
|
|
27
27
|
displayMode: WaveformDisplayMode
|
|
28
28
|
overlayMode: WaveformOverlayMode
|
|
29
29
|
showTooltip: boolean
|
|
30
|
+
integerZoom: boolean
|
|
30
31
|
plotMarginTop: number
|
|
31
32
|
plotMarginBottom: number
|
|
32
33
|
cleanView: boolean
|
|
@@ -38,6 +39,7 @@ export interface DemoControlPanelModel {
|
|
|
38
39
|
zeroLineVisible: boolean
|
|
39
40
|
zeroLineColor: string
|
|
40
41
|
zeroLineWidth: number
|
|
42
|
+
zeroLineOpacity: number
|
|
41
43
|
zeroLineDash: string
|
|
42
44
|
zeroLineDashOptions: Array<SelectOption<string>>
|
|
43
45
|
rowCount: number
|
|
@@ -101,6 +103,7 @@ export interface DemoChartModel {
|
|
|
101
103
|
cleanView: boolean
|
|
102
104
|
presentationMode: boolean
|
|
103
105
|
showTooltip: boolean
|
|
106
|
+
integerZoom: boolean
|
|
104
107
|
plotMargin: WaveformPlotMargin
|
|
105
108
|
zeroLine: WaveformZeroLineOptions
|
|
106
109
|
frameWatermarkVisible: boolean
|
package/src/index.ts
CHANGED
|
@@ -5,17 +5,21 @@
|
|
|
5
5
|
|
|
6
6
|
// Vue 组件
|
|
7
7
|
export { default as WaveformChart } from './components/WaveformChart.vue'
|
|
8
|
+
export type { WaveformChartProps } from './components/core/waveformChartTypes'
|
|
8
9
|
|
|
9
10
|
// 类型定义
|
|
10
11
|
export type {
|
|
11
12
|
// 图表类型
|
|
12
13
|
WaveformPoint,
|
|
13
14
|
WaveformDisplayMode,
|
|
15
|
+
WaveformUnitDisplayMode,
|
|
16
|
+
WaveformLayoutPreset,
|
|
14
17
|
WaveformOverlayMode,
|
|
15
18
|
WaveformInteractionMode,
|
|
16
19
|
WaveformXDomainStrategy,
|
|
17
20
|
WaveformZoomIntentPayload,
|
|
18
21
|
WaveformZoomEndPayload,
|
|
22
|
+
WaveformPanEndPayload,
|
|
19
23
|
WaveformZoomResetPayload,
|
|
20
24
|
WaveformAnnotationStyle,
|
|
21
25
|
WaveformAnnotation,
|
package/src/styles.css
CHANGED
|
@@ -329,7 +329,7 @@ body {
|
|
|
329
329
|
|
|
330
330
|
.mobile-control-toggle {
|
|
331
331
|
position: fixed;
|
|
332
|
-
top:
|
|
332
|
+
top: 58px;
|
|
333
333
|
left: 10px;
|
|
334
334
|
z-index: 20;
|
|
335
335
|
display: inline-flex;
|
|
@@ -339,7 +339,7 @@ body {
|
|
|
339
339
|
.control-backdrop {
|
|
340
340
|
position: fixed;
|
|
341
341
|
inset: 0 0 0 min(300px, calc(100vw - 48px));
|
|
342
|
-
z-index:
|
|
342
|
+
z-index: 44;
|
|
343
343
|
display: block;
|
|
344
344
|
width: auto;
|
|
345
345
|
height: 100%;
|
|
@@ -351,7 +351,7 @@ body {
|
|
|
351
351
|
.control-panel {
|
|
352
352
|
position: fixed;
|
|
353
353
|
inset: 0 auto 0 0;
|
|
354
|
-
z-index:
|
|
354
|
+
z-index: 50;
|
|
355
355
|
width: min(300px, calc(100vw - 48px));
|
|
356
356
|
visibility: hidden;
|
|
357
357
|
border-radius: 0 6px 6px 0;
|