feat(steady): 完善稳态数据视图功能

- 更新纵坐标刻度算法,优化小数趋势图范围显示
- 添加稳态趋势图全屏模式和共享工具组件
- 实现多图联动的鼠标悬停竖线同步功能
- 调整主线线宽分档策略,降低最大线宽限制
- 重构稳态趋势工具栏,优化谐波次数选择逻辑
- 添加周时间周期搜索支持和自定义时间范围选择
- 完善稳态数据表格和指示器浮动面板功能
- 优化稳态趋势图性能,添加LTB采样和动画控制
- 修复数据表格打开前的趋势数据验证问题
- 统一时间轴标签格式化和网格对齐处理
This commit is contained in:
2026-05-27 08:06:12 +08:00
parent b9ddfb5275
commit 055e69fff7
83 changed files with 9616 additions and 226 deletions

View File

@@ -117,6 +117,57 @@ const resolveZoomRangeFromAxisValues = (startValue: unknown, endValue: unknown)
)
}
const resolveTimeValue = (value: unknown): number | undefined => {
if (Array.isArray(value)) return resolveTimeValue(value[0])
const numberValue = getFiniteNumber(value)
if (numberValue !== undefined) return numberValue
if (typeof value === 'string') {
const timestamp = Date.parse(value.replace(' ', 'T'))
return Number.isFinite(timestamp) ? timestamp : undefined
}
return undefined
}
const getSeriesTimeRange = () => {
const seriesList = Array.isArray(props.options?.series) ? props.options.series : []
let minTime = Number.POSITIVE_INFINITY
let maxTime = Number.NEGATIVE_INFINITY
seriesList.forEach((series: { data?: unknown[] }) => {
;(series.data || []).forEach(point => {
const timestamp = resolveTimeValue(point)
if (timestamp === undefined) return
minTime = Math.min(minTime, timestamp)
maxTime = Math.max(maxTime, timestamp)
})
})
return Number.isFinite(minTime) && Number.isFinite(maxTime) && maxTime > minTime
? { minTime, maxTime }
: null
}
const resolveZoomRangeFromTimeAxisValues = (startValue: unknown, endValue: unknown) => {
const startTime = resolveTimeValue(startValue)
const endTime = resolveTimeValue(endValue)
const timeRange = getSeriesTimeRange()
if (startTime === undefined || endTime === undefined || !timeRange) return null
const rangeSize = timeRange.maxTime - timeRange.minTime
return normalizeZoomPercentRange(
((Math.min(startTime, endTime) - timeRange.minTime) / rangeSize) * 100,
((Math.max(startTime, endTime) - timeRange.minTime) / rangeSize) * 100
)
}
const resolveCurrentDataZoomRange = (zoomPayload: ChartDataZoomPayload) => {
const dataZoomOptions = chart?.getOption?.()?.dataZoom
const dataZoomList = Array.isArray(dataZoomOptions) ? dataZoomOptions : dataZoomOptions ? [dataZoomOptions] : []
@@ -140,6 +191,9 @@ const resolveChartDataZoomRange = (zoomPayload: ChartDataZoomPayload) => {
const valueRange = resolveZoomRangeFromAxisValues(zoomPayload?.startValue, zoomPayload?.endValue)
if (valueRange) return valueRange
const timeValueRange = resolveZoomRangeFromTimeAxisValues(zoomPayload?.startValue, zoomPayload?.endValue)
if (timeValueRange) return timeValueRange
return resolveCurrentDataZoomRange(zoomPayload)
}
@@ -199,9 +253,18 @@ const resetChartCursor = () => {
isPanPointerDown = false
}
const isSliderDataZoomResizeHandle = (target: any) => {
return target?.type === 'path' && target?.draggable === true && target?.parent?.parent?.type === 'group'
}
const updatePanCursor = (event: { offsetX: number; offsetY: number }) => {
const viewportRoot = getChartViewportRoot()
if (viewportRoot && isSliderDataZoomResizeHandle((event as any)?.target)) {
viewportRoot.style.cursor = 'pointer'
return
}
if (!viewportRoot || (props.options?.activeTool !== 'pan' && props.options?.activeTool !== 'mark')) {
resetChartCursor()
return