refactor: Auslagerung der Chart-Erstellungsfunktionen in chartUtils.ts

- createLoopChart und createTDRChart aus Kue705FO.tsx in eine separate Datei chartUtils.ts verschoben
- Verbesserte Code-Struktur und Wiederverwendbarkeit der Chart-Funktionen
- Import der ausgelagerten Funktionen in Kue705FO.tsx angepasst
This commit is contained in:
ISA
2025-02-10 13:32:53 +01:00
parent cb6e6d3926
commit 21e415a8ea
5 changed files with 266 additions and 185 deletions

View File

@@ -27,7 +27,7 @@ const Navigation: React.FC<NavigationProps> = ({ className }) => {
{ name: "Ein- und Ausgänge", path: "/einausgaenge" },
{ name: "Analoge Eingänge", path: "/analogeEingaenge" },
{ name: "Meldungen", path: "/messages" },
{ name: "Einstellung", path: "/settings" },
{ name: "Einstellungen", path: "/settings" },
// Weitere Menüpunkte hier
];

View File

@@ -13,6 +13,7 @@ import {
setSelectedFileName,
} from "../../redux/slices/variablesSlice";
import TDRPopup from "../modales/kueModal/TDRPopup";
import { createLoopChart, createTDRChart } from "../../utils/chartUtils";
const Kue705FO: React.FC<Kue705FOProps> = ({
isolationswert,
@@ -192,97 +193,6 @@ const Kue705FO: React.FC<Kue705FOProps> = ({
const chartInstance = useRef<Chart | null>(null);
const createTDRChart = (dataTDR: DataTDR[]) => {
const canvas = document.getElementById("myChart") as HTMLCanvasElement;
if (!canvas) {
console.error("Canvas mit ID 'myChart' nicht gefunden.");
return;
}
const ctx = canvas.getContext("2d");
if (!ctx) {
console.error("2D-Kontext für Canvas konnte nicht erstellt werden.");
return;
}
// Vorhandenes Chart zerstören, falls vorhanden
if (chartInstance.current) {
console.log("Vorhandenes Chart wird zerstört.");
chartInstance.current.destroy();
chartInstance.current = null; // Referenz zurücksetzen
}
// Maximal- und Minimalwerte berechnen
const minX = Math.min(...dataTDR.map((row) => row.t));
const maxX = Math.max(...dataTDR.map((row) => row.t));
const minY = Math.min(...dataTDR.map((row) => row.m));
const maxY = Math.max(...dataTDR.map((row) => row.m));
// Neues Chart erstellen
try {
chartInstance.current = new Chart(ctx, {
type: "line",
data: {
labels: dataTDR.map((row) => row.t),
datasets: [
{
label: "Pegel",
data: dataTDR.map((row) => row.m),
borderColor: "#00AEEF",
borderWidth: 2,
fill: false,
tension: 0.1, // Weiche Kurve
},
],
},
options: {
responsive: true,
maintainAspectRatio: false, // Ermöglicht flexible Größe
layout: {
padding: {
bottom: 25, // Fügt zusätzliches Padding unten hinzu
},
},
plugins: {
zoom: {
pan: {
enabled: true,
mode: "xy",
},
zoom: {
wheel: {
enabled: true,
},
pinch: {
enabled: true,
},
mode: "xy",
},
},
},
scales: {
x: {
type: "linear",
position: "bottom",
title: { display: true, text: "Entfernung" },
min: minX - 5, // Etwas Puffer hinzufügen
max: maxX + 5,
},
y: {
title: { display: true, text: "Pegel" },
min: minY - 10, // Puffer für Y-Werte
max: maxY + 10,
},
},
},
});
console.log("Neues Chart erfolgreich erstellt.");
} catch (error) {
console.error("Fehler beim Erstellen des Charts:", error);
}
};
const selectedFileName = useSelector(
(state: RootState) => state.variables.selectedFileName
);
@@ -347,96 +257,6 @@ const Kue705FO: React.FC<Kue705FOProps> = ({
n: number; // Schleifenwiderstand
}
const createLoopChart = (data: DataLoop[], title: string) => {
const canvas = document.getElementById("myChart") as HTMLCanvasElement;
if (!canvas) {
console.error("Canvas mit ID 'myChart' nicht gefunden.");
return;
}
const ctx = canvas.getContext("2d");
if (!ctx) {
console.error("2D-Kontext für Canvas konnte nicht erstellt werden.");
return;
}
// Konvertiere Zeitstempel in ein lesbares Format für die X-Achse
const labels = data.map((row) => {
const date = new Date(String(row.t).replace(/-/g, "/")); // Zeitstring parsen
return date.toLocaleString("de-DE", {
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
});
});
new Chart(ctx, {
type: "line",
data: {
labels,
datasets: [
{
label: "Isolationswiderstand (MOhm)",
data: data.map((row) => row.m),
borderColor: "#00AEEF",
borderWidth: 1,
tension: 0.1, // Glättung der Linie
pointRadius: 1,
pointHoverRadius: 5,
fill: false,
yAxisID: "y",
},
{
label: "Schleifenwiderstand (kOhm)",
data: data.map((row) => row.n),
borderColor: "black",
borderWidth: 1,
tension: 0.1,
pointRadius: 1,
pointHoverRadius: 5,
fill: false,
yAxisID: "y1",
},
],
},
options: {
scales: {
x: {
type: "category",
title: { display: true, text: "Zeit" },
},
y: {
type: "linear",
position: "left",
title: { display: true, text: "MOhm" },
},
y1: {
type: "linear",
position: "right",
title: { display: true, text: "kOhm" },
},
},
plugins: {
zoom: {
pan: {
enabled: true,
mode: "xy",
},
zoom: {
wheel: {
enabled: true,
},
pinch: {
enabled: true,
},
mode: "xy",
},
},
},
},
});
};
useEffect(() => {
const updateAlarmStatus = () => {
const alarmStatus =

View File

@@ -1,5 +1,113 @@
import React from "react";
import React, { useState } from "react";
export default function OPCUAInterfaceSettings() {
return <div>OPCUAInterfaceSettings</div>;
const [isEnabled, setIsEnabled] = useState(true);
const [encryption, setEncryption] = useState("None");
const [users, setUsers] = useState([
{ id: 1, username: "admin", password: "admin123" },
{ id: 2, username: "user1", password: "user123" },
]);
const [newUser, setNewUser] = useState({ username: "", password: "" });
const toggleServer = () => setIsEnabled(!isEnabled);
const updateEncryption = (event) => setEncryption(event.target.value);
const addUser = () => {
if (newUser.username && newUser.password) {
setUsers([...users, { id: users.length + 1, ...newUser }]);
setNewUser({ username: "", password: "" });
}
};
const removeUser = (id) => setUsers(users.filter((user) => user.id !== id));
return (
<div className="max-w-3xl mx-auto p-6 bg-gray-100 shadow-md rounded-lg">
<h2 className="text-xl font-semibold mb-4">OPCUA Server Einstellungen</h2>
{/* Server Aktivierung */}
<div className="mb-4">
<label className="flex items-center cursor-pointer">
<input
type="checkbox"
checked={isEnabled}
onChange={toggleServer}
className="hidden"
/>
<div
className={`w-12 h-6 rounded-full transition-all ${
isEnabled ? "bg-green-500" : "bg-gray-300"
}`}
></div>
<span className="ml-2 text-sm">
{isEnabled ? "Aktiviert" : "Deaktiviert"}
</span>
</label>
</div>
{/* Verschlüsselung */}
<div className="mb-4">
<label className="block text-sm font-medium text-gray-700">
Verschlüsselung
</label>
<select
value={encryption}
onChange={updateEncryption}
className="mt-1 block w-full p-2 border border-gray-300 rounded-md shadow-sm focus:ring focus:ring-blue-200"
>
<option value="None">Keine</option>
<option value="Basic256">Basic256</option>
<option value="Basic256Sha256">Basic256Sha256</option>
</select>
</div>
{/* Benutzer & Passwörter */}
<div className="mb-4">
<h3 className="text-lg font-semibold mb-2">Benutzer</h3>
<ul className="space-y-2">
{users.map((user) => (
<li
key={user.id}
className="p-2 bg-white shadow-sm rounded-md flex justify-between items-center"
>
<span className="font-medium">{user.username}</span>
<span className="text-gray-600 ml-2">
(Passwort: {user.password})
</span>
<button
onClick={() => removeUser(user.id)}
className="ml-4 text-red-500"
>
Löschen
</button>
</li>
))}
</ul>
<div className="mt-4">
<input
type="text"
placeholder="Benutzername"
value={newUser.username}
onChange={(e) =>
setNewUser({ ...newUser, username: e.target.value })
}
className="p-2 border rounded mr-2"
/>
<input
type="password"
placeholder="Passwort"
value={newUser.password}
onChange={(e) =>
setNewUser({ ...newUser, password: e.target.value })
}
className="p-2 border rounded mr-2"
/>
<button
onClick={addUser}
className="bg-blue-500 text-white p-2 rounded"
>
Hinzufügen
</button>
</div>
</div>
</div>
);
}

View File

@@ -17,7 +17,7 @@ export default function Settings() {
}`}
onClick={() => setActiveTab("tab1")}
>
Allgemeine Einstellung
Allgemeine Einstellungen
</button>
<button
className={`px-4 py-2 ${

153
utils/chartUtils.ts Normal file
View File

@@ -0,0 +1,153 @@
"use client";
import Chart from "chart.js/auto";
import { DataTDR } from "../redux/types/chartDataTypesTDR";
const chartInstance = { current: null as Chart | null };
/**
* Erstellt ein TDR-Chart basierend auf den übergebenen Daten.
*/
export const createTDRChart = (dataTDR: DataTDR[]) => {
const canvas = document.getElementById("myChart") as HTMLCanvasElement;
if (!canvas) {
console.error("Canvas mit ID 'myChart' nicht gefunden.");
return;
}
const ctx = canvas.getContext("2d");
if (!ctx) {
console.error("2D-Kontext für Canvas konnte nicht erstellt werden.");
return;
}
if (chartInstance.current) {
chartInstance.current.destroy();
chartInstance.current = null;
}
const minX = Math.min(...dataTDR.map((row) => row.t));
const maxX = Math.max(...dataTDR.map((row) => row.t));
const minY = Math.min(...dataTDR.map((row) => row.m));
const maxY = Math.max(...dataTDR.map((row) => row.m));
try {
chartInstance.current = new Chart(ctx, {
type: "line",
data: {
labels: dataTDR.map((row) => row.t),
datasets: [
{
label: "Pegel",
data: dataTDR.map((row) => row.m),
borderColor: "#00AEEF",
borderWidth: 2,
fill: false,
tension: 0.1,
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
x: {
type: "linear",
position: "bottom",
title: { display: true, text: "Entfernung" },
min: minX - 5,
max: maxX + 5,
},
y: {
title: { display: true, text: "Pegel" },
min: minY - 10,
max: maxY + 10,
},
},
},
});
} catch (error) {
console.error("Fehler beim Erstellen des TDR-Charts:", error);
}
};
interface DataLoop {
t: number;
m: number;
n: number;
}
/**
* Erstellt ein Schleifenmess-Chart basierend auf den übergebenen Daten.
*/
export const createLoopChart = (data: DataLoop[], title: string) => {
const canvas = document.getElementById("myChart") as HTMLCanvasElement;
if (!canvas) {
console.error("Canvas mit ID 'myChart' nicht gefunden.");
return;
}
const ctx = canvas.getContext("2d");
if (!ctx) {
console.error("2D-Kontext für Canvas konnte nicht erstellt werden.");
return;
}
const labels = data.map((row) => {
const date = new Date(String(row.t).replace(/-/g, "/"));
return date.toLocaleString("de-DE", {
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
});
});
new Chart(ctx, {
type: "line",
data: {
labels,
datasets: [
{
label: "Isolationswiderstand (MOhm)",
data: data.map((row) => row.m),
borderColor: "#00AEEF",
borderWidth: 1,
tension: 0.1,
pointRadius: 1,
pointHoverRadius: 5,
fill: false,
yAxisID: "y",
},
{
label: "Schleifenwiderstand (kOhm)",
data: data.map((row) => row.n),
borderColor: "black",
borderWidth: 1,
tension: 0.1,
pointRadius: 1,
pointHoverRadius: 5,
fill: false,
yAxisID: "y1",
},
],
},
options: {
scales: {
x: {
type: "category",
title: { display: true, text: "Zeit" },
},
y: {
type: "linear",
position: "left",
title: { display: true, text: "MOhm" },
},
y1: {
type: "linear",
position: "right",
title: { display: true, text: "kOhm" },
},
},
},
});
};