Files
CPLv4.0/components/main/kabelueberwachung/kue705FO/Charts/TDRChart/TDRChart.tsx
ISA 20e20dec30 feat(redux): Rename all Redux slices and store keys to match file names for clarity
- Renamed all slice names (createSlice `name` attribute) to match their file names (e.g. loopChartSlice, authSlice, kueDataSlice etc.)
- Updated `store.ts` to register each reducer with consistent key names (e.g. state.loopChartSlice instead of state.loopChart)
- Adjusted all `useSelector` and Redux state accesses across the codebase
- Improves maintainability, searchability and consistency across files and Redux DevTools
2025-04-01 12:26:41 +02:00

230 lines
7.6 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// components/main/kabelueberwachung/kue705FO/Charts/TDRChart/TDRChart.tsx
"use client";
import React, { useEffect, useRef, useMemo } from "react";
import { RootState } from "../../../../../../redux/store";
import { useSelector, useDispatch } from "react-redux";
import { AppDispatch } from "../../../../../../redux/store";
import { Chart, registerables } from "chart.js";
import "chartjs-adapter-date-fns";
import { getColor } from "../../../../../../utils/colors";
import TDRChartActionBar from "./TDRChartActionBar";
import { fetchReferenceCurveBySlotThunk } from "../../../../../../redux/thunks/fetchReferenceCurveBySlotThunk";
const TDRChart: React.FC<{ isFullScreen: boolean }> = ({ isFullScreen }) => {
const dispatch = useDispatch<AppDispatch>();
//---------------------------------
const chartRef = useRef<HTMLCanvasElement>(null);
const chartInstance = useRef<Chart | null>(null);
// 🟢 **Hole den ausgewählten Slot und Messkurve aus Redux**
const selectedId = useSelector(
(state: RootState) => state.tdrDataByIdSlice.selectedId
);
const selectedSlot = useSelector(
(state: RootState) => state.kueChartModeSlice.selectedSlot
);
const selectedChartType = useSelector(
(state: RootState) => state.kueChartModeSlice.activeMode
);
const tdrDataById = useSelector(
(state: RootState) => state.tdrDataByIdSlice.dataById
);
//--------------------------------
const tdrInitialData =
selectedId !== null && tdrDataById[selectedId]
? tdrDataById[selectedId]
: [];
//--------------------------------
// Kombinierte Logik: ID hat Vorrang, sonst Initial-Daten für Slot
const tdrChartData =
selectedId !== null && tdrDataById[selectedId]
? tdrDataById[selectedId]
: [];
//--------------------------------
const referenceChartData = useSelector((state: RootState) =>
selectedSlot !== null
? state.tdrReferenceChartDataBySlotSlice.referenceData[selectedSlot] || []
: []
);
//--------------------------------
useEffect(() => {
if (selectedSlot !== null) {
dispatch(fetchReferenceCurveBySlotThunk(selectedSlot));
}
}, [selectedSlot, dispatch]);
//--------------------------------
const tdmChartData = useSelector(
(state: RootState) => state.tdmSingleChartSlice.data
);
const pinDistance =
selectedId !== null && Array.isArray(tdmChartData?.[selectedSlot ?? -1])
? tdmChartData[selectedSlot!].find((entry) => entry.id === selectedId)
?.d ?? null
: null;
//--------------------------------
useEffect(() => {
import("chartjs-plugin-zoom").then((zoomPlugin) => {
Chart.register(...registerables, zoomPlugin.default);
if (chartRef.current && tdrChartData.length > 0) {
if (chartInstance.current) {
chartInstance.current.destroy();
}
const ctx = chartRef.current.getContext("2d");
if (ctx) {
chartInstance.current = new Chart(ctx, {
type: "line",
data: {
datasets: [
{
/* label: `Modul ${
selectedSlot !== null ? selectedSlot + 1 : "?"
}`, */
label: `TDR Kurve`,
data: tdrChartData,
borderColor: getColor("littwin-blue"),
borderWidth: 1,
tension: 0.1,
pointRadius: 0,
pointHoverRadius: 5,
parsing: {
xAxisKey: "d",
yAxisKey: "p",
},
},
{
label: "Referenzkurve",
data: referenceChartData,
borderColor: "black",
borderWidth: 1,
// borderDash: [5, 5],
pointRadius: 0,
pointHoverRadius: 5,
pointBackgroundColor: "gray",
tension: 0.1,
parsing: {
xAxisKey: "d",
yAxisKey: "p",
},
},
{
label: "Fehlerstelle",
data:
pinDistance !== null && typeof pinDistance === "number"
? [{ d: pinDistance, p: 0 }]
: [],
borderColor: "red",
backgroundColor: "red",
pointRadius: 10,
pointStyle: "triangle", // Hier den korrekten Stil setzen
showLine: false,
clip: false, // Wenn du die Fehlerstelle sichtbar sehen möchtest
parsing: {
xAxisKey: "d",
yAxisKey: "p",
},
order: 9999,
pointHoverRadius: 15,
// Hier die Reihenfolge der Marker bestimmen
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
animation: {
duration: 150, // 150 ms Animation
},
scales: {
x: {
type: "linear",
title: {
display: true,
text: "Entfernung (m)",
},
},
y: {
title: {
display: true,
text: "Pegel",
},
},
},
plugins: {
tooltip: {
yAlign: "bottom", // Tooltip oberhalb des Punktes
callbacks: {
title: () => "Fehlerstelle", // Kein Titel
label: function (context) {
const rawData = context.raw as { d: number; p: number };
// 👇 Unterscheide zwischen Mess- und Referenzkurve
if (context.dataset.label === "Referenzkurve") {
return [
`Referenzwert`,
`Entfernung: ${rawData.d.toFixed(0)} Meter`,
`Pegel: ${rawData.p.toFixed(2)}`,
];
} else {
return [
`Messwert`,
`Entfernung: ${rawData.d.toFixed(0)} Meter`,
`Pegel: ${rawData.p.toFixed(2)}`,
];
}
},
},
},
zoom: {
pan: {
enabled: true,
mode: "xy",
},
zoom: {
wheel: {
enabled: true,
},
pinch: {
enabled: true,
},
mode: "xy",
},
},
},
},
});
}
}
});
}, [
JSON.stringify(tdrChartData),
JSON.stringify(referenceChartData),
selectedSlot,
selectedChartType,
]);
//--------------------------------------
return (
<div style={{ width: "100%", height: isFullScreen ? "90%" : "28rem" }}>
<TDRChartActionBar />
{tdrChartData.length === 0 ? (
<div className="flex items-center justify-center h-full text-gray-500 italic">
Keine Daten verfügbar für diesen Slot
</div>
) : (
<canvas ref={chartRef} style={{ width: "100%", height: "100%" }} />
)}
</div>
);
};
export default TDRChart;