'use strict'; /** * uiRenderer.js * Verantwortlich für DOM-Manipulation zur Anzeige von Daten. * Enthält Rendering-Methoden für Timeline, Statistik-Zusammenfassungen und Tabellen. */ /** * Rendert die Timeline der write_pre / write_post Ereignisse. * @param {Array<{corr_id: string, type: string, timestamp: number, details?: object}>} eventPairs */ export function renderTimeline(eventPairs = []) { const panel = document.getElementById('timeline-panel'); if (!panel) return; panel.innerHTML = ''; if (!Array.isArray(eventPairs) || eventPairs.length === 0) { const msg = document.createElement('p'); msg.textContent = 'Keine Ereignisse vorhanden.'; panel.appendChild(msg); return; } const list = document.createElement('ul'); list.className = 'timeline__list'; eventPairs.forEach(event => { const item = document.createElement('li'); item.className = `timeline__item timeline__item--${event.type}`; const label = document.createElement('div'); label.className = 'timeline__label'; const tsDate = new Date(event.timestamp).toLocaleTimeString(); label.textContent = `${event.type} [${tsDate}] (corr: ${event.corr_id})`; item.appendChild(label); list.appendChild(item); }); panel.appendChild(list); } /** * Aktualisiert Statistik-Karten und Übersichten. * @param {Object} statsObj - Enthält berechnete Statistiken * @param {number} statsObj.totalEvents - Gesamtanzahl der Events * @param {number} statsObj.avgDuration - Durchschnittliche Dauer zwischen pre/post * @param {number} statsObj.numWrites - Anzahl write Events * @param {number} statsObj.numReads - Anzahl read Events */ export function renderStatsSummary(statsObj = {}) { const container = document.getElementById('stats-summary'); if (!container) return; const { totalEvents = 0, avgDuration = 0, numWrites = 0, numReads = 0 } = statsObj; container.innerHTML = ''; const createCard = (label, value) => { const card = document.createElement('div'); card.className = 'stats__card'; const header = document.createElement('h3'); header.textContent = label; const val = document.createElement('p'); val.textContent = value; card.append(header, val); return card; }; container.append( createCard('Gesamtanzahl Events', totalEvents), createCard('Durchschnittliche Dauer (ms)', avgDuration.toFixed(2)), createCard('Writes', numWrites), createCard('Reads', numReads) ); } /** * Füllt Tabelle mit den Schreib-/Lesepaaren. * @param {Array<{corr_id: string, type: string, timestamp: number, details?: object}>} dataPairs */ export function renderDataTable(dataPairs = []) { const table = document.getElementById('data-table'); if (!table) return; const tbody = table.querySelector('tbody') || document.createElement('tbody'); tbody.innerHTML = ''; if (!Array.isArray(dataPairs) || dataPairs.length === 0) { const tr = document.createElement('tr'); const td = document.createElement('td'); td.colSpan = 4; td.textContent = 'Keine Daten verfügbar'; tr.appendChild(td); tbody.appendChild(tr); table.appendChild(tbody); return; } dataPairs.forEach(item => { const tr = document.createElement('tr'); const tsFmt = new Date(item.timestamp).toLocaleString(); const cols = [ item.corr_id, item.type, tsFmt, item.details ? JSON.stringify(item.details) : '-' ]; cols.forEach(value => { const td = document.createElement('td'); td.textContent = value; tr.appendChild(td); }); tbody.appendChild(tr); }); table.appendChild(tbody); }