2025-06-04 10:03:22 +02:00

25 lines
7.5 KiB
JavaScript

window.statsCharts={};function getChartTheme(){const isDark=document.documentElement.classList.contains('dark');return{isDark:isDark,backgroundColor:isDark?'rgba(30, 41, 59, 0.8)':'rgba(255, 255, 255, 0.8)',textColor:isDark?'#e2e8f0':'#374151',gridColor:isDark?'rgba(148, 163, 184, 0.1)':'rgba(156, 163, 175, 0.2)',borderColor:isDark?'rgba(148, 163, 184, 0.3)':'rgba(156, 163, 175, 0.5)'};}
function getDefaultChartOptions(){const theme=getChartTheme();return{responsive:true,maintainAspectRatio:false,plugins:{legend:{labels:{color:theme.textColor,font:{family:'Inter, sans-serif'}}},tooltip:{backgroundColor:theme.backgroundColor,titleColor:theme.textColor,bodyColor:theme.textColor,borderColor:theme.borderColor,borderWidth:1}},scales:{x:{ticks:{color:theme.textColor,font:{family:'Inter, sans-serif'}},grid:{color:theme.gridColor}},y:{ticks:{color:theme.textColor,font:{family:'Inter, sans-serif'}},grid:{color:theme.gridColor}}}};}
async function createJobStatusChart(){try{const response=await fetch('/api/stats/charts/job-status');const data=await response.json();if(!response.ok){throw new Error(data.error||'Fehler beim Laden der Job-Status-Daten');}
const ctx=document.getElementById('job-status-chart');if(!ctx)return;if(window.statsCharts.jobStatus){window.statsCharts.jobStatus.destroy();}
const theme=getChartTheme();window.statsCharts.jobStatus=new Chart(ctx,{type:'doughnut',data:data,options:{responsive:true,maintainAspectRatio:false,plugins:{legend:{position:'bottom',labels:{color:theme.textColor,font:{family:'Inter, sans-serif',size:12},padding:15}},tooltip:{backgroundColor:theme.backgroundColor,titleColor:theme.textColor,bodyColor:theme.textColor,borderColor:theme.borderColor,borderWidth:1,callbacks:{label:function(context){const label=context.label||'';const value=context.parsed;const total=context.dataset.data.reduce((a,b)=>a+b,0);const percentage=total>0?Math.round((value/total)*100):0;return`${label}:${value}(${percentage}%)`;}}}},cutout:'60%'}});}catch(error){console.error('Fehler beim Erstellen des Job-Status-Charts:',error);showChartError('job-status-chart','Fehler beim Laden der Job-Status-Daten');}}
async function createPrinterUsageChart(){try{const response=await fetch('/api/stats/charts/printer-usage');const data=await response.json();if(!response.ok){throw new Error(data.error||'Fehler beim Laden der Drucker-Nutzung-Daten');}
const ctx=document.getElementById('printer-usage-chart');if(!ctx)return;if(window.statsCharts.printerUsage){window.statsCharts.printerUsage.destroy();}
const options=getDefaultChartOptions();options.scales.y.title={display:true,text:'Anzahl Jobs',color:getChartTheme().textColor,font:{family:'Inter, sans-serif'}};window.statsCharts.printerUsage=new Chart(ctx,{type:'bar',data:data,options:options});}catch(error){console.error('Fehler beim Erstellen des Drucker-Nutzung-Charts:',error);showChartError('printer-usage-chart','Fehler beim Laden der Drucker-Nutzung-Daten');}}
async function createJobsTimelineChart(){try{const response=await fetch('/api/stats/charts/jobs-timeline');const data=await response.json();if(!response.ok){throw new Error(data.error||'Fehler beim Laden der Jobs-Timeline-Daten');}
const ctx=document.getElementById('jobs-timeline-chart');if(!ctx)return;if(window.statsCharts.jobsTimeline){window.statsCharts.jobsTimeline.destroy();}
const options=getDefaultChartOptions();options.scales.y.title={display:true,text:'Jobs pro Tag',color:getChartTheme().textColor,font:{family:'Inter, sans-serif'}};options.scales.x.title={display:true,text:'Datum (letzte 30 Tage)',color:getChartTheme().textColor,font:{family:'Inter, sans-serif'}};window.statsCharts.jobsTimeline=new Chart(ctx,{type:'line',data:data,options:options});}catch(error){console.error('Fehler beim Erstellen des Jobs-Timeline-Charts:',error);showChartError('jobs-timeline-chart','Fehler beim Laden der Jobs-Timeline-Daten');}}
async function createUserActivityChart(){try{const response=await fetch('/api/stats/charts/user-activity');const data=await response.json();if(!response.ok){throw new Error(data.error||'Fehler beim Laden der Benutzer-Aktivität-Daten');}
const ctx=document.getElementById('user-activity-chart');if(!ctx)return;if(window.statsCharts.userActivity){window.statsCharts.userActivity.destroy();}
const options=getDefaultChartOptions();options.indexAxis='y';options.scales.x.title={display:true,text:'Anzahl Jobs',color:getChartTheme().textColor,font:{family:'Inter, sans-serif'}};options.scales.y.title={display:true,text:'Benutzer',color:getChartTheme().textColor,font:{family:'Inter, sans-serif'}};window.statsCharts.userActivity=new Chart(ctx,{type:'bar',data:data,options:options});}catch(error){console.error('Fehler beim Erstellen des Benutzer-Aktivität-Charts:',error);showChartError('user-activity-chart','Fehler beim Laden der Benutzer-Aktivität-Daten');}}
function showChartError(chartId,message){const container=document.getElementById(chartId);if(container){container.innerHTML=`<div class="flex items-center justify-center h-full"><div class="text-center"><svg class="h-12 w-12 mx-auto text-red-500 mb-4"fill="none"viewBox="0 0 24 24"stroke="currentColor"><path stroke-linecap="round"stroke-linejoin="round"stroke-width="2"d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.732-.833-2.5 0L4.268 16.5c-.77.833.192 2.5 1.732 2.5z"/></svg><p class="text-red-500 font-medium">${message}</p><button onclick="refreshAllCharts()"class="mt-2 text-sm text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300">Erneut versuchen</button></div></div>`;}}
async function initializeAllCharts(){showChartLoading();await Promise.allSettled([createJobStatusChart(),createPrinterUsageChart(),createJobsTimelineChart(),createUserActivityChart()]);}
function showChartLoading(){const chartIds=['job-status-chart','printer-usage-chart','jobs-timeline-chart','user-activity-chart'];chartIds.forEach(chartId=>{const container=document.getElementById(chartId);if(container){container.innerHTML=`<div class="flex items-center justify-center h-full"><div class="text-center"><div class="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600 mx-auto mb-2"></div><p class="text-slate-500 dark:text-slate-400 text-sm">Diagramm wird geladen...</p></div></div>`;}});}
async function refreshAllCharts(){console.log('Aktualisiere alle Diagramme...');Object.values(window.statsCharts).forEach(chart=>{if(chart&&typeof chart.destroy==='function'){chart.destroy();}});await initializeAllCharts();console.log('Alle Diagramme aktualisiert');}
function updateChartsTheme(){refreshAllCharts();}
let chartRefreshInterval;function startChartAutoRefresh(){if(chartRefreshInterval){clearInterval(chartRefreshInterval);}
chartRefreshInterval=setInterval(()=>{refreshAllCharts();},5*60*1000);}
function stopChartAutoRefresh(){if(chartRefreshInterval){clearInterval(chartRefreshInterval);chartRefreshInterval=null;}}
function cleanup(){stopChartAutoRefresh();Object.values(window.statsCharts).forEach(chart=>{if(chart&&typeof chart.destroy==='function'){chart.destroy();}});window.statsCharts={};}
window.refreshAllCharts=refreshAllCharts;window.updateChartsTheme=updateChartsTheme;window.startChartAutoRefresh=startChartAutoRefresh;window.stopChartAutoRefresh=stopChartAutoRefresh;window.cleanup=cleanup;document.addEventListener('DOMContentLoaded',function(){if(document.getElementById('job-status-chart')){initializeAllCharts();startChartAutoRefresh();}});if(typeof window.addEventListener!=='undefined'){window.addEventListener('darkModeChanged',function(e){updateChartsTheme();});}
window.addEventListener('beforeunload',cleanup);