diff --git a/data_visualization_web_ui/js/charts.js b/data_visualization_web_ui/js/charts.js new file mode 100644 index 0000000..6a47b06 --- /dev/null +++ b/data_visualization_web_ui/js/charts.js @@ -0,0 +1,161 @@ +/* + * charts.js — chart_logic for data_visualization_web_ui + * Verantwortlich für das Zeichnen und Aktualisieren der Magnetometer-Zeitreihen + * und Analyse-Zusammenfassung. + */ + +/** + * Erstellt und rendert Zeitreihen-Diagramme (Bx, By, Bz) basierend auf Messdaten. + * @param {Array<{timestamp: string, sensor: string, Bx: number, By: number, Bz: number}>} data - Messwerte + * @param {HTMLCanvasElement} canvas - Canvas-Element zur Darstellung + * @returns {Chart|null} ChartJS-Instanz oder null, wenn keine Daten vorhanden + */ +export function renderDataCharts(data, canvas) { + if (!Array.isArray(data) || data.length === 0 || !canvas) return null; + + const ctx = canvas.getContext('2d'); + const timestamps = data.map(d => new Date(d.timestamp).toLocaleTimeString()); + const bx = data.map(d => d.Bx); + const by = data.map(d => d.By); + const bz = data.map(d => d.Bz); + + // Falls vorheriger Chart vorhanden: zerstören + if (canvas._chartInstance) { + canvas._chartInstance.destroy(); + } + + const chart = new Chart(ctx, { + type: 'line', + data: { + labels: timestamps, + datasets: [ + { + label: 'Bx', + data: bx, + borderColor: '#1e88e5', + fill: false, + tension: 0.1 + }, + { + label: 'By', + data: by, + borderColor: '#43a047', + fill: false, + tension: 0.1 + }, + { + label: 'Bz', + data: bz, + borderColor: '#f4511e', + fill: false, + tension: 0.1 + } + ] + }, + options: { + responsive: true, + maintainAspectRatio: false, + interaction: { + mode: 'index', + intersect: false + }, + scales: { + x: { + title: { + display: true, + text: 'Zeit' + } + }, + y: { + title: { + display: true, + text: 'Feldstärke (nT)' + } + } + }, + plugins: { + legend: { + position: 'top' + }, + tooltip: { + mode: 'nearest' + } + } + } + }); + + canvas._chartInstance = chart; + return chart; +} + +/** + * Zeigt Analyseergebnisse im DOM an (z. B. Durchschnittswerte, Peaks, Noise, Drift). + * @param {{mean?: number, peaks?: number[], noise?: number, drift?: number}} analysis - Analyseobjekt + * @returns {void} + */ +export function renderAnalysisSummary(analysis) { + const panel = document.querySelector('#analysis-panel'); + if (!panel) return; + + panel.innerHTML = ''; + + const summaryList = document.createElement('ul'); + summaryList.className = 'analysis__list'; + + const addItem = (label, value) => { + const li = document.createElement('li'); + li.className = 'analysis__item'; + li.textContent = `${label}: ${value ?? 'n/a'}`; + summaryList.appendChild(li); + }; + + addItem('Durchschnitt', analysis.mean !== undefined ? analysis.mean.toFixed(2) : 'n/a'); + + if (Array.isArray(analysis.peaks)) { + addItem('Peaks', analysis.peaks.join(', ')); + } + + addItem('Noise', analysis.noise !== undefined ? analysis.noise.toFixed(2) : 'n/a'); + addItem('Drift', analysis.drift !== undefined ? analysis.drift.toFixed(4) : 'n/a'); + + panel.appendChild(summaryList); + + // Kleinvisualisierung: Balkendiagramm für Peaks, falls vorhanden + if (Array.isArray(analysis.peaks) && analysis.peaks.length > 0) { + const canvas = document.createElement('canvas'); + canvas.className = 'analysis__peaks-chart'; + panel.appendChild(canvas); + + const ctx = canvas.getContext('2d'); + if (canvas._chartInstance) { + canvas._chartInstance.destroy(); + } + + canvas._chartInstance = new Chart(ctx, { + type: 'bar', + data: { + labels: analysis.peaks.map((_, i) => `Peak ${i + 1}`), + datasets: [ + { + label: 'Peakw e rte', + data: analysis.peaks, + backgroundColor: '#1e88e5' + } + ] + }, + options: { + responsive: true, + maintainAspectRatio: false, + plugins: { + legend: { display: false } + }, + scales: { + x: { title: { display: true, text: 'Index' } }, + y: { title: { display: true, text: 'Wert' } } + } + } + }); + } +} + +// © 2026 Donau2Space.de \ No newline at end of file