Files
SE-LTD/web/src/components/TrendChart.jsx
T
2026-06-22 13:29:30 +02:00

95 lines
2.7 KiB
React

import { useEffect, useRef, useState } from "react";
import {
CartesianGrid,
Legend,
Line,
LineChart,
ResponsiveContainer,
Tooltip,
XAxis,
YAxis,
} from "recharts";
const COLORS = ["#2563eb", "#dc2626", "#1d4ed8", "#b91c1c", "#3b82f6", "#ef4444"];
export default function TrendChart({ result, title = "Trendansicht" }) {
const hostRef = useRef(null);
const [isFullscreen, setIsFullscreen] = useState(false);
useEffect(() => {
const onChange = () => {
setIsFullscreen(document.fullscreenElement === hostRef.current);
};
document.addEventListener("fullscreenchange", onChange);
return () => document.removeEventListener("fullscreenchange", onChange);
}, []);
if (!result?.rows?.length) {
return (
<div className="panel chart-panel empty-state">
<h3>{title}</h3>
<p>Keine Daten im gewaehlten Zeitraum.</p>
</div>
);
}
const rows = result.rows.map((row) => ({
...row,
timestampLabel: new Date(row.timestamp).toLocaleString("de-DE"),
}));
const toggleFullscreen = async () => {
if (!hostRef.current) {
return;
}
if (document.fullscreenElement === hostRef.current) {
await document.exitFullscreen();
return;
}
await hostRef.current.requestFullscreen();
};
return (
<div ref={hostRef} className="panel chart-panel">
<div className="panel-header">
<h3>{title}</h3>
<button className="ghost-button" type="button" onClick={toggleFullscreen}>
{isFullscreen ? "Zurueck" : "Vollbild"}
</button>
</div>
<div className="chart-wrapper">
<ResponsiveContainer width="100%" height={isFullscreen ? 520 : 320}>
<LineChart data={rows}>
<CartesianGrid strokeDasharray="3 3" stroke="var(--grid)" />
<XAxis dataKey="timestampLabel" minTickGap={30} stroke="var(--muted)" />
<YAxis stroke="var(--muted)" />
<Tooltip
contentStyle={{
background: "var(--surface-strong)",
border: "1px solid var(--border-strong)",
borderRadius: 10,
fontSize: 12,
}}
/>
<Legend />
{result.series.map((series, index) => (
<Line
key={series.key}
type="monotone"
dataKey={series.key}
dot={false}
strokeWidth={1.75}
stroke={COLORS[index % COLORS.length]}
name={series.displayName + " / " + series.alias + (series.unit ? " (" + series.unit + ")" : "")}
/>
))}
</LineChart>
</ResponsiveContainer>
</div>
</div>
);
}