'use client'; import Highcharts from 'highcharts'; import HighchartsReact from 'highcharts-react-official'; import type { Options } from 'highcharts'; import { VerbrauchPoint, Every } from '@/types/strom'; interface BarChartProps { title: string; data: VerbrauchPoint[]; every: Every; color: string; // Optionale feste Achsengrenzen (z.B. komplettes Jahr -> immer 12 Monate sichtbar) xMin?: number; xMax?: number; // Hervorzuhebende Balken (Zeitstempel-Set, z.B. E-Auto-Ladetage) + Farbe highlight?: Set; highlightColor?: string; } const HOUR_MS = 60 * 60 * 1000; const DAY_MS = 24 * HOUR_MS; export default function BarChart({ title, data, every, color, xMin, xMax, highlight, highlightColor = '#c0392b', }: BarChartProps) { const isHourly = every === '1h'; const isMonthly = every === '1mo'; const tooltipDateFormat = isHourly ? '%d.%m.%Y %H:%M' : isMonthly ? '%B %Y' : '%d.%m.%Y'; // Spaltenbreite: Stunde/Tag fix; Monat ~30 Tage breit const pointRange = isHourly ? HOUR_MS : isMonthly ? 30 * DAY_MS : DAY_MS; const options: Options = { // Achse in lokaler Zeit rendern, damit Berliner Tages-/Monatsgrenzen // (z.B. 01.01. 00:00 = 31.12. 23:00 UTC) korrekt beschriftet werden. time: { timezone: 'Europe/Berlin' }, chart: { type: 'column', backgroundColor: '#F4F4F5', style: { fontFamily: 'Arial, Helvetica, sans-serif' }, height: 300, width: null, zooming: { type: 'x' }, }, title: { text: title, style: { fontWeight: 'bold', fontSize: '15px' } }, xAxis: { type: 'datetime', min: xMin, max: xMax, dateTimeLabelFormats: { hour: '%H:%M', day: '%d.%m.', week: '%d.%m.', month: '%m.%Y', }, title: { text: null }, labels: { style: { fontSize: '11px' } }, }, yAxis: { title: { text: 'kWh' }, min: 0, gridLineColor: '#ddd', }, tooltip: { xDateFormat: tooltipDateFormat, pointFormat: '{point.y:.3f} kWh', valueDecimals: 3, }, credits: { enabled: false }, legend: { enabled: false }, plotOptions: { column: { borderRadius: 0, groupPadding: 0.12, pointPadding: 0.05, maxPointWidth: 26, pointRange, }, }, series: [ { type: 'column', name: 'Verbrauch', // markierte Balken (z.B. Ladetage) bekommen eine eigene Farbe data: highlight && highlight.size ? data.map(([x, y]) => highlight.has(x) ? { x, y, color: highlightColor } : { x, y } ) : data, color, }, ], }; return ( ); }