timekeeping_analysis/trace_visualization/js/app.js

106 lines
No EOL
2.8 KiB
JavaScript

(() => {
'use strict';
const state = {
filter: 'all',
chart: null,
data: null
};
async function fetchAnalysisData(filter = 'all') {
try {
const url = filter && filter !== 'all' ? `/api/get-analysis?filter=${encodeURIComponent(filter)}` : '/api/get-analysis';
const response = await fetch(url);
if (!response.ok) throw new Error(`API Error: ${response.status}`);
const data = await response.json();
return data;
} catch (err) {
console.error('Datenabruf fehlgeschlagen:', err);
return null;
}
}
function renderCharts(data) {
const ctx = document.getElementById('analysisChart');
if (!ctx) {
console.warn('Canvas-Element für Diagramme nicht gefunden.');
return;
}
const datasets = data.runs.map(run => ({
label: `${run.type}`,
data: [run.median_shift, run.variance, run.migrated_ratio, run.offset_constant],
backgroundColor: 'rgba(54,162,235,0.4)',
borderColor: 'rgba(54,162,235,1)',
borderWidth: 1
}));
const chartData = {
labels: ['Median Shift', 'Variance', 'Migrated Ratio', 'Offset Constant'],
datasets
};
if (state.chart) {
state.chart.destroy();
}
state.chart = new Chart(ctx, {
type: 'bar',
data: chartData,
options: {
responsive: true,
scales: {
y: { beginAtZero: true }
},
plugins: {
legend: { position: 'bottom' },
title: {
display: true,
text: 'WF_MIGRATED Zeitmessungsanalyse'
}
}
}
});
}
function updateSummaryPanel(data) {
const panel = document.getElementById('summaryPanel');
if (!panel) return;
const avgVariance = data.runs.length ? (data.runs.reduce((sum, r) => sum + r.variance, 0) / data.runs.length).toFixed(2) : 'N/A';
const avgMigrated = data.runs.length ? (data.runs.reduce((sum, r) => sum + r.migrated_ratio, 0) / data.runs.length * 100).toFixed(1) + '%' : 'N/A';
panel.innerHTML = `
<h3>Statistik</h3>
<p>Durchschnittliche Varianz: ${avgVariance}</p>
<p>Durchschnittlicher WF_MIGRATED-Anteil: ${avgMigrated}</p>
<p>Datensätze: ${data.runs.length}</p>
`;
}
async function refreshData() {
const data = await fetchAnalysisData(state.filter);
if (!data) return;
state.data = data;
renderCharts(data);
updateSummaryPanel(data);
}
function registerEventHandlers() {
const filterSelect = document.getElementById('filterSelect');
if (filterSelect) {
filterSelect.addEventListener('change', async (e) => {
state.filter = e.target.value;
await refreshData();
});
}
}
async function initApp() {
registerEventHandlers();
await refreshData();
}
window.addEventListener('load', initApp);
})();