"use client"; // /components/main/system/DetailModal.tsx import React, { useEffect, useRef, useState } from "react"; import { Line } from "react-chartjs-2"; import { useSelector, useDispatch } from "react-redux"; import { RootState } from "@/redux/store"; import { Listbox } from "@headlessui/react"; import { setFullScreen } from "@/redux/slices/kabelueberwachungChartSlice"; import DateRangePicker from "@/components/common/DateRangePicker"; import { setVonDatum, setBisDatum, } from "@/redux/slices/kabelueberwachungChartSlice"; import { Chart as ChartJS, LineElement, PointElement, CategoryScale, LinearScale, Title, Tooltip, Legend, Filler, TimeScale, } from "chart.js"; import "chartjs-adapter-date-fns"; import { de } from "date-fns/locale"; ChartJS.register( LineElement, PointElement, CategoryScale, LinearScale, Title, Tooltip, Legend, Filler, TimeScale ); type ReduxDataEntry = { //Alle DIA0 t,m,i,a , DIA1 und DIA2 t,i,a,g t: string; // Zeitstempel i: number; // Minimum a: number; // Maximum g?: number; // Durchschnitt (optional, falls vorhanden) m?: number; // aktueller Messwert (optional, falls vorhanden) }; const chartOptions = { responsive: true, maintainAspectRatio: false, plugins: { legend: { position: "top" as const }, title: { display: true, text: "Verlauf", }, tooltip: { mode: "index" as const, intersect: false, callbacks: { label: function (ctx: any) { return `Messwert: ${ctx.parsed.y}`; }, title: function (items: any[]) { const date = items[0].parsed.x; return `Zeitpunkt: ${new Date(date).toLocaleString("de-DE")}`; }, }, }, zoom: { pan: { enabled: true, mode: "x" as const }, zoom: { wheel: { enabled: true }, pinch: { enabled: true }, mode: "x" as const, }, }, }, scales: { x: { type: "time" as const, time: { unit: "day" as const, tooltipFormat: "dd.MM.yyyy HH:mm", displayFormats: { day: "dd.MM.yyyy", }, }, adapters: { date: { locale: de }, }, title: { display: true, text: "Zeit", }, }, y: { title: { display: true, text: "Messwert", }, }, }, }; type Props = { isOpen: boolean; selectedKey: string | null; onClose: () => void; zeitraum: "DIA0" | "DIA1" | "DIA2"; setZeitraum: (typ: "DIA0" | "DIA1" | "DIA2") => void; }; export const DetailModal = ({ isOpen, selectedKey, onClose, zeitraum, setZeitraum, }: Props) => { const chartRef = useRef(null); const [chartData, setChartData] = useState({ datasets: [], }); const vonDatum = useSelector( (state: RootState) => state.kabelueberwachungChartSlice.vonDatum ); const bisDatum = useSelector( (state: RootState) => state.kabelueberwachungChartSlice.bisDatum ); const [filteredData, setFilteredData] = useState([]); const reduxData = useSelector((state: RootState) => { switch (selectedKey) { case "+5V": return state.systemspannung5Vplus[zeitraum]; case "+15V": return state.systemspannung15Vplus[zeitraum]; case "-15V": return state.systemspannung15Vminus[zeitraum]; case "-98V": return state.systemspannung98Vminus[zeitraum]; case "ADC Temp": return state.temperaturAdWandler[zeitraum]; case "CPU Temp": return state.temperaturProzessor[zeitraum]; default: return []; } }) as ReduxDataEntry[]; const isFullScreen = useSelector( (state: RootState) => state.kabelueberwachungChartSlice.isFullScreen ); const dispatch = useDispatch(); const toggleFullScreen = () => { dispatch(setFullScreen(!isFullScreen)); setTimeout(() => { chartRef.current?.resize(); }, 50); }; const handleClose = () => { dispatch(setFullScreen(false)); dispatch(setVonDatum("")); dispatch(setBisDatum("")); onClose(); }; useEffect(() => { const loadZoomPlugin = async () => { if (typeof window !== "undefined") { const zoomPlugin = (await import("chartjs-plugin-zoom")).default; if (!ChartJS.registry.plugins.get("zoom")) { ChartJS.register(zoomPlugin); } } }; loadZoomPlugin(); }, []); const handleFetchData = () => { let sortedData = [...reduxData].reverse(); if (vonDatum && bisDatum) { const vonDate = new Date(vonDatum); const bisDate = new Date(bisDatum); sortedData = sortedData.filter((entry) => { const entryDate = new Date(entry.t); return entryDate >= vonDate && entryDate <= bisDate; }); } setFilteredData(sortedData); setChartData({ datasets: [ { label: "Minimum", data: sortedData.map((p) => ({ x: new Date(p.t), y: p.i })), borderColor: "lightgrey", backgroundColor: "rgba(211,211,211,0.3)", borderWidth: 2, pointRadius: 0, tension: 0.1, }, { label: "Maximum", data: sortedData.map((p) => ({ x: new Date(p.t), y: p.a })), borderColor: "lightgrey", backgroundColor: "rgba(211,211,211,0.3)", borderWidth: 2, pointRadius: 0, tension: 0.1, }, { label: zeitraum === "DIA0" ? "Messwert" : "Durchschnitt", data: sortedData.map((p) => ({ x: new Date(p.t), y: zeitraum === "DIA0" ? p.m : p.g, })), borderColor: "rgba(59,130,246,1)", backgroundColor: "rgba(59,130,246,0.3)", borderWidth: 2, pointRadius: 0, tension: 0.1, }, ], }); }; useEffect(() => { if (chartRef.current && selectedKey) { chartRef.current.options.plugins.title.text = `Verlauf ${selectedKey}`; chartRef.current.update("none"); } }, [selectedKey]); useEffect(() => { if (chartRef.current) { chartRef.current.resetZoom(); } }, [zeitraum]); // beim start soll der Chart einmal aufgerufen wird, also einmal der Button "Daten laden" geklickt werden useEffect(() => { if (isOpen && selectedKey) { handleFetchData(); } }, [isOpen, selectedKey]); if (!isOpen || !selectedKey) return null; return (

Detailansicht: {selectedKey}

{ { DIA0: "Alle Messwerte", DIA1: "Stündlich", DIA2: "Täglich", }[zeitraum] } {["DIA0", "DIA1", "DIA2"].map((option) => ( `px-4 py-1 cursor-pointer ${ selected ? "bg-littwin-blue text-white" : active ? "bg-gray-200" : "" }` } > { { DIA0: "Alle Messwerte", DIA1: "Stündlich", DIA2: "Täglich", }[option] } ))}
); };