Waste Reduction Tracker Generator

Waste Reduction Tracker Generator

EcoTrack

Waste Reduction Log Generator
Project Metadata & Goals
Waste Log Entries (Weight/Volume)

Enter output for each date/logging interval.

Date/Interval
Paper/Cardboard
Plastics/Metals
Organics/Compost
Remove

Period: ${period} | Unit: ${unit.toUpperCase()}

`; html += `

${totals.total.toFixed(1)} ${unit.toUpperCase()}

Total Waste Logged

${reductionPct.toFixed(1)}%

Reduction Progress (Goal: ${goal}%)

`; // 2. Breakdown Table html += `

Category Breakdown (${unit.toUpperCase()})

Category Total Output Percentage Notes
Paper/Cardboard${totals.paper.toFixed(1)}${(totals.paper / totals.total * 100).toFixed(1)}%Largest volume contributor.
Plastics/Metals${totals.plastic.toFixed(1)}${(totals.plastic / totals.total * 100).toFixed(1)}%Key target for immediate substitution.
Organics/Compost${totals.organic.toFixed(1)}${(totals.organic / totals.total * 100).toFixed(1)}%Best opportunity for diversion.
`; // 3. Detailed Log html += `

Detailed Log Entries

`; logData.forEach(item => { const rowTotal = (item.paper + item.plastic + item.organic).toFixed(1); html += ``; }); html += `
Date/Interval Paper Plastic Organic Total
${item.date} ${item.paper.toFixed(1)} ${item.plastic.toFixed(1)} ${item.organic.toFixed(1)} ${rowTotal}
`; container.innerHTML = html; } function wrtgSwitchTab(tabId) { document.querySelectorAll('.wrtg-tab-btn').forEach(b => b.classList.remove('active')); document.querySelectorAll('.wrtg-content').forEach(c => c.classList.remove('active')); const idx = tabId === 'setup' ? 0 : (tabId === 'log' ? 1 : 2); document.querySelectorAll('.wrtg-tab-btn')[idx].classList.add('active'); document.getElementById('wrtg-' + tabId).classList.add('active'); if (tabId === 'report') { wrtgRenderReport(); } } function wrtgLoadExample() { if(!confirm("Overwrite current data and load example office waste data?")) return; document.getElementById('inp-project').value = "HQ Cafeteria Waste Stream Analysis"; document.getElementById('inp-period').value = "May 2026 Baseline"; document.getElementById('inp-unit').value = "kg"; document.getElementById('inp-goal').value = "15"; // Clear and fill log entries document.getElementById('wrtg-log-rows-container').innerHTML = ''; wrtgAddLogRow("Week 1", 45, 15, 10); wrtgAddLogRow("Week 2", 40, 13, 9); wrtgAddLogRow("Week 3", 35, 11, 7); wrtgAddLogRow("Week 4", 32, 10, 6); // Showing successful reduction trend wrtgRenderReport(); wrtgSwitchTab('report'); } /* --- PDF Generation --- */ async function wrtgGeneratePDF() { wrtgRenderReport(); // Ensure report is updated const logData = wrtgGetLogData(); if (logData.length === 0) { alert("Please add log entries before generating the PDF."); return; } const { jsPDF } = window.jspdf; const doc = new jsPDF('p', 'mm', 'a4'); const unit = document.getElementById('inp-unit').value.toUpperCase(); const project = document.getElementById('inp-project').value || "Waste Audit Project"; const period = document.getElementById('inp-period').value || "Reporting Period"; const goal = parseFloat(document.getElementById('inp-goal').value) || 0; const totals = logData.reduce((acc, item) => ({ paper: acc.paper + item.paper, plastic: acc.plastic + item.plastic, organic: acc.organic + item.organic, total: acc.total + item.paper + item.plastic + item.organic }), { paper: 0, plastic: 0, organic: 0, total: 0 }); const reductionPct = ((logData[0].paper + logData[0].plastic + logData[0].organic - (logData[logData.length - 1].paper + logData[logData.length - 1].plastic + logData[logData.length - 1].organic)) / (logData[0].paper + logData[0].plastic + logData[0].organic)) * 100; const teal = [0, 150, 136]; let y = 20; // 1. Header doc.setFillColor(...teal); doc.rect(0, 0, 210, 20, 'F'); doc.setTextColor(255, 255, 255); doc.setFontSize(16); doc.text(`Waste Reduction Audit: ${project}`, 14, 13); // 2. Summary doc.setTextColor(0, 0, 0); doc.setFontSize(10); doc.text(`Period: ${period} | Unit: ${unit}`, 14, y + 10); y += 20; const summaryTable = [ ['Total Waste Logged', `${totals.total.toFixed(1)} ${unit}`, 'Reduction Goal', `${goal}%`], ['Achieved Reduction', `${reductionPct.toFixed(1)}%`, 'Plastic Total', `${totals.plastic.toFixed(1)} ${unit}`] ]; doc.autoTable({ startY: y, body: summaryTable, theme: 'grid', styles: { fontSize: 9 }, headStyles: { fillColor: [240, 240, 240], textColor: [0, 0, 0], fontStyle: 'bold' } }); y = doc.lastAutoTable.finalY + 10; // 3. Detailed Log doc.setFontSize(12); doc.setFont("helvetica", "bold"); doc.setTextColor(0, 150, 136); doc.text("Detailed Log Entries", 14, y); y += 5; const tableBody = logData.map(item => [ item.date, item.paper.toFixed(1), item.plastic.toFixed(1), item.organic.toFixed(1), (item.paper + item.plastic + item.organic).toFixed(1) ]); doc.autoTable({ startY: y, head: [['Date/Interval', 'Paper', 'Plastics', 'Organics', `Total (${unit})`]], body: tableBody, theme: 'grid', headStyles: { fillColor: teal, fontSize: 10 }, styles: { fontSize: 9 }, columnStyles: { 0: { cellWidth: 30, fontStyle: 'bold' }, 4: { cellWidth: 30, fontStyle: 'bold', halign: 'center' } } }); // 4. Recommendation Space y = doc.lastAutoTable.finalY + 15; if (y > 270) { doc.addPage(); y = 20; } doc.setFontSize(10); doc.setTextColor(50); doc.text("Recommendations / Next Steps (To be filled manually):", 14, y); doc.setDrawColor(200); doc.rect(14, y + 5, 180, 25, 'S'); doc.save(`WasteAudit_${project.replace(/\s/g, '_')}.pdf`); }
Scroll to Top