129 lines
No EOL
3.7 KiB
JavaScript
129 lines
No EOL
3.7 KiB
JavaScript
/* eslint-disable no-undef */
|
|
/**
|
|
* @module ui
|
|
* Präsentationslogik für die Visualisierung der Analyse-Ergebnisse.
|
|
* Verantwortlich für DOM-Manipulationen basierend auf geladenen Daten.
|
|
*/
|
|
|
|
/**
|
|
* Rendert eine Übersicht der aggregierten Statistiken zu Runs im Hauptbereich.
|
|
* @param {Array<Object>} results - Teil der API-Response mit Statistiken.
|
|
*/
|
|
export function renderOverview(results = []) {
|
|
const container = document.getElementById('results-overview');
|
|
if (!container) return;
|
|
|
|
// Defensive: Cleanup und Fallback
|
|
container.innerHTML = '';
|
|
if (!Array.isArray(results) || results.length === 0) {
|
|
container.textContent = 'Keine Ergebnisse verfügbar.';
|
|
return;
|
|
}
|
|
|
|
// Aggregation - Beispielhafte Kennzahlen
|
|
const totalRuns = results.length;
|
|
const pinnedRuns = results.filter(r => r.type === 'pinned').length;
|
|
const unpinnedRuns = totalRuns - pinnedRuns;
|
|
|
|
const avgCorrelations = (results
|
|
.map(r => r?.statistics?.correlation ?? 0)
|
|
.reduce((a, b) => a + b, 0)) / totalRuns;
|
|
|
|
const overviewHTML = `
|
|
<section class="overview__stats" aria-label="Ergebnisübersicht">
|
|
<h2>Analyseübersicht</h2>
|
|
<ul class="overview__list">
|
|
<li>Gesamtanzahl Runs: <strong>${totalRuns}</strong></li>
|
|
<li>Pinned Runs: <strong>${pinnedRuns}</strong></li>
|
|
<li>Unpinned Runs: <strong>${unpinnedRuns}</strong></li>
|
|
<li>Ø Korrelation: <strong>${avgCorrelations.toFixed(3)}</strong></li>
|
|
</ul>
|
|
</section>
|
|
`;
|
|
|
|
container.innerHTML = overviewHTML;
|
|
}
|
|
|
|
/**
|
|
* Aktualisiert oder rendert Diagramme auf Basis der gegebenen API-Daten.
|
|
* Wird bei Initialisierung und Filter-Events aufgerufen.
|
|
* @param {Array<Object>} runData - Liste der Runs mit chartData-Feldern.
|
|
* @param {string} [filterType] - Optionaler Filter (pinned/unpinned)
|
|
*/
|
|
export function updateCharts(runData = [], filterType) {
|
|
const chartPanel = document.getElementById('chart-panel');
|
|
if (!chartPanel) return;
|
|
chartPanel.innerHTML = '';
|
|
|
|
// Optionales Filtern
|
|
const filteredData = filterType
|
|
? runData.filter(r => r.type === filterType)
|
|
: runData;
|
|
|
|
if (filteredData.length === 0) {
|
|
chartPanel.textContent = 'Keine Diagrammdaten verfügbar.';
|
|
return;
|
|
}
|
|
|
|
// Dynamisches Rendern pro Run
|
|
filteredData.forEach(run => {
|
|
const canvas = document.createElement('canvas');
|
|
canvas.setAttribute('aria-label', `Chart für Run ${run.id}`);
|
|
canvas.setAttribute('role', 'img');
|
|
chartPanel.appendChild(canvas);
|
|
|
|
const ctx = canvas.getContext('2d');
|
|
if (ctx && run.chartData && Chart) {
|
|
// Chart.js Standard-Konfiguration
|
|
new Chart(ctx, {
|
|
type: 'line',
|
|
data: {
|
|
labels: run.chartData.labels,
|
|
datasets: [{
|
|
label: `${run.type} Run ${run.id}`,
|
|
data: run.chartData.values,
|
|
borderColor: run.type === 'pinned' ? '#007ACC' : '#FF9900',
|
|
fill: false,
|
|
tension: 0.1
|
|
}]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
plugins: {
|
|
legend: {
|
|
display: true,
|
|
labels: {
|
|
color: '#333'
|
|
}
|
|
},
|
|
tooltip: {
|
|
mode: 'index',
|
|
intersect: false
|
|
}
|
|
},
|
|
interaction: {
|
|
mode: 'nearest',
|
|
axis: 'x',
|
|
intersect: false
|
|
},
|
|
scales: {
|
|
x: {
|
|
title: {
|
|
display: true,
|
|
text: 'Parameter Index'
|
|
}
|
|
},
|
|
y: {
|
|
title: {
|
|
display: true,
|
|
text: 'Wert'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
// Hinweis: Wird von app.initApp() und Filter-Events importiert und genutzt.
|