eBPF_Write_Hooks_Analysis/results_visualization/js/uiRenderer.js

121 lines
3.6 KiB
JavaScript

'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);
}