Overall Equipment Effectiveness (OEE) Dashboard

Overall Equipment Effectiveness (OEE)

Analyze production efficiency through Availability, Performance, and Quality.

Overall Performance

OEE Trend Over Time

Downtime Analysis (Minutes)

Daily Performance Log

Date Availability Performance Quality OEE

Enter Daily Production Data

No data available.

`; return; } const metrics = state.logs.map(log => calculateOEE(log)); const avgAvailability = metrics.reduce((sum, m) => sum + m.availability, 0) / totalLogs; const avgPerformance = metrics.reduce((sum, m) => sum + m.performance, 0) / totalLogs; const avgQuality = metrics.reduce((sum, m) => sum + m.quality, 0) / totalLogs; const avgOEE = metrics.reduce((sum, m) => sum + m.oee, 0) / totalLogs; kpiContainer.innerHTML = ` ${createGauge('Overall OEE', avgOEE, 'stroke-emerald-500')} ${createGauge('Availability', avgAvailability, 'stroke-blue-500')} ${createGauge('Performance', avgPerformance, 'stroke-purple-500')} ${createGauge('Quality', avgQuality, 'stroke-yellow-500')} `; }; const renderDataTable = () => { dataTableBody.innerHTML = ''; const sortedLogs = [...state.logs].sort((a, b) => new Date(b.date) - new Date(a.date)); sortedLogs.forEach(log => { const { availability, performance, quality, oee } = calculateOEE(log); const row = ` ${log.date} ${(availability * 100).toFixed(1)}% ${(performance * 100).toFixed(1)}% ${(quality * 100).toFixed(1)}% ${(oee * 100).toFixed(1)}% `; dataTableBody.innerHTML += row; }); }; const renderCharts = () => { const sortedLogs = [...state.logs].sort((a, b) => new Date(a.date) - new Date(b.date)); const labels = sortedLogs.map(log => log.date); const oeeData = sortedLogs.map(log => calculateOEE(log).oee * 100); if (oeeTrendChart) oeeTrendChart.destroy(); oeeTrendChart = new Chart(oeeTrendCanvas.getContext('2d'), { type: 'line', data: { labels: labels, datasets: [{ label: 'OEE (%)', data: oeeData, borderColor: '#059669', backgroundColor: 'rgba(5, 150, 105, 0.1)', fill: true, tension: 0.1 }] }, options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { display: false } }, scales: { x: { type: 'time', time: { unit: 'day' } }, y: { beginAtZero: false, max: 100, title: { display: true, text: 'OEE (%)' } } } } }); // Mock downtime reasons for chart const downtimeByReason = { "Mechanical": 100, "Electrical": 45, "Operator Error": 30, "Material Shortage": 60 }; if (downtimeChart) downtimeChart.destroy(); downtimeChart = new Chart(downtimeCanvas.getContext('2d'), { type: 'pie', data: { labels: Object.keys(downtimeByReason), datasets: [{ data: Object.values(downtimeByReason), backgroundColor: ['#ef4444', '#f97316', '#eab308', '#84cc16'] }] }, options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { position: 'top' } } } }); }; const renderConfigRows = () => { configRowsContainer.innerHTML = ''; const sortedLogs = [...state.logs].sort((a, b) => new Date(b.date) - new Date(a.date)); sortedLogs.forEach(log => { configRowsContainer.innerHTML += `
`.replaceAll('class="config-input"', 'class="config-input w-full border-gray-300 rounded-md shadow-sm"'); }); addConfigEventListeners(); }; // --- EVENT HANDLERS --- const handleConfigChange = (e) => { const id = parseInt(e.target.dataset.id); const field = e.target.dataset.field; const value = (e.target.type === 'number') ? parseFloat(e.target.value) || 0 : e.target.value; const log = state.logs.find(l => l.id === id); if (log) log[field] = value; renderAll(); }; const handleAddLog = () => { const newId = state.logs.length > 0 ? Math.max(...state.logs.map(l => l.id)) + 1 : 1; const today = new Date().toISOString().split('T')[0]; state.logs.push({ id: newId, date: today, plannedTime: 480, downtime: 0, idealCycle: 30, totalUnits: 0, defectiveUnits: 0 }); renderAll(); }; const handleRemoveLog = (e) => { const id = parseInt(e.target.dataset.id); state.logs = state.logs.filter(l => l.id !== id); renderAll(); }; const addConfigEventListeners = () => { document.querySelectorAll('.config-input').forEach(input => input.addEventListener('change', handleConfigChange)); document.querySelectorAll('.remove-btn').forEach(button => button.addEventListener('click', handleRemoveLog)); }; 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('OEE-Dashboard.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 (kpiContainer && addLogBtn && downloadPdfBtn) { addLogBtn.addEventListener('click', handleAddLog); downloadPdfBtn.addEventListener('click', handleDownloadPdf); renderAll(); updateTabButtons(); } else { console.error("Essential dashboard elements could not be found."); } });
Scroll to Top