Files
CPLv4.0/components/main/kabelueberwachung/kue705FO/Charts/TDRChart/TDRChart.tsx

197 lines
6.5 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 } from "react-redux";
import { Chart, registerables } from "chart.js";
import "chartjs-adapter-date-fns";
import { getColor } from "../../../../../../utils/colors";
import TDRChartActionBar from "./TDRChartActionBar";
const TDRChart: React.FC<{ isFullScreen: boolean }> = ({ isFullScreen }) => {
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.tdrDataById.selectedId
);
const selectedSlot = useSelector(
(state: RootState) => state.kueChartMode.selectedSlot
);
const selectedChartType = useSelector(
(state: RootState) => state.kueChartMode.activeMode
);
const tdrDataById = useSelector(
(state: RootState) => state.tdrDataById.dataById
);
const tdrInitialData = useSelector((state: RootState) =>
selectedSlot !== null ? state.tdrChart.data[selectedSlot] || [] : []
);
// Kombinierte Logik: ID hat Vorrang, sonst Initial-Daten für Slot
const tdrChartData = useMemo(() => {
if (selectedId !== null && tdrDataById[selectedId]) {
return tdrDataById[selectedId];
}
return tdrInitialData;
}, [selectedId, tdrDataById, tdrInitialData]);
const referenceChartData = useSelector((state: RootState) =>
selectedSlot !== null
? state.tdrReferenceChart.referenceData[selectedSlot] || []
: []
);
//--------------------------------
const tdmChartData = useSelector((state: RootState) => state.tdmChart.data);
const pinDistance =
Array.isArray(tdmChartData?.[selectedSlot ?? -1]) &&
tdmChartData[selectedSlot!]?.length > 0 &&
typeof tdmChartData[selectedSlot!][0].d === "number"
? tdmChartData[selectedSlot!][0].d
: 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 : "?"
}`,
data: tdrChartData,
borderColor: getColor("littwin-blue"),
borderWidth: 1,
tension: 0.1,
parsing: {
xAxisKey: "d",
yAxisKey: "p",
},
},
{
label: "Referenzkurve",
data: referenceChartData,
borderColor: "black",
borderWidth: 1,
borderDash: [5, 5],
pointRadius: 3,
pointHoverRadius: 5,
pointBackgroundColor: "black",
tension: 0.1,
parsing: {
xAxisKey: "d",
yAxisKey: "p",
},
},
{
label: "Fehlerstelle",
data: pinDistance !== null ? [{ d: pinDistance, p: 0 }] : [],
borderColor: "red",
backgroundColor: "red",
pointRadius: 5,
pointStyle: "circle",
showLine: false,
parsing: {
xAxisKey: "d",
yAxisKey: "p",
},
},
],
},
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: {
callbacks: {
title: () => "", // 🚫 Entfernt die erste Zeile mit der Nummer
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), 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;