165 lines
5.4 KiB
TypeScript
165 lines
5.4 KiB
TypeScript
// components/main/kabelueberwachung/kue705FO/Charts/TDRChart/TDRChart.tsx
|
||
"use client";
|
||
|
||
import React, { useEffect, useRef } 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 tdrChartData = useSelector((state: RootState) =>
|
||
selectedId !== null ? state.tdrDataById.dataById[selectedId] || [] : []
|
||
);
|
||
|
||
const referenceChartData = useSelector((state: RootState) =>
|
||
selectedSlot !== null
|
||
? state.tdrReferenceChart.referenceData[selectedSlot] || []
|
||
: []
|
||
);
|
||
|
||
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", // Entfernung/distance // statt "t"
|
||
yAxisKey: "p", // Pegel // statt "m"
|
||
},
|
||
},
|
||
{
|
||
label: "Referenzkurve",
|
||
data: referenceChartData,
|
||
borderColor: "black", // Schwarz für Referenzkurve
|
||
borderWidth: 1,
|
||
borderDash: [5, 5], // Gepunktete Linie
|
||
pointRadius: 3, // Punkte für Tooltip sichtbar machen
|
||
pointHoverRadius: 5, // Größere Punkte beim Hover
|
||
pointBackgroundColor: "black",
|
||
tension: 0.1,
|
||
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;
|