Smart Task Load Balancer
Team Members
Note: This tool assumes equal capacity for all members for V1.
Tasks
Input team members and tasks on the first tab, then click "Balance Task Load".
Load Standard Deviation: ${standardDeviation.toFixed(2)} (Lower is more balanced)
`; html += ``;
memberLoads.forEach(member => {
html += `
`;
});
html += `
`;
// Simple Bar Chart
html += `${member.name} (Total Effort: ${member.totalEffort.toFixed(1)})
`; if (member.tasks.length > 0) { html += `- `;
member.tasks.forEach(task => {
html += `
- ${task.name} (Effort: ${task.effort}) `; }); html += `
No tasks assigned.
`; } html += `Load Distribution Chart:
`; const maxLoadVal = Math.max(...memberLoads.map(ml => ml.totalEffort), 0); // Ensure maxLoadVal is not 0 to avoid division by zero if all loads are 0 const chartScaleFactor = maxLoadVal > 0 ? (100 / maxLoadVal) : 0; // Percentage for max bar width memberLoads.forEach(member => { const barWidth = member.totalEffort * chartScaleFactor; const isMax = member.totalEffort === maxLoadVal && maxLoadVal > 0; html += `${member.name}
${member.totalEffort.toFixed(1)}
Task Load Balancing Report
`; pdfHTML += `Team Members (${stlbMembers.length})
- `;
stlbMembers.forEach(m => pdfHTML += `
- ${m.name} `); pdfHTML += `
Input Tasks (${stlbTasks.length})
`; if(stlbTasks.length > 0){ pdfHTML += `| Task Name | Estimated Effort |
|---|---|
| ${task.name} | ${task.effort} |
No tasks were input.
` } // Get structured content from the display to ensure PDF matches what user sees // Clone the report display, remove the chart for simpler PDF rendering if it's too complex, or try to include const reportClone = reportDisplayElement.cloneNode(true); // The chart might render if its simple divs, html2pdf will try // Let's keep the chart for now and see. pdfHTML += reportClone.innerHTML; const pdfContainer = document.getElementById('stlb-report-content-for-pdf'); if(!pdfContainer) return; pdfContainer.innerHTML = pdfHTML; // Apply critical styles from CSS variables if html2pdf doesn't pick them up perfectly pdfContainer.querySelectorAll('.stlb-chart-bar').forEach(bar => { if(bar.classList.contains('max-load')) { bar.style.backgroundColor = getComputedStyle(document.documentElement).getPropertyValue('--primary-color'); } else { bar.style.backgroundColor = getComputedStyle(document.documentElement).getPropertyValue('--accent-color'); } bar.style.color = 'white'; // Ensure text on bar is visible }); const opt = { margin: [0.6, 0.5, 0.6, 0.5], filename: 'Task_Load_Balance_Report.pdf', image: { type: 'jpeg', quality: 0.98 }, html2canvas: { scale: 2, useCORS: true, logging: false, scrollX: 0, scrollY: 0, windowWidth: pdfContainer.scrollWidth + 50 }, // Add some width for PDF rendering jsPDF: { unit: 'in', format: 'letter', orientation: 'portrait' }, pagebreak: { mode: ['avoid-all', 'css', 'legacy'] } }; html2pdf().from(pdfContainer).set(opt).save().then(() => { pdfContainer.innerHTML = ''; }).catch(err => { console.error("Error generating PDF:", err); pdfContainer.innerHTML = ''; alert("An error occurred while generating the PDF. Check console for details."); }); }