Project Blocker Dashboard

Open Blockers by Priority

Open Blockers by Project

Blocker Board (Drag cards to update status)

OPEN

IN PROGRESS

RESOLVED

Log New Blocker

Master Blocker List

DescriptionProjectPriorityStatusAction

Total Open Blockers

${openBlockers.length}

Critical Blockers

${openBlockers.filter(b=>b.priority==='Critical').length}

Avg. Blocker Age

${avgAge.toFixed(1)} Days

Top Blocker Owner

${topOwner}

`; } const renderChart = (id, type, data, options) => { const ctx = document.getElementById(id)?.getContext('2d'); if(!ctx) return; if(charts[id]) charts[id].destroy(); charts[id] = new Chart(ctx, { type, data, options }); }; function renderCharts(openBlockers) { const byPriority = openBlockers.reduce((acc,b)=>{acc[b.priority]=(acc[b.priority]||0)+1; return acc;},{}); renderChart('blocker-priority-chart', 'doughnut', { labels: Object.keys(byPriority), datasets: [{ data: Object.values(byPriority), backgroundColor: ['#dc2626','#f97316','#facc15','#3b82f6'] }] }, {responsive:true, maintainAspectRatio:false}); const byProject = openBlockers.reduce((acc,b)=>{acc[b.project]=(acc[b.project]||0)+1; return acc;},{}); renderChart('blocker-project-chart', 'bar', { labels: Object.keys(byProject), datasets: [{ label: '# of Blockers', data: Object.values(byProject), backgroundColor: 'rgba(124, 58, 237, 0.7)'}] }, {responsive:true, maintainAspectRatio:false}); } function renderKanbanBoard(allBlockers) { const columns = { Open: '', 'In Progress': '', Resolved: '' }; allBlockers.forEach(b => { if(columns[b.status] !== undefined) { columns[b.status] += `

${b.desc}

${b.project} | Owner: ${b.owner}
`; } }); document.getElementById('kanban-open').innerHTML = columns['Open']; document.getElementById('kanban-in-progress').innerHTML = columns['In Progress']; document.getElementById('kanban-resolved').innerHTML = columns['Resolved']; } function addBlocker() { blockers.push({ id: Date.now(), desc: document.getElementById('add-desc').value, project: document.getElementById('add-proj').value, owner: 'Unassigned', priority: document.getElementById('add-priority').value, status: 'Open', date: new Date().toISOString().split('T')[0] }); render(); } function blockerDownloadPDF() { html2canvas(document.getElementById('blocker-pdf-content'), {scale: 2}).then(canvas => { const pdf = new jspdf.jsPDF({orientation: 'landscape', unit: 'pt', format: 'a4'}); pdf.addImage(canvas.toDataURL('image/png'), 'PNG', 40, 40, pdf.internal.pageSize.getWidth() - 80, 0); pdf.save('Project_Blocker_Dashboard.pdf'); }); } initialize(); });
Scroll to Top