import { ComposedChart, AreaChart, Area, LineChart, Line, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer, ReferenceLine, } from 'recharts' const DARK_TICK = { fill: '#475569', fontSize: 11 } const GRID_PROPS = { stroke: 'rgba(255,255,255,0.05)', strokeDasharray: '3 3' } const CustomTooltip = ({ active, payload, label }) => { if (!active || !payload?.length) return null return (
Step {label}
{payload.map(p => (
{p.name}: {typeof p.value === 'number' ? p.value.toFixed(3) : p.value}
))}
) } /* ── 1. Battery SOC ─────────────────────────────────────── */ export function SOCChart({ data }) { return (
Battery State of Charge
`${(v*100).toFixed(0)}%`} /> } />
) } /* ── 2. Energy Arbitrage (LMP vs action) ────────────────── */ export function ArbitrageChart({ data }) { return (
Energy Arbitrage
} />
) } /* ── 3. Frequency Regulation ────────────────────────────── */ export function FreqRegChart({ data }) { return (
Frequency Regulation
} />
) } /* ── 4. Peak Shaving ─────────────────────────────────────── */ export function PeakShavingChart({ data }) { return (
Peak Shaving
} />
) } /* ── 5. Cumulative Reward ────────────────────────────────── */ export function RewardChart({ data }) { let cum = 0 const cumData = data.map(d => ({ ...d, cum_reward: (cum += d.reward) })) return (
Cumulative Reward
v >= 1000 ? `${(v/1000).toFixed(0)}k` : v} /> } />
) }