Network Downtime Analysis Dashboard

Network Downtime Analysis

Analyze incident frequency, duration, and root causes.

Overall Performance

Total Downtime by Root Cause (Minutes)

Incident Frequency by Root Cause

Incident Log

Date Root Cause Duration (Minutes)

Enter Downtime Incidents

${totalIncidents}

Total Downtime

${formatMinutes(totalDowntime)}

MTTR

${formatMinutes(Math.round(mttr))}

Uptime (30d)

${uptimePercentage.toFixed(3)}%

`; }; const renderDataTable = () => { dataTableBody.innerHTML = ''; // Sort by most recent date const sortedIncidents = [...state.incidents].sort((a, b) => new Date(b.date) - new Date(a.date)); sortedIncidents.forEach(inc => { const row = ` ${inc.date} ${inc.cause} ${inc.duration} `; dataTableBody.innerHTML += row; }); }; const renderCharts = () => { const aggregatedData = getAggregatedData(); const labels = aggregatedData.map(d => d.cause); const durationData = aggregatedData.map(d => d.totalDuration); const frequencyData = aggregatedData.map(d => d.count); const chartColors = ['#2563eb', '#f97316', '#16a34a', '#dc2626', '#9333ea']; // Duration Bar Chart if (durationChart) durationChart.destroy(); durationChart = new Chart(durationCanvas.getContext('2d'), { type: 'bar', data: { labels: labels, datasets: [{ label: 'Total Downtime (Minutes)', data: durationData, backgroundColor: 'rgba(37, 99, 235, 0.7)', borderColor: 'rgba(37, 99, 235, 1)', borderWidth: 1 }] }, options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { display: false } } } }); // Frequency Pie Chart if (frequencyChart) frequencyChart.destroy(); frequencyChart = new Chart(frequencyCanvas.getContext('2d'), { type: 'pie', data: { labels: labels, datasets: [{ data: frequencyData, backgroundColor: chartColors, }] }, options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { position: 'top' } } } }); }; const renderConfigRows = () => { configRowsContainer.innerHTML = ''; state.incidents.forEach(inc => { const row = `
`; configRowsContainer.innerHTML += row; }); addConfigEventListeners(); }; // --- EVENT HANDLERS --- const handleConfigChange = (e) => { const id = parseInt(e.target.dataset.id); const field = e.target.dataset.field; const value = field === 'duration' ? parseInt(e.target.value, 10) || 0 : e.target.value; const incident = state.incidents.find(inc => inc.id === id); if (incident) { incident[field] = value; } renderAll(); }; const handleAddIncident = () => { const newId = state.incidents.length > 0 ? Math.max(...state.incidents.map(inc => inc.id)) + 1 : 1; const today = new Date().toISOString().split('T')[0]; state.incidents.push({ id: newId, date: today, cause: "New Incident", duration: 0 }); renderAll(); }; const handleRemoveIncident = (e) => { const id = parseInt(e.target.dataset.id); state.incidents = state.incidents.filter(inc => inc.id !== id); renderAll(); }; const addConfigEventListeners = () => { document.querySelectorAll('.config-input').forEach(input => input.addEventListener('change', handleConfigChange)); document.querySelectorAll('.remove-incident-btn').forEach(button => button.addEventListener('click', handleRemoveIncident)); }; const handleDownloadPdf = () => { const { jsPDF } = window.jspdf; const pdfContent = document.getElementById('pdf-content'); document.querySelectorAll('.no-print').forEach(el => el.style.visibility = 'hidden'); Chart.defaults.animation = false; html2canvas(pdfContent, { scale: 2, useCORS: true, backgroundColor: '#ffffff' }).then(canvas => { document.querySelectorAll('.no-print').forEach(el => el.style.visibility = 'visible'); Chart.defaults.animation = true; const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF({ orientation: 'p', unit: 'mm', format: 'a4' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const imgWidth = pdfWidth - 20; const imgHeight = canvas.height * imgWidth / canvas.width; pdf.addImage(imgData, 'PNG', 10, 10, imgWidth, imgHeight); pdf.save('Network-Downtime-Analysis.pdf'); }); }; // --- TABBING LOGIC --- let currentTabIndex = 0; const updateTabButtons = () => { prevTabBtn.disabled = currentTabIndex === 0; nextTabBtn.disabled = currentTabIndex === tabContents.length - 1; }; const switchTab = (index) => { tabButtons.forEach(btn => btn.classList.remove('active')); tabContents.forEach(content => content.classList.remove('active')); tabButtons[index].classList.add('active'); tabContents[index].classList.add('active'); currentTabIndex = index; updateTabButtons(); }; tabButtons.forEach((button, index) => button.addEventListener('click', () => switchTab(index))); prevTabBtn.addEventListener('click', () => { if (currentTabIndex > 0) switchTab(currentTabIndex - 1); }); nextTabBtn.addEventListener('click', () => { if (currentTabIndex < tabContents.length - 1) switchTab(currentTabIndex + 1); }); // --- INITIALIZATION --- if (kpiCardsContainer && addIncidentBtn && downloadPdfBtn) { addIncidentBtn.addEventListener('click', handleAddIncident); downloadPdfBtn.addEventListener('click', handleDownloadPdf); renderAll(); updateTabButtons(); } else { console.error("Essential dashboard elements could not be found."); } });
Scroll to Top