yeg
2026-09-09 528d52f2c7c6f911c54cae6e3f25500eab4384fe
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import { toTestDisplayValue } from './testDataUnits'
 
export interface StepCurveSeries { name: string; points: Array<[number, number | null]>; hidden?: boolean }
/** 工步图表及对比报表共享显示设置;每根曲线独立相对零点,绝不累加前一根的横轴长度。 */
export function stepCurveChartOption(metric: { key: string; unit: string }, series: StepCurveSeries[], colors: string[]) {
  const values = series.flatMap(item => item.points.map(point => point[1])).filter((value): value is number => value !== null && Number.isFinite(value))
  const low = values.length ? Math.min(...values) : 0
  const high = values.length ? Math.max(...values) : 1
  const margin = Math.max((high - low) * 0.16, metric.key === 'temperature' ? 1 : toTestDisplayValue(metric.key, 0.08))
  const maxTime = series.reduce((max, item) => item.points.reduce((value, point) => Math.max(value, point[0]), max), 0)
  const unit = maxTime >= 3600 ? 3600 : maxTime >= 180 ? 60 : 1
  const axis = (position: 'left' | 'right') => ({ type: 'value', name: metric.unit, position, nameLocation: 'middle', nameGap: 42, nameRotate: position === 'left' ? 90 : -90, min: low - margin, max: high + margin, nameTextStyle: { color: '#8795a3', fontSize: 10 }, axisLine: { show: true, lineStyle: { color: '#cbd8e4' } }, axisTick: { show: true, lineStyle: { color: '#cbd8e4' } }, splitLine: { show: position === 'left', lineStyle: { color: '#e8eef4' } }, axisLabel: { color: '#8795a3', fontSize: 10, margin: 8, formatter: (value: number) => String(Number(value.toPrecision(6))) } })
  return { animation: false, color: colors, grid: { top: 62, right: 62, bottom: 46, left: 62 }, tooltip: { trigger: 'axis' },
    legend: { top: 4, right: 6, left: 6, type: 'scroll', icon: 'roundRect', itemWidth: 14, itemHeight: 8, itemGap: 12, textStyle: { fontSize: 10, color: '#52606d' }, selected: Object.fromEntries(series.map(item => [item.name, !item.hidden])) },
    xAxis: { type: 'value', min: 0, max: maxTime || undefined, name: `相对时间 / ${unit === 3600 ? 'h' : unit === 60 ? 'min' : 's'}`, nameLocation: 'middle', nameGap: 29, axisLine: { lineStyle: { color: '#cbd8e4' } }, axisLabel: { color: '#8795a3', fontSize: 10, hideOverlap: true, formatter: (value: number) => String(Number((value / unit).toFixed(3))) }, nameTextStyle: { color: '#52606d', fontSize: 10 } },
    yAxis: [axis('left'), axis('right')],
    series: series.map((item, index) => ({ name: item.name, type: 'line', smooth: false, connectNulls: false, showSymbol: item.points.length === 1, lineStyle: { width: 2 }, itemStyle: { color: colors[index % colors.length] }, data: item.points })),
  }
}