Files
CN_Tool_client/frontend/src/views/steady/steadyDataView/utils/selectionRules.ts

142 lines
4.4 KiB
TypeScript
Raw Normal View History

2026-05-15 16:36:50 +08:00
import type { SteadyDataView } from '@/api/steady/steadyDataView/interface'
export const MAX_TREND_SERIES_COUNT = 24
export const MAX_HARMONIC_ORDER_COUNT = 6
const isSelectableLineNode = (node: SteadyDataView.SteadyLedgerNode) => {
return node.level === 3 && node.selectable !== false
}
2026-05-15 16:36:50 +08:00
export const collectSelectedLineIds = (nodes: SteadyDataView.SteadyLedgerNode[]) => {
const lineIds = new Set<string>()
const collect = (node: SteadyDataView.SteadyLedgerNode) => {
if (isSelectableLineNode(node)) {
2026-05-15 16:36:50 +08:00
lineIds.add(node.id)
}
node.children?.forEach(collect)
}
nodes.forEach(collect)
return Array.from(lineIds)
}
export const collectLeafIndicators = (nodes: SteadyDataView.SteadyIndicatorNode[]) => {
const indicators: SteadyDataView.SteadyIndicatorNode[] = []
const collect = (node: SteadyDataView.SteadyIndicatorNode) => {
if (node.children?.length) {
node.children.forEach(collect)
return
}
if (node.indicatorCode) {
indicators.push(node)
}
}
nodes.forEach(collect)
return indicators
}
export const findFirstSelectableLedgerNode = (
nodes: SteadyDataView.SteadyLedgerNode[]
): SteadyDataView.SteadyLedgerNode | null => {
for (const node of nodes) {
if (isSelectableLineNode(node)) {
return node
}
const childNode = findFirstSelectableLedgerNode(node.children || [])
if (childNode) return childNode
}
return null
}
export const findFirstLeafIndicator = (
nodes: SteadyDataView.SteadyIndicatorNode[]
): SteadyDataView.SteadyIndicatorNode | null => {
for (const node of nodes) {
if (node.children?.length) {
const childNode = findFirstLeafIndicator(node.children)
if (childNode) return childNode
continue
}
if (node.indicatorCode) {
return node
}
}
return null
}
2026-05-15 16:36:50 +08:00
export const hasHarmonicIndicator = (indicators: SteadyDataView.SteadyIndicatorNode[]) => {
return indicators.some(item => item.harmonic || Boolean(item.harmonicOrderStart || item.harmonicOrderEnd))
}
export const resolveAvailableStats = (indicators: SteadyDataView.SteadyIndicatorNode[]) => {
const statSet = new Set<SteadyDataView.SteadyTrendStatType>()
indicators.forEach(indicator => {
indicator.supportStats?.forEach(stat => statSet.add(stat))
})
return Array.from(statSet)
}
export const estimateTrendSeriesCount = (
lineIds: string[],
indicators: SteadyDataView.SteadyIndicatorNode[],
statTypes: SteadyDataView.SteadyTrendStatType[],
harmonicOrders: number[]
) => {
const harmonicMultiplier = hasHarmonicIndicator(indicators) ? Math.max(harmonicOrders.length, 1) : 1
return indicators.reduce((count, indicator) => {
const phaseCount = indicator.phaseCodes?.length || 1
2026-05-15 16:36:50 +08:00
const fieldCount = Math.max(indicator.seriesFields?.length || indicator.baseFields?.length || 1, 1)
return count + lineIds.length * phaseCount * Math.max(statTypes.length, 1) * fieldCount * harmonicMultiplier
2026-05-15 16:36:50 +08:00
}, 0)
}
export const validateHarmonicOrders = (
indicators: SteadyDataView.SteadyIndicatorNode[],
harmonicOrders: number[]
) => {
if (!hasHarmonicIndicator(indicators)) return ''
if (!harmonicOrders.length) return '谐波指标必须选择谐波次数'
if (harmonicOrders.length > MAX_HARMONIC_ORDER_COUNT) return '谐波次数最多选择 6 个'
return ''
}
export const validateTrendSelection = (params: {
lineIds: string[]
indicators: SteadyDataView.SteadyIndicatorNode[]
statTypes: SteadyDataView.SteadyTrendStatType[]
harmonicOrders: number[]
}) => {
const { lineIds, indicators, statTypes, harmonicOrders } = params
2026-05-15 16:36:50 +08:00
if (!lineIds.length) return '请选择监测点'
if (!indicators.length) return '请选择趋势指标'
if (lineIds.length > 1 && indicators.length > 1) return '多监测点查询时只能选择 1 个指标'
if (!statTypes.length) return '请选择统计类型'
const harmonicError = validateHarmonicOrders(indicators, harmonicOrders)
if (harmonicError) return harmonicError
const seriesCount = estimateTrendSeriesCount(lineIds, indicators, statTypes, harmonicOrders)
2026-05-15 16:36:50 +08:00
if (seriesCount > MAX_TREND_SERIES_COUNT) {
return '趋势曲线数量不能超过 24 条,请缩小监测点、指标或统计类型范围'
2026-05-15 16:36:50 +08:00
}
return ''
}