Add results_visualization/js/visualization.js
This commit is contained in:
parent
4a562fc18c
commit
f0db07d35a
1 changed files with 121 additions and 0 deletions
121
results_visualization/js/visualization.js
Normal file
121
results_visualization/js/visualization.js
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
"use strict";
|
||||
|
||||
/**
|
||||
* @module visualization
|
||||
* @description Verarbeitung und Darstellung aggregierter Zeitmessungsdaten.
|
||||
* Verantwortlich für Rendering und Update von Charts und Summary Cards.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Rendert interaktive Diagramme auf Basis der geladenen Daten.
|
||||
* @param {Array<Object>} data - Aggregierte Ergebnisse von der /results API.
|
||||
* @param {HTMLElement} container - Container-Element zur Anzeige des Diagramms.
|
||||
* @returns {void}
|
||||
*/
|
||||
export function renderCharts(data, container) {
|
||||
if (!Array.isArray(data) || !container) return;
|
||||
|
||||
container.innerHTML = "";
|
||||
|
||||
const canvas = document.createElement("canvas");
|
||||
canvas.id = "chart-results";
|
||||
canvas.setAttribute("aria-label", "Zeitmessungsdiagramm");
|
||||
canvas.setAttribute("role", "img");
|
||||
container.appendChild(canvas);
|
||||
|
||||
const ctx = canvas.getContext("2d");
|
||||
|
||||
const runTypes = [...new Set(data.map(d => d.run_type))];
|
||||
const labels = data.map(d => d.run_id);
|
||||
|
||||
const datasets = runTypes.map((type) => {
|
||||
const subset = data.filter(d => d.run_type === type);
|
||||
return {
|
||||
label: type,
|
||||
data: subset.map(r => r.metrics?.latency_mean ?? 0),
|
||||
borderColor: type === "pinned" ? "#2a9d8f" : "#e76f51",
|
||||
backgroundColor: type === "pinned" ? "rgba(42,157,143,0.4)" : "rgba(231,111,81,0.4)",
|
||||
borderWidth: 2,
|
||||
tension: 0.3,
|
||||
};
|
||||
});
|
||||
|
||||
if (window.currentChart) {
|
||||
window.currentChart.destroy();
|
||||
}
|
||||
|
||||
window.currentChart = new Chart(ctx, {
|
||||
type: "line",
|
||||
data: { labels, datasets },
|
||||
options: {
|
||||
responsive: true,
|
||||
interaction: { mode: "index", intersect: false },
|
||||
scales: {
|
||||
x: { title: { display: true, text: "Run ID" } },
|
||||
y: { title: { display: true, text: "Latenz (ms)" }, beginAtZero: true }
|
||||
},
|
||||
plugins: {
|
||||
legend: { position: "top" },
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: ctx => `${ctx.dataset.label}: ${ctx.parsed.y.toFixed(2)} ms`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
renderSummary(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Aktualisiert Diagramme und Statistiken basierend auf Filtern.
|
||||
* @param {Object} filters - Nutzerdefinierte Filterparameter.
|
||||
* @param {Array<Object>} data - Aktuelle Ergebnisdaten.
|
||||
* @returns {void}
|
||||
*/
|
||||
export function updateVisualization(filters, data) {
|
||||
if (typeof filters !== "object" || !Array.isArray(data)) return;
|
||||
|
||||
const filteredData = data.filter(item => {
|
||||
const matchRunType = !filters.runType || item.run_type === filters.runType;
|
||||
const matchMetric = !filters.metric || Object.keys(item.metrics || {}).includes(filters.metric);
|
||||
return matchRunType && matchMetric;
|
||||
});
|
||||
|
||||
const container = document.querySelector("#chart-container");
|
||||
renderCharts(filteredData, container);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rendert aggregierte Kennzahlen als Summary Cards unterhalb des Diagramms.
|
||||
* @param {Array<Object>} data
|
||||
*/
|
||||
function renderSummary(data) {
|
||||
const summaryContainer = document.querySelector("#summary-container");
|
||||
if (!summaryContainer) return;
|
||||
|
||||
const total = data.length;
|
||||
const avgLatency = (data.reduce((acc, val) => acc + (val.metrics?.latency_mean ?? 0), 0) / Math.max(total, 1)).toFixed(2);
|
||||
const avgVariance = (data.reduce((acc, val) => acc + (val.metrics?.variance ?? 0), 0) / Math.max(total, 1)).toFixed(3);
|
||||
const avgStability = (data.reduce((acc, val) => acc + (val.metrics?.stability_index ?? 0), 0) / Math.max(total, 1)).toFixed(3);
|
||||
|
||||
summaryContainer.innerHTML = `
|
||||
<div class="summary-card">
|
||||
<h3>Runs insgesamt</h3>
|
||||
<p>${total}</p>
|
||||
</div>
|
||||
<div class="summary-card">
|
||||
<h3>Ø Latenz</h3>
|
||||
<p>${avgLatency} ms</p>
|
||||
</div>
|
||||
<div class="summary-card">
|
||||
<h3>Ø Varianz</h3>
|
||||
<p>${avgVariance}</p>
|
||||
</div>
|
||||
<div class="summary-card">
|
||||
<h3>Ø Stabilität</h3>
|
||||
<p>${avgStability}</p>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
Loading…
Reference in a new issue