Files
waveform-analysis/src/components/core/useWaveformData.ts

78 lines
2.4 KiB
TypeScript
Raw Normal View History

2026-07-20 10:21:30 +08:00
import { shallowRef, watch } from 'vue'
import { normalizeWaveformSeries, resolveWaveformPointErrors } from '../../core'
import type {
ResolvedWaveformErrorBarOptions,
WaveformData,
WaveformLineType,
WaveformLineStyle,
WaveformPoint,
WaveformPointType,
} from '../../types'
2026-07-20 10:21:30 +08:00
import { paddedDomain } from '../../utils'
export interface PreparedWaveformSeries {
id: string
trackId?: string
2026-07-20 10:21:30 +08:00
name: string
unit?: string
color?: string
lineType: WaveformLineType
lineStyle: WaveformLineStyle
pointType: WaveformPointType
errorBar: ResolvedWaveformErrorBarOptions
2026-07-20 10:21:30 +08:00
points: WaveformPoint[]
xDomain: [number, number]
yDomain: [number, number]
hasErrorPoints: boolean
2026-07-20 10:21:30 +08:00
}
function pointMetrics(
points: WaveformPoint[],
includeErrors = false,
): { xDomain: [number, number]; yDomain: [number, number]; hasErrorPoints: boolean } {
let xMinimum = Number.POSITIVE_INFINITY
let xMaximum = Number.NEGATIVE_INFINITY
let yMinimum = Number.POSITIVE_INFINITY
let yMaximum = Number.NEGATIVE_INFINITY
let hasErrorPoints = false
for (const point of points) {
if (point.x < xMinimum) xMinimum = point.x
if (point.x > xMaximum) xMaximum = point.x
if (point.y < yMinimum) yMinimum = point.y
if (point.y > yMaximum) yMaximum = point.y
if (includeErrors) {
const errors = resolveWaveformPointErrors(point)
if (errors.lower !== 0 || errors.upper !== 0) hasErrorPoints = true
yMinimum = Math.min(yMinimum, point.y - errors.lower)
yMaximum = Math.max(yMaximum, point.y + errors.upper)
}
}
return {
xDomain: paddedDomain(Number.isFinite(xMinimum) ? [xMinimum, xMaximum] : []),
yDomain: paddedDomain(Number.isFinite(yMinimum) ? [yMinimum, yMaximum] : []),
hasErrorPoints,
}
2026-07-20 10:21:30 +08:00
}
export function prepareWaveformSeries(data: WaveformData): PreparedWaveformSeries[] {
return normalizeWaveformSeries(data).map((series) => {
const metrics = pointMetrics(series.points, series.errorBar.visible)
return { ...series, ...metrics }
})
2026-07-20 10:21:30 +08:00
}
export function usePreparedWaveformSeries(
data: () => WaveformData,
onBeforeDataChange: () => void,
onDataChange: () => void,
) {
2026-07-20 10:21:30 +08:00
const preparedSeries = shallowRef<PreparedWaveformSeries[]>(prepareWaveformSeries(data()))
watch(data, (nextData) => {
onBeforeDataChange()
2026-07-20 10:21:30 +08:00
preparedSeries.value = prepareWaveformSeries(nextData)
onDataChange()
})
return preparedSeries
}