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

171 lines
4.8 KiB
TypeScript

"use client";
import React, { useCallback, useEffect, useMemo } from "react";
import { useSelector, useDispatch } from "react-redux";
import { RootState } from "../../../../../../redux/store";
import {
ComposedChart,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
Legend,
ResponsiveContainer,
Line,
Brush,
} from "recharts";
import { setBrushRange } from "../../../../../../redux/slices/brushSlice";
const CustomTooltip = ({ active, payload, label }: any) => {
if (active && payload && payload.length) {
const messwertMax = payload.find(
(p: any) => p.dataKey === "messwertMaximum"
);
const messwert = payload.find((p: any) => p.dataKey === "messwert");
const messwertMin = payload.find(
(p: any) => p.dataKey === "messwertMinimum"
);
const messwertDurchschnitt = payload.find(
(p: any) => p.dataKey === "messwertDurchschnitt"
);
return (
<div
style={{
background: "white",
padding: "8px",
border: "1px solid lightgrey",
borderRadius: "5px",
}}
>
<strong>{new Date(label).toLocaleString()}</strong>
{messwertMax && (
<div style={{ color: "grey" }}>
Messwert Maximum: {messwertMax.value.toFixed(2)} kOhm
</div>
)}
{messwert && (
<div style={{ color: "#00AEEF", fontWeight: "bold" }}>
Messwert: {messwert.value.toFixed(2)} kOhm
</div>
)}
{messwertDurchschnitt && (
<div
style={{ color: "#00AEEF" }}
>{`Messwert Durchschnitt: ${messwertDurchschnitt.value.toFixed(
2
)} kOhm`}</div>
)}
{messwertMin && (
<div
style={{ color: "grey" }}
>{`Messwert Minimum: ${messwertMin.value.toFixed(2)} kOhm`}</div>
)}
</div>
);
}
return null;
};
const LoopMeasurementChart = () => {
const dispatch = useDispatch();
const brushRange = useSelector((state: RootState) => state.brush);
const {
loopMeasurementCurveChartData,
selectedMode,
vonDatum,
bisDatum,
isFullScreen,
} = useSelector((state: RootState) => state.kabelueberwachungChart);
const formatierteDaten = useMemo(
() =>
loopMeasurementCurveChartData
.map((eintrag) => ({
zeit: new Date(eintrag.t).getTime(),
messwertMinimum: eintrag.i,
messwertMaximum: eintrag.a,
messwert: eintrag.m ?? null,
messwertDurchschnitt: ["DIA1", "DIA2"].includes(selectedMode)
? eintrag.g ?? null
: null,
}))
.reverse(),
[loopMeasurementCurveChartData, selectedMode]
);
// Initialisierung des Brush-Bereichs nur beim ersten Laden der Daten
useEffect(() => {
if (brushRange.endIndex === 0 && formatierteDaten.length) {
dispatch(
setBrushRange({
startIndex: 0,
endIndex: formatierteDaten.length - 1,
})
);
}
}, [formatierteDaten, brushRange.endIndex, dispatch]);
const handleBrushChange = useCallback(
({ startIndex, endIndex }) => {
dispatch(setBrushRange({ startIndex, endIndex }));
},
[dispatch]
);
return (
<div style={{ width: "100%", height: isFullScreen ? "90%" : "400px" }}>
<ResponsiveContainer width="100%" height="100%">
<ComposedChart data={formatierteDaten}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis
dataKey="zeit"
domain={["dataMin", "dataMax"]}
tickFormatter={(zeit) => new Date(zeit).toLocaleDateString()}
/>
<YAxis
label={{ value: "kOhm", angle: -90, position: "insideLeft" }}
domain={["auto", "auto"]}
tickFormatter={(wert) => `${wert.toFixed(2)} kOhm`}
/>
<Tooltip content={<CustomTooltip />} />
<Legend />
<Line
type="monotone"
dataKey="messwertMinimum"
stroke="lightgrey"
dot={false}
/>
<Line
type="monotone"
dataKey="messwertMaximum"
stroke="lightgrey"
dot={false}
/>
{["DIA1", "DIA2"].includes(selectedMode) && (
<Line
type="monotone"
dataKey="messwertDurchschnitt"
stroke="#00AEEF"
dot
/>
)}
{selectedMode === "DIA0" && (
<Line type="monotone" dataKey="messwert" stroke="#00AEEF" dot />
)}
<Brush
dataKey="zeit"
height={30}
stroke="#8884d8"
onChange={handleBrushChange}
startIndex={brushRange.startIndex}
endIndex={brushRange.endIndex || formatierteDaten.length - 1}
/>
</ComposedChart>
</ResponsiveContainer>
</div>
);
};
export default LoopMeasurementChart;