import { memo } from 'react'; import { Area, AreaChart, CartesianGrid, ResponsiveContainer, Tooltip, XAxis, YAxis, } from 'recharts'; import { chartSeriesDelta, chartSeriesPeak, type ChartDisplayMode, } from '../../help/chartSampleData'; import './HashrateChart.css'; export interface ChartPoint { time: string; value: number; label?: string; } interface HashrateChartProps { data: ChartPoint[]; title?: string; color?: string; unit?: string; height?: number; displayMode?: ChartDisplayMode; } const GRAD_IDS = ['cyan', 'magenta', 'amber', 'green', 'purple'] as const; function colorToId(color: string): string { if (color.includes('e8f5') || color.includes('f5ff') || color.includes('06b6d4') || color === '#00e8f5' || color === '#00f5ff' || color.includes('neon-cyan')) return 'cyan'; if (color.includes('2da6') || color.includes('8b5cf6')) return 'magenta'; if (color.includes('b020') || color.includes('eab308')) return 'amber'; if (color.includes('39ff') || color.includes('22c55e')) return 'green'; return 'purple'; } function HashrateChart({ data, title, color = 'var(--neon-cyan)', unit = 'H/s', height = 280, displayMode = 'live', }: HashrateChartProps) { const gradId = colorToId(color); const peak = chartSeriesPeak(data); const delta = chartSeriesDelta(data); const liveLabel = displayMode === 'live' ? '● LIVE' : '○ IDLE'; const liveClass = displayMode === 'live' ? 'pulse' : 'empty'; if (data.length === 0) { return (

{title || 'Telemetry'}

No live data yet — connect miners to populate this chart
); } return (
{title && (

{title}

PEAK {formatFull(peak, unit)} {delta != null && ( = 0 ? 'up' : 'down'}`}> {delta >= 0 ? '▲' : '▼'} {Math.abs(delta).toFixed(1)}% )} {liveLabel}
)} formatShort(v, unit)} /> ( )} />
); } function NeonTooltip({ active, payload, label, unit, title, color, }: { active?: boolean; payload?: { value: number }[]; label?: string; unit: string; title?: string; color: string; }) { if (!active || !payload?.length) return null; const v = payload[0].value; return (
{label}
{formatFull(v, unit)}
{title || 'Reading'}
); } function formatShort(v: number, unit: string): string { if (unit === 'H/s') { if (v >= 1_000_000) return `${(v / 1_000_000).toFixed(1)}M`; if (v >= 1_000) return `${(v / 1_000).toFixed(1)}K`; return `${v.toFixed(0)}`; } return `${v.toFixed(0)}${unit === '%' ? '%' : ''}`; } function formatFull(v: number, unit: string): string { if (unit === 'H/s') { if (v >= 1_000_000) return `${(v / 1_000_000).toFixed(3)} MH/s`; if (v >= 1_000) return `${(v / 1_000).toFixed(2)} KH/s`; return `${v.toFixed(0)} H/s`; } return `${v.toFixed(1)}${unit}`; } export default memo(HashrateChart);