From 9de6ac10c4c3a94ea76407749aac9b9cc643dfaf Mon Sep 17 00:00:00 2001 From: ISA Date: Wed, 2 Apr 2025 08:57:07 +0200 Subject: [PATCH] fix: window is not defined Fehler durch dynamischen Import von chartjs-plugin-zoom behoben --- .../kue705FO/Charts/ChartSwitcher.tsx | 6 +- .../LoopMeasurementChart.client.tsx | 163 ----------------- .../LoopMeasurementChart.tsx | 173 ++++++++++++++++++ config/webVersion.ts | 2 +- 4 files changed, 175 insertions(+), 169 deletions(-) delete mode 100644 components/main/kabelueberwachung/kue705FO/Charts/LoopMeasurementChart/LoopMeasurementChart.client.tsx create mode 100644 components/main/kabelueberwachung/kue705FO/Charts/LoopMeasurementChart/LoopMeasurementChart.tsx diff --git a/components/main/kabelueberwachung/kue705FO/Charts/ChartSwitcher.tsx b/components/main/kabelueberwachung/kue705FO/Charts/ChartSwitcher.tsx index 64b1ac6..1851352 100644 --- a/components/main/kabelueberwachung/kue705FO/Charts/ChartSwitcher.tsx +++ b/components/main/kabelueberwachung/kue705FO/Charts/ChartSwitcher.tsx @@ -1,10 +1,10 @@ "use client"; // /components/modules/kue705FO/charts/ChartSwitcher.tsx -import dynamic from "next/dynamic"; import React, { useState, useEffect } from "react"; import ReactModal from "react-modal"; import LoopChartActionBar from "./LoopMeasurementChart/LoopChartActionBar"; import TDRChartActionBar from "./TDRChart/TDRChartActionBar"; +import LoopMeasurementChart from "./LoopMeasurementChart/LoopMeasurementChart"; import TDRChart from "./TDRChart/TDRChart"; import { useSelector, useDispatch } from "react-redux"; import { AppDispatch } from "../../../../../redux/store"; @@ -31,10 +31,6 @@ const ChartSwitcher: React.FC = ({ onClose, slotIndex, }) => { - const LoopMeasurementChart = dynamic( - () => import("./LoopMeasurementChart/LoopMeasurementChart.client"), - { ssr: false } - ); const dispatch = useDispatch(); const chartTitle = useSelector( (state: RootState) => state.loopChartType.chartTitle diff --git a/components/main/kabelueberwachung/kue705FO/Charts/LoopMeasurementChart/LoopMeasurementChart.client.tsx b/components/main/kabelueberwachung/kue705FO/Charts/LoopMeasurementChart/LoopMeasurementChart.client.tsx deleted file mode 100644 index 498fbf6..0000000 --- a/components/main/kabelueberwachung/kue705FO/Charts/LoopMeasurementChart/LoopMeasurementChart.client.tsx +++ /dev/null @@ -1,163 +0,0 @@ -"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 zoomPlugin from "chartjs-plugin-zoom"; -import "chartjs-adapter-date-fns"; -import { de } from "date-fns/locale"; - -ChartJS.register( - LineElement, - PointElement, - LinearScale, - TimeScale, - Title, - Tooltip, - Legend, - Filler, - zoomPlugin -); - -const LoopMeasurementChart = () => { - const canvasRef = useRef(null); - const chartInstance = useRef(null); - - const { loopMeasurementCurveChartData, selectedMode, unit, isFullScreen } = - useSelector((state: RootState) => state.kabelueberwachungChartSlice); - - useEffect(() => { - if (!canvasRef.current) return; - const ctx = canvasRef.current.getContext("2d"); - if (!ctx) return; - - 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: 1, - fill: false, - pointRadius: 0, - }, - - selectedMode === "DIA0" - ? { - label: "Messwert", - data: loopMeasurementCurveChartData.map((e) => e.m).reverse(), - borderColor: "#00AEEF", - borderWidth: 2, - fill: false, - pointRadius: 2, - } - : { - label: "Messwert Durchschnitt", - data: loopMeasurementCurveChartData.map((e) => e.g).reverse(), - borderColor: "#00AEEF", - borderWidth: 2, - fill: false, - pointRadius: 2, - }, - { - label: "Messwert Maximum", - data: loopMeasurementCurveChartData.map((e) => e.a).reverse(), - borderColor: "lightgrey", - borderWidth: 1, - fill: false, - pointRadius: 0, - }, - ], - }; - - const options = { - responsive: true, - maintainAspectRatio: false, - plugins: { - legend: { - position: "top" as const, - }, - tooltip: { - 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", - }, - }, - title: { - display: true, - text: "Zeit", - }, - // Hier Deutsch setzen: - locale: de, - }, - y: { - title: { - display: true, - text: unit, - }, - ticks: { - precision: 0, - }, - }, - }, - }; - - if (chartInstance.current) { - chartInstance.current.destroy(); - } - - chartInstance.current = new ChartJS(ctx, { - type: "line", - data: chartData, - options, - }); - - // Kein Cleanup mit Destroy, damit Zoom erhalten bleibt - }, [loopMeasurementCurveChartData, selectedMode]); - - return ( -
- -
- ); -}; - -export default LoopMeasurementChart; diff --git a/components/main/kabelueberwachung/kue705FO/Charts/LoopMeasurementChart/LoopMeasurementChart.tsx b/components/main/kabelueberwachung/kue705FO/Charts/LoopMeasurementChart/LoopMeasurementChart.tsx new file mode 100644 index 0000000..8344192 --- /dev/null +++ b/components/main/kabelueberwachung/kue705FO/Charts/LoopMeasurementChart/LoopMeasurementChart.tsx @@ -0,0 +1,173 @@ +"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 +); + +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 } = + 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: 1, + fill: false, + pointRadius: 0, + }, + selectedMode === "DIA0" + ? { + label: "Messwert", + data: loopMeasurementCurveChartData.map((e) => e.m).reverse(), + borderColor: "#00AEEF", + borderWidth: 2, + fill: false, + pointRadius: 2, + } + : { + label: "Messwert Durchschnitt", + data: loopMeasurementCurveChartData.map((e) => e.g).reverse(), + borderColor: "#00AEEF", + borderWidth: 2, + fill: false, + pointRadius: 2, + }, + { + label: "Messwert Maximum", + data: loopMeasurementCurveChartData.map((e) => e.a).reverse(), + borderColor: "lightgrey", + borderWidth: 1, + fill: false, + pointRadius: 0, + }, + ], + }; + + const options = { + responsive: true, + maintainAspectRatio: false, + plugins: { + legend: { position: "top" as const }, + tooltip: { 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 ( +
+ +
+ ); +}; + +export default LoopMeasurementChart; diff --git a/config/webVersion.ts b/config/webVersion.ts index 5f382bb..11af2b0 100644 --- a/config/webVersion.ts +++ b/config/webVersion.ts @@ -6,5 +6,5 @@ 2: Patch oder Hotfix (Bugfixes oder kleine Änderungen). */ -const webVersion = "1.6.200"; +const webVersion = "1.6.201"; export default webVersion;