From 97f1ff99dfc10497389a3cf81d8fce6bc1631ac0 Mon Sep 17 00:00:00 2001 From: Mika Date: Thu, 5 Mar 2026 15:48:00 +0000 Subject: [PATCH] Add visualization_tool/js/charts.js --- visualization_tool/js/charts.js | 77 +++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 visualization_tool/js/charts.js diff --git a/visualization_tool/js/charts.js b/visualization_tool/js/charts.js new file mode 100644 index 0000000..a48f64d --- /dev/null +++ b/visualization_tool/js/charts.js @@ -0,0 +1,77 @@ +/** + * @module charts + * @description Verarbeitet Analyseergebnisse zu grafischen Darstellungen der Δt‑Verteilung. + * Enthält Funktionen zur Darstellung der Resultate in einem Canvas im Element #chart-panel. + */ + +/** + * Rendert ein einfaches Balkendiagramm der Δt‑Werte innerhalb #chart-panel. + * @param {Array<{run_id: string, category: string, delta_t: number, timestamp: string, status: string}>} results - Analyseergebnisse + */ +export function renderChart(results) { + const panel = document.getElementById('chart-panel'); + if (!panel) return; + + // Vorherige Inhalte leeren + panel.innerHTML = ''; + + // Canvas erzeugen + const canvas = document.createElement('canvas'); + canvas.setAttribute('aria-label', 'Δt‑Verteilung Diagramm'); + canvas.setAttribute('role', 'img'); + panel.appendChild(canvas); + + const ctx = canvas.getContext('2d'); + + // Daten vorbereiten: Zonen definieren und zählen + const bins = [ + { label: '< -2', min: -Infinity, max: -2 }, + { label: '-2 bis -1', min: -2, max: -1 }, + { label: '-1 bis 0', min: -1, max: 0 }, + { label: '0 bis 1', min: 0, max: 1 }, + { label: '> 1', min: 1, max: Infinity } + ]; + + const binCounts = bins.map(({ min, max }) => + results.filter(r => r.delta_t >= min && r.delta_t < max).length + ); + + const maxCount = Math.max(...binCounts, 1); + + const width = canvas.width = panel.clientWidth || 400; + const height = canvas.height = 300; + const barWidth = width / bins.length - 10; + + ctx.clearRect(0, 0, width, height); + ctx.font = '14px sans-serif'; + ctx.textAlign = 'center'; + ctx.textBaseline = 'top'; + + bins.forEach((bin, i) => { + const x = i * (barWidth + 10) + 10; + const y = height - (binCounts[i] / maxCount) * (height - 50); + const barHeight = (binCounts[i] / maxCount) * (height - 50); + + // Farbkennzeichnung: Δt < 0 Fälle hervorheben + const isCritical = bin.max <= 0; + ctx.fillStyle = isCritical ? 'hsl(0, 70%, 50%)' : 'hsl(210, 50%, 50%)'; + + ctx.fillRect(x, y, barWidth, barHeight); + ctx.fillStyle = '#000'; + ctx.fillText(bin.label, x + barWidth / 2, height - 20); + }); + + // Achsen zeichnen + ctx.strokeStyle = '#333'; + ctx.lineWidth = 1; + ctx.beginPath(); + ctx.moveTo(0, height - 30); + ctx.lineTo(width, height - 30); + ctx.stroke(); + + // Optional: Legende zeichnen + ctx.fillStyle = '#000'; + ctx.textAlign = 'left'; + ctx.fillText('Δt < 0 (kritisch): Rot', 10, 10); + ctx.fillText('Δt ≥ 0: Blau', 10, 30); +}