waveform-analysis 0.1.77 → 0.1.78
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 +10 -3
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/types/components/core/useWaveformChartController.d.ts +1 -0
- package/dist/types/components/core/useWaveformLayout.d.ts +1 -0
- package/package.json +1 -1
- package/src/components/WaveformChartView.vue +3 -2
- package/src/components/animation/trackPresentation.ts +1 -1
- package/src/components/controls/useChartCommands.ts +9 -7
- package/src/components/core/useWaveformChartController.ts +1 -2
- package/src/components/core/useWaveformData.ts +13 -1
- package/src/components/core/useWaveformLayout.ts +4 -0
- package/src/components/interaction/zoomConstraints.ts +2 -0
- package/src/demo/remoteWaveformLoader.ts +10 -5
|
@@ -274,6 +274,7 @@ export declare function useWaveformChartController(inputProps: ResolvedWaveformC
|
|
|
274
274
|
innerWidth: number;
|
|
275
275
|
hasVisibleWaveformData: boolean;
|
|
276
276
|
hasWaveformData: boolean;
|
|
277
|
+
hasWaveformSamples: boolean;
|
|
277
278
|
hasChartArea: boolean;
|
|
278
279
|
resolvedXLabel: string;
|
|
279
280
|
activeInteractionMode: import("..").WaveformInteractionMode | undefined;
|
|
@@ -35,6 +35,7 @@ export declare function useWaveformLayout(context: LayoutContext): {
|
|
|
35
35
|
innerWidth: ComputedRef<number>;
|
|
36
36
|
hasVisibleWaveformData: ComputedRef<boolean>;
|
|
37
37
|
hasWaveformData: ComputedRef<boolean>;
|
|
38
|
+
hasWaveformSamples: ComputedRef<boolean>;
|
|
38
39
|
hasChartArea: ComputedRef<boolean>;
|
|
39
40
|
resolvedXLabel: ComputedRef<string>;
|
|
40
41
|
activeInteractionMode: ComputedRef<import("..").WaveformInteractionMode | undefined>;
|
package/package.json
CHANGED
|
@@ -46,6 +46,7 @@ const {
|
|
|
46
46
|
chartWidth,
|
|
47
47
|
drawingHeight,
|
|
48
48
|
hasWaveformData,
|
|
49
|
+
hasWaveformSamples,
|
|
49
50
|
trackLayouts,
|
|
50
51
|
presentationTracks,
|
|
51
52
|
presentationAnnotations,
|
|
@@ -186,7 +187,7 @@ function handleChartPointerLeave() {
|
|
|
186
187
|
:width="chartWidth"
|
|
187
188
|
:height="drawingHeight"
|
|
188
189
|
role="img"
|
|
189
|
-
:aria-label="
|
|
190
|
+
:aria-label="hasWaveformSamples ? '波形折线图' : '暂无波形数据'"
|
|
190
191
|
>
|
|
191
192
|
<defs>
|
|
192
193
|
<clipPath
|
|
@@ -343,7 +344,7 @@ function handleChartPointerLeave() {
|
|
|
343
344
|
</text>
|
|
344
345
|
|
|
345
346
|
<text
|
|
346
|
-
v-if="hasChartArea && !
|
|
347
|
+
v-if="hasChartArea && !hasWaveformSamples"
|
|
347
348
|
class="waveform-chart__empty"
|
|
348
349
|
:x="chartWidth / 2"
|
|
349
350
|
:y="drawingHeight / 2"
|
|
@@ -92,7 +92,7 @@ export function transitionTrack(
|
|
|
92
92
|
const series = new Map<string, SeriesGeometry>()
|
|
93
93
|
for (const [id, next] of to.series) {
|
|
94
94
|
const previous = from.series.get(id)
|
|
95
|
-
if (!previous) {
|
|
95
|
+
if (!previous || (next.path.series.source?.length ?? next.path.series.points.length) === 0) {
|
|
96
96
|
series.set(id, next)
|
|
97
97
|
continue
|
|
98
98
|
}
|
|
@@ -122,13 +122,15 @@ export function useChartCommands(c: Context) {
|
|
|
122
122
|
? tracks.some((t) => c.independentYDomains.value[t.index])
|
|
123
123
|
: Object.keys(c.sharedYDomains.value).length > 0)
|
|
124
124
|
const boundaryChanged = tracks.length && !same(bounds, boundary(tracks))
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
? '
|
|
129
|
-
:
|
|
130
|
-
? '
|
|
131
|
-
:
|
|
125
|
+
const hasSeries = tracks.some((t) => t.seriesList.length > 0)
|
|
126
|
+
const status: WaveformTargetResult['status'] =
|
|
127
|
+
!hasSeries || (action === 'fit' && !nonempty)
|
|
128
|
+
? 'empty-data'
|
|
129
|
+
: c.props.presentationMode || !c.props.zoomable
|
|
130
|
+
? 'disabled'
|
|
131
|
+
: before && same(before.xDomain, xDomain) && !hasY && !boundaryChanged
|
|
132
|
+
? 'unchanged'
|
|
133
|
+
: 'applied'
|
|
132
134
|
return { id, tracks, before, bounds, xDomain, status, resetsY }
|
|
133
135
|
})
|
|
134
136
|
return { entries }
|
|
@@ -32,7 +32,6 @@ import { resolveCompactPaginationBand } from './pagination'
|
|
|
32
32
|
import type { WaveformHoverState } from './types'
|
|
33
33
|
import { useWaveformChartLifecycle } from './useWaveformChartLifecycle'
|
|
34
34
|
import { usePreparedWaveformSeries } from './useWaveformData'
|
|
35
|
-
import { remotePanBoundary } from '../interaction/remoteViewport'
|
|
36
35
|
import { useWaveformLayout } from './useWaveformLayout'
|
|
37
36
|
import { useWaveformPresentation } from './useWaveformPresentation'
|
|
38
37
|
import { usePlotLabelLayout } from './usePlotLabelLayout'
|
|
@@ -103,7 +102,7 @@ export function useWaveformChartController(
|
|
|
103
102
|
handleBeforeDataReferenceChange()
|
|
104
103
|
},
|
|
105
104
|
() => handleDataReferenceChange(),
|
|
106
|
-
() =>
|
|
105
|
+
() => true,
|
|
107
106
|
)
|
|
108
107
|
|
|
109
108
|
const presentation = useWaveformPresentation({
|
|
@@ -71,7 +71,19 @@ export function usePreparedWaveformSeries(
|
|
|
71
71
|
)
|
|
72
72
|
watch([data, retainEmpty], ([nextData, preserveEmpty]) => {
|
|
73
73
|
onBeforeDataChange()
|
|
74
|
-
preparedSeries.value
|
|
74
|
+
const previousById = new Map(preparedSeries.value.map((series) => [series.id, series]))
|
|
75
|
+
preparedSeries.value = prepareWaveformSeries(nextData, preserveEmpty).map((series) => {
|
|
76
|
+
const previous = previousById.get(series.id)
|
|
77
|
+
// Preserve axes, never geometry, across empty windows of the same channel/track.
|
|
78
|
+
if (series.source.length || !previous || series.trackId !== previous.trackId) return series
|
|
79
|
+
return {
|
|
80
|
+
...series,
|
|
81
|
+
xDomain: previous.xDomain,
|
|
82
|
+
yDomain: previous.yDomain,
|
|
83
|
+
rawYMaximum: previous.rawYMaximum,
|
|
84
|
+
rawYMinimum: previous.rawYMinimum,
|
|
85
|
+
}
|
|
86
|
+
})
|
|
75
87
|
onDataChange()
|
|
76
88
|
})
|
|
77
89
|
return preparedSeries
|
|
@@ -149,6 +149,9 @@ export function useWaveformLayout(context: LayoutContext) {
|
|
|
149
149
|
yAxisTickCount,
|
|
150
150
|
})
|
|
151
151
|
const hasWaveformData = computed(() => chartSeries.value.length > 0)
|
|
152
|
+
const hasWaveformSamples = computed(() =>
|
|
153
|
+
chartSeries.value.some((series) => (series.source?.length ?? series.points.length) > 0),
|
|
154
|
+
)
|
|
152
155
|
const hasChartArea = computed(() => innerWidth.value > 0 && innerHeight.value > 0)
|
|
153
156
|
const resolvedXLabel = computed(() => props.xLabel ?? `时间(${props.timeUnit})`)
|
|
154
157
|
const activeInteractionMode = computed(() => props.interactionMode)
|
|
@@ -349,6 +352,7 @@ export function useWaveformLayout(context: LayoutContext) {
|
|
|
349
352
|
innerWidth,
|
|
350
353
|
hasVisibleWaveformData,
|
|
351
354
|
hasWaveformData,
|
|
355
|
+
hasWaveformSamples,
|
|
352
356
|
hasChartArea,
|
|
353
357
|
resolvedXLabel,
|
|
354
358
|
activeInteractionMode,
|
|
@@ -56,6 +56,7 @@ function minimumPointSpan(
|
|
|
56
56
|
let minimumSpan = 0
|
|
57
57
|
for (const group of groups) {
|
|
58
58
|
const values = uniqueXValues(group, boundary)
|
|
59
|
+
if (!group.some((series) => (series.source?.length ?? series.points.length) > 0)) continue
|
|
59
60
|
if (values.length < required) return boundary[1] - boundary[0]
|
|
60
61
|
let groupSpan = Number.POSITIVE_INFINITY
|
|
61
62
|
for (let index = 0; index + required <= values.length; index += 1) {
|
|
@@ -104,6 +105,7 @@ function expandToMinimumPoints(
|
|
|
104
105
|
let expanded = domain
|
|
105
106
|
for (const group of groups) {
|
|
106
107
|
const values = uniqueXValues(group, boundary)
|
|
108
|
+
if (!group.some((series) => (series.source?.length ?? series.points.length) > 0)) continue
|
|
107
109
|
if (values.length < required) return [...boundary]
|
|
108
110
|
const visibleCount = values.filter(
|
|
109
111
|
(value) => value >= expanded[0] && value <= expanded[1],
|
|
@@ -52,14 +52,19 @@ export function mergeWaveformWindow(
|
|
|
52
52
|
response: WaveformData,
|
|
53
53
|
seriesIds?: string[],
|
|
54
54
|
): WaveformData {
|
|
55
|
-
if (
|
|
56
|
-
const selected = new Set(seriesIds)
|
|
55
|
+
if (current.kind !== 'series' || response.kind !== 'series') return response
|
|
56
|
+
const selected = seriesIds ? new Set(seriesIds) : undefined
|
|
57
57
|
const byId = new Map(response.series.map((series) => [series.id, series]))
|
|
58
|
+
const knownIds = new Set(current.series.map((series) => series.id))
|
|
58
59
|
return {
|
|
59
60
|
kind: 'series',
|
|
60
|
-
series:
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
series: [
|
|
62
|
+
...current.series.map((series) => {
|
|
63
|
+
if (selected && (!series.id || !selected.has(series.id))) return series
|
|
64
|
+
return byId.get(series.id) ?? { ...series, data: { kind: 'points' as const, points: [] } }
|
|
65
|
+
}),
|
|
66
|
+
...response.series.filter((series) => !knownIds.has(series.id)),
|
|
67
|
+
],
|
|
63
68
|
}
|
|
64
69
|
}
|
|
65
70
|
|