'use strict'; /** * @module ui * Funktionen zur Aktualisierung der visuellen Komponenten (Karten und Diagramme) */ /** * Aktualisiert die Kennzahlenkarten im DOM basierend auf API-Daten. * @param {Object} retry_analysis_report - JSON Report aus der API /api/retry-stats */ export function renderSummaryCards(retry_analysis_report) { const container = document.getElementById('stats-summary'); if (!container) return; container.innerHTML = ''; const metrics = [ { label: '\u0394t<0', value: retry_analysis_report?.delta_t_neg_rate ?? 'N/A', unit: '%' }, { label: 'Warn Rate', value: retry_analysis_report?.warn_rate ?? 'N/A', unit: '%' }, { label: 'Unknown Rate', value: retry_analysis_report?.unknown_rate ?? 'N/A', unit: '%' }, { label: 'Heilungsrate', value: retry_analysis_report?.healing_rate ?? 'N/A', unit: '%' }, { label: 'p95', value: retry_analysis_report?.p95 ?? 'N/A', unit: 'ms' }, { label: 'p99', value: retry_analysis_report?.p99 ?? 'N/A', unit: 'ms' } ]; const frag = document.createDocumentFragment(); metrics.forEach(metric => { const card = document.createElement('div'); card.className = 'summary-card'; const title = document.createElement('h3'); title.textContent = metric.label; const value = document.createElement('p'); value.className = 'summary-card__value'; value.textContent = `${metric.value} ${metric.unit}`; card.appendChild(title); card.appendChild(value); frag.appendChild(card); }); container.appendChild(frag); } /** * Erzeugt oder aktualisiert ein Diagramm in #retry-chart basierend auf API-Daten. * @param {Object} retry_analysis_report - JSON Report aus der API /api/retry-stats */ export function renderRetryChart(retry_analysis_report) { const chartContainer = document.getElementById('retry-chart'); if (!chartContainer) return; chartContainer.innerHTML = ''; const canvas = document.createElement('canvas'); canvas.id = 'retryChartCanvas'; canvas.setAttribute('aria-label', 'Retry Statistik Diagramm'); chartContainer.appendChild(canvas); const ctx = canvas.getContext('2d'); if (!ctx) return; // Minimalistische Chart-Implementation ohne externe Libraries const { stats = [] } = retry_analysis_report || {}; if (stats.length === 0) { ctx.fillStyle = '#666'; ctx.font = '16px sans-serif'; ctx.fillText('Keine Daten verfügbar', 10, 30); return; } const width = canvas.width = chartContainer.clientWidth || 400; const height = canvas.height = 200; const margin = 20; const colorP95 = '#2c7'; const colorP99 = '#f93'; const maxValue = Math.max(...stats.map(s => Math.max(s.p95 ?? 0, s.p99 ?? 0))); const barWidth = Math.max(5, (width - margin * 2) / stats.length); stats.forEach((s, index) => { const x = margin + index * barWidth; const p95Height = ((s.p95 ?? 0) / maxValue) * (height - margin * 2); const p99Height = ((s.p99 ?? 0) / maxValue) * (height - margin * 2); // p95 bar ctx.fillStyle = colorP95; ctx.fillRect(x, height - p95Height - margin, barWidth * 0.4, p95Height); // p99 bar ctx.fillStyle = colorP99; ctx.fillRect(x + barWidth * 0.5, height - p99Height - margin, barWidth * 0.4, p99Height); }); // Axis Labels ctx.fillStyle = '#000'; ctx.font = '12px sans-serif'; ctx.fillText('p95', 10, 12); ctx.fillText('p99', 50, 12); }