Cohort Analysis Dashboard

Report Configuration

Cohort Data Entry

Enter your cohort data below. Each row is a cohort (e.g., users acquired in a month). "Initial Size" is the total number of users in that cohort. Subsequent columns are the number of those users who remained active in that period.

Key Metrics

Retention Heatmap

${totalUsers.toLocaleString()}

Avg. Period 1 Retention

${avgRetentionP1.toFixed(1)}%

Best Performing Cohort (P1)

${bestCohort.name || 'N/A'}

`; } renderCohortHeatmap(processedData) { let table = ``; this.state.periods.forEach(p => table += ``); table += ``; processedData.forEach(cohort => { table += ``; cohort.retentionRates.forEach((rate, i) => { if (cohort.retained[i] === 0 && i > 0 && cohort.retained[i-1] === 0) { table += ``; } else { const color = this.getColorForPercentage(rate); table += ``; } }); table += ``; }); table += `
CohortInitial Size${p}
${cohort.name}${cohort.initialSize.toLocaleString()}-
${rate.toFixed(1)}% (${cohort.retained[i].toLocaleString()})
`; this.dom.cohortTableContainer.innerHTML = table; } getColorForPercentage(pct) { if (pct === 0) return '#ffffff'; // HSL: Hue=140 (green), Saturation=60%, Lightness varies from 90% (low) to 40% (high) const lightness = 90 - (pct * 0.5); // Maps 0-100 to 90-40 return `hsl(140, 60%, ${lightness}%)`; } // --- PDF & Navigation --- openTab(event, tabName) { this.state.activeTab = tabName; this.updateUI(); } navigateTabs(dir) { const i = this.TABS_ORDER.indexOf(this.state.activeTab); let n = i; if (dir === 'next' && i < this.TABS_ORDER.length - 1) n++; if (dir === 'prev' && i > 0) n--; this.openTab(null, this.TABS_ORDER[n]); } async generatePdf() { if(this.state.activeTab !== 'dashboard') { this.openTab(null, 'dashboard'); await new Promise(res => setTimeout(res, 50)); } this.dom.downloadPdfBtn.disabled = true; this.dom.downloadPdfBtn.textContent = 'Generating...'; this.dom.container.classList.add('pdf-export-mode'); try { const { jsPDF } = window.jspdf; const canvas = await html2canvas(this.dom.pdfOutput, { scale: 2, useCORS: true, backgroundColor: '#ffffff' }); const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF({ orientation: 'landscape', unit: 'pt', format: 'a4' }); const margin = 40; const pdfWidth = pdf.internal.pageSize.getWidth(); const imgWidth = pdfWidth - margin * 2; const imgHeight = canvas.height * imgWidth / canvas.width; pdf.addImage(imgData, 'PNG', margin, margin, imgWidth, imgHeight); pdf.save(`${this.state.reportTitle.replace(/\s+/g, '_')}.pdf`); } catch(e) { console.error(e); alert('Error generating PDF.'); } finally { this.dom.container.classList.remove('pdf-export-mode'); this.dom.downloadPdfBtn.disabled = false; this.dom.downloadPdfBtn.textContent = 'Download Dashboard as PDF'; } } } const app = new CohortAnalysisDashboard();
Scroll to Top