gate_v0_analysis/result_visualization/js/app.js

144 lines
No EOL
4 KiB
JavaScript

'use strict';
/**
* Gate v0 Analysis - Result Visualization
* Initializer File: js/app.js
* © 2026 Donau2Space.de
*/
/**
* Lädt die Analyseergebnisse vom /results-Endpunkt und initialisiert die Visualisierungskomponenten.
* @async
* @function initApp
* @returns {Promise<void>}
*/
async function initApp() {
try {
showLoadingState(true);
const params = getFilterParams();
const queryString = new URLSearchParams(params).toString();
const url = queryString ? `/results?${queryString}` : '/results';
const response = await fetch(url, { method: 'GET' });
if (!response.ok) {
throw new Error(`API-Fehler: ${response.status}`);
}
const results = await response.json();
renderResults(results);
bindFilterEvents();
} catch (error) {
console.error('Fehler beim Initialisieren der Anwendung:', error);
displayError('Es ist ein Fehler beim Laden der Ergebnisse aufgetreten.');
} finally {
showLoadingState(false);
}
}
/**
* Bindet Event-Handler an Filterelemente, um bei Änderungen neue Daten zu laden.
* @function bindFilterEvents
* @returns {void}
*/
function bindFilterEvents() {
const runTypeSelect = document.querySelector('#filter-run-type');
const metricSelect = document.querySelector('#filter-metric');
if (runTypeSelect) {
runTypeSelect.addEventListener('change', initApp);
}
if (metricSelect) {
metricSelect.addEventListener('change', initApp);
}
}
/**
* Liest aktuelle Filterparameter aus.
* @returns {Object} - Objekt mit Filterparametern
*/
function getFilterParams() {
const runType = document.querySelector('#filter-run-type')?.value || '';
const metric = document.querySelector('#filter-metric')?.value || '';
const params = {};
if (runType) params.run_type = runType;
if (metric) params.metric = metric;
return params;
}
/**
* Zeigt oder versteckt den Ladezustand.
* @param {boolean} isLoading
*/
function showLoadingState(isLoading) {
const loader = document.querySelector('#loading-indicator');
if (loader) {
loader.style.display = isLoading ? 'block' : 'none';
}
}
/**
* Baut die DOM-Struktur für angezeigte Ergebnisse auf.
* @param {Array<Object>} results - Ergebnisse vom /results-Endpunkt
*/
function renderResults(results) {
const container = document.querySelector('#results-container');
if (!container) return;
container.innerHTML = '';
if (!results?.length) {
container.innerHTML = '<p>Keine Ergebnisse gefunden.</p>';
return;
}
results.forEach(run => {
const runElement = document.createElement('article');
runElement.className = 'result-item';
const header = document.createElement('h3');
header.textContent = `Run #${run.id} (${run.type})`;
const stats = document.createElement('p');
stats.textContent = `Parameter: ${JSON.stringify(run.parameters)} | Statistik: ${JSON.stringify(run.statistics)}`;
runElement.appendChild(header);
runElement.appendChild(stats);
const chart = document.createElement('div');
chart.className = 'result-chart';
chart.setAttribute('aria-label', 'Diagramm der Ergebnisse');
renderChart(chart, run.chartData);
runElement.appendChild(chart);
container.appendChild(runElement);
});
}
/**
* Simuliert das Rendering eines Diagramms. In der realen Anwendung würde hier ein Chart-Bibliothek genutzt.
* @param {HTMLElement} container
* @param {Object} chartData
*/
function renderChart(container, chartData) {
const chartPlaceholder = document.createElement('div');
chartPlaceholder.textContent = `Diagramm für ${chartData?.label ?? 'unbekannt'} (Datenpunkte: ${chartData?.points?.length ?? 0})`;
chartPlaceholder.className = 'chart-placeholder';
container.appendChild(chartPlaceholder);
}
/**
* Zeigt eine Fehlermeldung im UI an.
* @param {string} message
*/
function displayError(message) {
const errorBox = document.querySelector('#error-message');
if (errorBox) {
errorBox.textContent = message;
errorBox.style.display = 'block';
}
}
window.addEventListener('load', initApp);