2026-07-20 10:21:30 +08:00
|
|
|
import { shallowRef, watch } from 'vue'
|
|
|
|
|
|
2026-07-20 17:57:52 +08:00
|
|
|
import { normalizeWaveformSeries, resolveWaveformPointErrors } from '../../core'
|
|
|
|
|
import type {
|
|
|
|
|
ResolvedWaveformErrorBarOptions,
|
|
|
|
|
WaveformData,
|
|
|
|
|
WaveformLineType,
|
2026-07-22 16:36:48 +08:00
|
|
|
WaveformLineStyle,
|
2026-07-20 17:57:52 +08:00
|
|
|
WaveformPoint,
|
|
|
|
|
WaveformPointType,
|
|
|
|
|
} from '../../types'
|
2026-07-20 10:21:30 +08:00
|
|
|
import { paddedDomain } from '../../utils'
|
|
|
|
|
|
|
|
|
|
export interface PreparedWaveformSeries {
|
|
|
|
|
id: string
|
2026-07-20 14:07:43 +08:00
|
|
|
trackId?: string
|
2026-07-20 10:21:30 +08:00
|
|
|
name: string
|
|
|
|
|
unit?: string
|
|
|
|
|
color?: string
|
2026-07-20 17:57:52 +08:00
|
|
|
lineType: WaveformLineType
|
2026-07-22 16:36:48 +08:00
|
|
|
lineStyle: WaveformLineStyle
|
2026-07-20 17:57:52 +08:00
|
|
|
pointType: WaveformPointType
|
|
|
|
|
errorBar: ResolvedWaveformErrorBarOptions
|
2026-07-20 10:21:30 +08:00
|
|
|
points: WaveformPoint[]
|
|
|
|
|
xDomain: [number, number]
|
|
|
|
|
yDomain: [number, number]
|
2026-07-22 10:56:25 +08:00
|
|
|
hasErrorPoints: boolean
|
2026-07-20 10:21:30 +08:00
|
|
|
}
|
|
|
|
|
|
2026-07-22 10:56:25 +08:00
|
|
|
function pointMetrics(
|
2026-07-20 17:57:52 +08:00
|
|
|
points: WaveformPoint[],
|
|
|
|
|
includeErrors = false,
|
2026-07-22 10:56:25 +08:00
|
|
|
): { 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) {
|
2026-07-20 17:57:52 +08:00
|
|
|
const errors = resolveWaveformPointErrors(point)
|
2026-07-22 10:56:25 +08:00
|
|
|
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)
|
2026-07-20 17:57:52 +08:00
|
|
|
}
|
2026-07-22 10:56:25 +08:00
|
|
|
}
|
|
|
|
|
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[] {
|
2026-07-22 10:56:25 +08:00
|
|
|
return normalizeWaveformSeries(data).map((series) => {
|
|
|
|
|
const metrics = pointMetrics(series.points, series.errorBar.visible)
|
|
|
|
|
return { ...series, ...metrics }
|
|
|
|
|
})
|
2026-07-20 10:21:30 +08:00
|
|
|
}
|
|
|
|
|
|
2026-07-20 15:35:19 +08:00
|
|
|
export function usePreparedWaveformSeries(data: () => WaveformData, onDataChange: () => void) {
|
2026-07-20 10:21:30 +08:00
|
|
|
const preparedSeries = shallowRef<PreparedWaveformSeries[]>(prepareWaveformSeries(data()))
|
|
|
|
|
watch(data, (nextData) => {
|
|
|
|
|
preparedSeries.value = prepareWaveformSeries(nextData)
|
|
|
|
|
onDataChange()
|
|
|
|
|
})
|
|
|
|
|
return preparedSeries
|
|
|
|
|
}
|