From 9424a6cc4316b161f13e6297b079dae45fb89890 Mon Sep 17 00:00:00 2001 From: ISA Date: Tue, 25 Feb 2025 11:55:37 +0100 Subject: [PATCH] =?UTF-8?q?feat:=20Redux-Integration=20f=C3=BCr=20Datumsau?= =?UTF-8?q?swahl=20und=20Chart-Zoom=20verbessert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `DateRangePicker.tsx` angepasst, um `vonDatum` und `bisDatum` direkt in Redux zu aktualisieren - `LoopMeasurementChart.tsx` verbessert, sodass `vonDatum` und `bisDatum` beim Zoomen mit Mausrad automatisch in Redux gespeichert werden - Chart.js `onZoom` korrekt implementiert, um Änderungen in der X-Achse sofort zu übernehmen - Redux-Updates optimiert, um unnötige `dispatch`-Aufrufe zu vermeiden --- .../kue705FO/Charts/DateRangePicker.tsx | 50 +++++------- .../LoopChartActionBar.tsx | 16 ++-- .../LoopMeasurementChart.tsx | 79 +++++++++---------- redux/slices/kabelueberwachungChartSlice.ts | 4 +- 4 files changed, 67 insertions(+), 82 deletions(-) diff --git a/components/main/kabelueberwachung/kue705FO/Charts/DateRangePicker.tsx b/components/main/kabelueberwachung/kue705FO/Charts/DateRangePicker.tsx index 6a6a703..6e2626a 100644 --- a/components/main/kabelueberwachung/kue705FO/Charts/DateRangePicker.tsx +++ b/components/main/kabelueberwachung/kue705FO/Charts/DateRangePicker.tsx @@ -1,19 +1,17 @@ // /components/modules/kue705FO/charts/DateRangePicker.tsx -import React, { useState } from "react"; +import React from "react"; import DatePicker from "react-datepicker"; -import { useSelector } from "react-redux"; +import { useSelector, useDispatch } from "react-redux"; import { RootState } from "../../../../../redux/store"; -import "react-datepicker/dist/react-datepicker.css"; - -interface DateRangePickerProps { - setVonDatum: (date: Date) => void; - setBisDatum: (date: Date) => void; -} - -const DateRangePicker: React.FC = ({ +import { setVonDatum, setBisDatum, -}) => { +} from "../../../../../redux/slices/kabelueberwachungChartSlice"; +import "react-datepicker/dist/react-datepicker.css"; + +const DateRangePicker: React.FC = () => { + const dispatch = useDispatch(); + // Redux-Werte abrufen const reduxVonDatum = useSelector( (state: RootState) => state.kabelueberwachungChart.vonDatum @@ -22,29 +20,21 @@ const DateRangePicker: React.FC = ({ (state: RootState) => state.kabelueberwachungChart.bisDatum ); - // Direkt mit Redux-Werten initialisieren, falls vorhanden - const [startDate, setStartDate] = useState( - reduxVonDatum ? new Date(reduxVonDatum) : new Date() - ); - const [endDate, setEndDate] = useState( - reduxBisDatum ? new Date(reduxBisDatum) : new Date() - ); - return (
{ if (date) { - setStartDate(date); - setVonDatum(date); + const isoDate = date.toISOString().split("T")[0]; + dispatch(setVonDatum(isoDate)); } }} selectsStart - startDate={startDate} - endDate={endDate} + startDate={reduxVonDatum ? new Date(reduxVonDatum) : new Date()} + endDate={reduxBisDatum ? new Date(reduxBisDatum) : new Date()} dateFormat="dd.MM.yyyy" className="border px-2 py-1 rounded" /> @@ -53,17 +43,17 @@ const DateRangePicker: React.FC = ({
{ if (date) { - setEndDate(date); - setBisDatum(date); + const isoDate = date.toISOString().split("T")[0]; + dispatch(setBisDatum(isoDate)); } }} selectsEnd - startDate={startDate} - endDate={endDate} - minDate={startDate} + startDate={reduxVonDatum ? new Date(reduxVonDatum) : new Date()} + endDate={reduxBisDatum ? new Date(reduxBisDatum) : new Date()} + minDate={reduxVonDatum ? new Date(reduxVonDatum) : new Date()} dateFormat="dd.MM.yyyy" className="border px-2 py-1 rounded" /> diff --git a/components/main/kabelueberwachung/kue705FO/Charts/LoopMeasurementChart/LoopChartActionBar.tsx b/components/main/kabelueberwachung/kue705FO/Charts/LoopMeasurementChart/LoopChartActionBar.tsx index 52ae8a9..654b79f 100644 --- a/components/main/kabelueberwachung/kue705FO/Charts/LoopMeasurementChart/LoopChartActionBar.tsx +++ b/components/main/kabelueberwachung/kue705FO/Charts/LoopMeasurementChart/LoopChartActionBar.tsx @@ -74,7 +74,7 @@ const LoopChartActionBar: React.FC = () => { console.log("✅ Daten erfolgreich geladen:", jsonData); if (Array.isArray(jsonData)) { - dispatch(setLoopMeasurementCurveChartData(jsonData)); + dispatch(setLoopMeasurementCurveChartData([...jsonData])); // Erzwingt eine neue Referenz // Falls das Chart zum ersten Mal geöffnet wird, setze vonDatum & bisDatum if (!isChartOpen && jsonData.length > 0) { @@ -101,12 +101,14 @@ const LoopChartActionBar: React.FC = () => {
{/* Datumsauswahl */} - dispatch(setVonDatum(date.toISOString().split("T")[0])) - } - setBisDatum={(date) => - dispatch(setBisDatum(date.toISOString().split("T")[0])) - } + setVonDatum={(date) => { + const isoDate = date.toISOString().split("T")[0]; + if (isoDate !== vonDatum) dispatch(setVonDatum(isoDate)); + }} + setBisDatum={(date) => { + const isoDate = date.toISOString().split("T")[0]; + if (isoDate !== bisDatum) dispatch(setBisDatum(isoDate)); + }} /> {/* Dropdown für DIA-Modus */} diff --git a/components/main/kabelueberwachung/kue705FO/Charts/LoopMeasurementChart/LoopMeasurementChart.tsx b/components/main/kabelueberwachung/kue705FO/Charts/LoopMeasurementChart/LoopMeasurementChart.tsx index b3b06e5..e9898ae 100644 --- a/components/main/kabelueberwachung/kue705FO/Charts/LoopMeasurementChart/LoopMeasurementChart.tsx +++ b/components/main/kabelueberwachung/kue705FO/Charts/LoopMeasurementChart/LoopMeasurementChart.tsx @@ -1,19 +1,25 @@ "use client"; // components/main/kabelueberwachung/kue705FO/Charts/LoopMeasurementChart/LoopMeasurementChart.tsx - import React, { useEffect, useRef, useState } from "react"; -import { useSelector } from "react-redux"; +import { useSelector, useDispatch } from "react-redux"; import { RootState } from "../../../../../../redux/store"; import Chart from "chart.js/auto"; import "chartjs-adapter-moment"; -// 🟢 **Prop-Typ für isFullScreen hinzufügen** -interface LoopMeasurementChartProps { - isFullScreen: boolean; -} +import { + setVonDatum, + setBisDatum, +} from "../../../../../../redux/slices/kabelueberwachungChartSlice"; const LoopMeasurementChart = () => { + const dispatch = useDispatch(); const isFullScreen = useSelector( (state: RootState) => state.kabelueberwachungChart.isFullScreen ); + const { loopMeasurementCurveChartData, vonDatum, bisDatum } = useSelector( + (state: RootState) => state.kabelueberwachungChart + ); + const selectedMode = useSelector( + (state: RootState) => state.kabelueberwachungChart.selectedMode + ); const chartRef = useRef(null); const chartInstance = useRef(null); @@ -28,14 +34,6 @@ const LoopMeasurementChart = () => { } }, []); - // Daten & Datum aus Redux abrufen - const { loopMeasurementCurveChartData, vonDatum, bisDatum } = useSelector( - (state: RootState) => state.kabelueberwachungChart - ); - const selectedMode = useSelector( - (state: RootState) => state.kabelueberwachungChart.selectedMode - ); - useEffect(() => { if (chartRef.current) { if (chartInstance.current) { @@ -46,20 +44,11 @@ const LoopMeasurementChart = () => { console.log("Von Datum:", vonDatum, "Bis Datum:", bisDatum); console.log("Selected Mode:", selectedMode); - // Daten filtern basierend auf vonDatum und bisDatum - const filteredData = loopMeasurementCurveChartData.filter((entry) => { - const timestampMs = new Date(entry.t).getTime(); - return ( - timestampMs >= new Date(vonDatum).getTime() && - timestampMs <= new Date(bisDatum).getTime() - ); - }); - - // Basis-Datasets für i (Minimum) und a (Maximum) + // Basis-Datasets für alle Datenpunkte const datasets = [ { label: "Messwert Minimum (kOhm)", - data: filteredData.map((entry) => ({ + data: loopMeasurementCurveChartData.map((entry) => ({ x: new Date(entry.t).getTime(), y: entry.i, })), @@ -69,7 +58,7 @@ const LoopMeasurementChart = () => { }, { label: "Messwert Maximum (kOhm)", - data: filteredData.map((entry) => ({ + data: loopMeasurementCurveChartData.map((entry) => ({ x: new Date(entry.t).getTime(), y: entry.a, })), @@ -82,11 +71,11 @@ const LoopMeasurementChart = () => { // Falls DIA0: `m` als aktueller Messwert verwenden if ( selectedMode === "DIA0" && - filteredData.some((entry) => entry.m !== undefined) + loopMeasurementCurveChartData.some((entry) => entry.m !== undefined) ) { datasets.push({ label: "Messwert Aktuell (m)", - data: filteredData.map((entry) => ({ + data: loopMeasurementCurveChartData.map((entry) => ({ x: new Date(entry.t).getTime(), y: entry.m ?? NaN, })), @@ -99,11 +88,11 @@ const LoopMeasurementChart = () => { // Falls DIA1 oder DIA2: `g` als Durchschnittswert verwenden if ( (selectedMode === "DIA1" || selectedMode === "DIA2") && - filteredData.some((entry) => entry.g !== undefined) + loopMeasurementCurveChartData.some((entry) => entry.g !== undefined) ) { datasets.push({ label: "Messwert Durchschnitt (g)", - data: filteredData.map((entry) => ({ + data: loopMeasurementCurveChartData.map((entry) => ({ x: new Date(entry.t).getTime(), y: entry.g ?? NaN, })), @@ -129,8 +118,8 @@ const LoopMeasurementChart = () => { type: "time", time: { unit: "day", - tooltipFormat: "dd.MM.yyyy HH:mm", // Ändert das Format für Tooltips (inkl. Uhrzeit) - displayFormats: { day: "dd.MM.yyyy" }, // Achse bleibt nur Datum + tooltipFormat: "dd.MM.yyyy HH:mm", + displayFormats: { day: "dd.MM.yyyy" }, }, title: { display: true, text: "Zeit (Datum)" }, min: new Date(vonDatum).getTime(), @@ -149,17 +138,9 @@ const LoopMeasurementChart = () => { callbacks: { label: (tooltipItem) => { const rawItem = tooltipItem.raw as { x: number; y: number }; - const date = new Date(rawItem.x); - const timeString = `${date - .getHours() - .toString() - .padStart(2, "0")}:${date - .getMinutes() - .toString() - .padStart(2, "0")}`; - return `${tooltipItem.dataset.label}: ${( - tooltipItem.raw as { x: number; y: number } - ).y.toFixed(2)} kOhm `; + return `${tooltipItem.dataset.label}: ${rawItem.y.toFixed( + 2 + )} kOhm`; }, }, }, @@ -169,6 +150,18 @@ const LoopMeasurementChart = () => { wheel: { enabled: true }, pinch: { enabled: true }, mode: "x", + onZoomComplete: (chart) => { + const xScale = chart.chart.scales.x; + const newVonDatum = new Date(xScale.min) + .toISOString() + .split("T")[0]; + const newBisDatum = new Date(xScale.max) + .toISOString() + .split("T")[0]; + + dispatch(setVonDatum(newVonDatum)); + dispatch(setBisDatum(newBisDatum)); + }, }, }, }, diff --git a/redux/slices/kabelueberwachungChartSlice.ts b/redux/slices/kabelueberwachungChartSlice.ts index 86a100f..b6f3d49 100644 --- a/redux/slices/kabelueberwachungChartSlice.ts +++ b/redux/slices/kabelueberwachungChartSlice.ts @@ -49,11 +49,11 @@ const kabelueberwachungChartSlice = createSlice({ }, // Aktion zum Setzen des Startdatums setVonDatum: (state, action: PayloadAction) => { - state.vonDatum = action.payload.replace(/-/g, ";"); + state.vonDatum = action.payload; // **Kein replace mehr** }, // Aktion zum Setzen des Enddatums setBisDatum: (state, action: PayloadAction) => { - state.bisDatum = action.payload.replace(/-/g, ";"); + state.bisDatum = action.payload; // **Kein replace mehr** }, // Aktion zum Setzen des ausgewählten Modus setSelectedMode: (