"use client"; import React, { useEffect, useRef } from "react"; import { useSelector } from "react-redux"; import { RootState } from "../../../../../../redux/store"; import { Chart as ChartJS, LineElement, PointElement, LinearScale, TimeScale, Title, Tooltip, Legend, Filler, } from "chart.js"; import "chartjs-adapter-date-fns"; import { de } from "date-fns/locale"; ChartJS.register( LineElement, PointElement, LinearScale, TimeScale, Title, Tooltip, Legend, Filler ); import { getColor } from "../../../../../../utils/colors"; import { PulseLoader } from "react-spinners"; const usePreviousData = (data: any[]) => { const ref = useRef([]); useEffect(() => { ref.current = data; }, [data]); return ref.current; }; const LoopMeasurementChart = () => { const canvasRef = useRef(null); const chartInstance = useRef(null); const { loopMeasurementCurveChartData, selectedMode, unit, isFullScreen, isLoading, } = useSelector((state: RootState) => state.kabelueberwachungChartSlice); const previousData = usePreviousData(loopMeasurementCurveChartData); // Vergleichsfunktion const isEqual = (a: any[], b: any[]): boolean => { if (a.length !== b.length) return false; for (let i = 0; i < a.length; i++) { if ( a[i].t !== b[i].t || a[i].i !== b[i].i || a[i].m !== b[i].m || a[i].g !== b[i].g || a[i].a !== b[i].a ) { return false; } } return true; }; useEffect(() => { import("chartjs-plugin-zoom").then((zoomPlugin) => { if (!ChartJS.registry.plugins.get("zoom")) { ChartJS.register(zoomPlugin.default); } if (!canvasRef.current) return; const ctx = canvasRef.current.getContext("2d"); if (!ctx) return; if (isEqual(loopMeasurementCurveChartData, previousData)) { return; // keine echte Datenänderung → nicht neu zeichnen } if (chartInstance.current) { chartInstance.current.destroy(); } const chartData = { labels: loopMeasurementCurveChartData .map((entry) => new Date(entry.t)) .reverse(), datasets: [ { label: "Messwert Minimum", data: loopMeasurementCurveChartData.map((e) => e.i).reverse(), borderColor: "lightgrey", borderWidth: 2, // fill: false, pointRadius: 0, pointHoverRadius: 10, tension: 0.1, }, selectedMode === "DIA0" ? { label: "Messwert", data: loopMeasurementCurveChartData.map((e) => e.m).reverse(), borderColor: getColor("littwin-blue"), borderWidth: 2, // fill: false, pointRadius: 0, pointHoverRadius: 10, tension: 0.1, } : { label: "Messwert Durchschnitt", data: loopMeasurementCurveChartData.map((e) => e.g).reverse(), borderColor: getColor("littwin-blue"), borderWidth: 2, // fill: false, pointRadius: 0, pointHoverRadius: 10, tension: 0.1, }, { label: "Messwert Maximum", data: loopMeasurementCurveChartData.map((e) => e.a).reverse(), borderColor: "lightgrey", borderWidth: 2, // fill: false, pointRadius: 0, pointHoverRadius: 10, tension: 0.1, }, ], }; const options = { responsive: true, maintainAspectRatio: false, plugins: { legend: { position: "top" as const }, tooltip: { yAlign: "bottom" as const, // ← explizit casten mode: "index" as const, intersect: false, }, 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" }, locale: de, }, title: { display: true, text: "Zeit" }, }, y: { title: { display: true, text: unit }, ticks: { precision: 0 }, }, }, }; chartInstance.current = new ChartJS(ctx, { type: "line", data: chartData, options, }); }); }, [loopMeasurementCurveChartData, selectedMode]); return (
{isLoading && (
)}
); }; export default LoopMeasurementChart;