import React from 'react'; import { timeWeightedAverage } from './resultSync'; interface TimeSeriesChartProps { title: string; unit: string; values: number[]; timeSteps: number[]; // in seconds currentIndex: number; onSelectTimeIndex?: (index: number) => void; color?: string; } export const TimeSeriesChart: React.FC = ({ title, unit, values, timeSteps, currentIndex, onSelectTimeIndex, color = 'var(--accent)', }) => { if (!values || values.length === 0) return null; const min = Math.min(...values); const max = Math.max(...values); const range = max - min || 1; const avg = timeWeightedAverage(values, timeSteps); const width = 320; const height = 90; const padLeft = 32; const padRight = 12; const padTop = 10; const padBottom = 18; const plotWidth = width - padLeft - padRight; const plotHeight = height - padTop - padBottom; const points = values.map((v, i) => { const x = padLeft + (i / (values.length - 1 || 1)) * plotWidth; const y = padTop + plotHeight - ((v - min) / range) * plotHeight; return `${x.toFixed(1)},${y.toFixed(1)}`; }); const pathD = `M ${points.join(' L ')}`; // Current time marker X const currentX = padLeft + (currentIndex / (values.length - 1 || 1)) * plotWidth; const currentY = padTop + plotHeight - (((values[currentIndex] ?? min) - min) / range) * plotHeight; // Format time (seconds -> HH:00) const formatTime = (secs: number) => { const hours = Math.floor(secs / 3600); return `${String(hours).padStart(2, '0')}:00`; }; return (
24h 시계열: {title} 현재:{' '} {values[currentIndex]?.toFixed(2)} {unit}
{ if (!onSelectTimeIndex) return; const rect = e.currentTarget.getBoundingClientRect(); const clickRatio = (e.clientX - rect.left - (padLeft / width) * rect.width) / ((plotWidth / width) * rect.width); const clamped = Math.max(0, Math.min(1, clickRatio)); const targetIdx = Math.round(clamped * (values.length - 1)); onSelectTimeIndex(targetIdx); }} > {/* Background grid lines */} {/* Min / Max Labels */} {max.toFixed(1)} {min.toFixed(1)} {/* Trend line */} {/* Current time marker line */} {/* Current value circle */} {/* Time axis labels */} {formatTime(timeSteps[0] ?? 0)} {formatTime(timeSteps[Math.floor(timeSteps.length / 2)] ?? 43200)} {formatTime(timeSteps[timeSteps.length - 1] ?? 86400)}
최소: {min.toFixed(2)} 평균: {avg.toFixed(2)} 최대: {max.toFixed(2)}
); };