Overall Conversion Rate
${overallConversionRateElem.textContent}
Avg. Time to Convert (Days)
${avgTimeToConvertElem.textContent}
Total Revenue Impact ($)
${totalRevenueImpactElem.textContent}
`;
pdfContentWrapper.appendChild(summarySection);
// Add distribution charts
const chartsSection = document.createElement('div');
chartsSection.classList.add('grid', 'grid-cols-2', 'gap-6', 'mb-6');
chartsSection.innerHTML = `
Average Time in Stage (Days)
Journey Status Distribution
`;
pdfContentWrapper.appendChild(chartsSection);
// Populate PDF charts (re-use logic but target PDF elements)
const totalJourneys = customerJourneyRecords.length;
const stageOrder = ["Awareness", "Consideration", "Decision", "Purchase", "Retention", "Advocacy"];
// Conversion Rate by Stage for PDF
const stageConversionCountsPdf = {};
const stageTotalCountsPdf = {};
stageOrder.forEach(stage => { stageConversionCountsPdf[stage] = 0; stageTotalCountsPdf[stage] = 0; });
customerJourneyRecords.forEach(record => {
stageTotalCountsPdf[record.currentStage] = (stageTotalCountsPdf[record.currentStage] || 0) + 1;
if (record.conversionStatus === 'Converted') {
stageConversionCountsPdf[record.currentStage] = (stageConversionCountsPdf[record.currentStage] || 0) + 1;
}
});
const conversionRatesByStagePdf = {};
stageOrder.forEach(stage => {
if (stageTotalCountsPdf[stage] > 0) {
conversionRatesByStagePdf[stage] = (stageConversionCountsPdf[stage] / stageTotalCountsPdf[stage]) * 100;
} else {
conversionRatesByStagePdf[stage] = 0;
}
});
renderBarChart(chartsSection.querySelector('#pdfConversionRateByStageChart'), conversionRatesByStagePdf, 'percentage');
// Average Time in Stage (Days) for PDF
const timeInStageSumsPdf = {};
const timeInStageCountsPdf = {};
stageOrder.forEach(stage => { timeInStageSumsPdf[stage] = 0; timeInStageCountsPdf[stage] = 0; });
customerJourneyRecords.forEach(record => {
const daysInStage = calculateDaysBetween(record.startDate, record.lastActivityDate);
timeInStageSumsPdf[record.currentStage] = (timeInStageSumsPdf[record.currentStage] || 0) + daysInStage;
timeInStageCountsPdf[record.currentStage] = (timeInStageCountsPdf[record.currentStage] || 0) + 1;
});
const avgTimeInStagePdf = {};
stageOrder.forEach(stage => {
if (timeInStageCountsPdf[stage] > 0) {
avgTimeInStagePdf[stage] = timeInStageSumsPdf[stage] / timeInStageCountsPdf[stage];
} else {
avgTimeInStagePdf[stage] = 0;
}
});
renderBarChart(chartsSection.querySelector('#pdfAvgTimeInStageChart'), avgTimeInStagePdf, 'days');
// Journey Status Distribution for PDF
const journeyStatusCountsPdf = customerJourneyRecords.reduce((acc, record) => { acc[record.conversionStatus] = (acc[record.conversionStatus] || 0) + 1; return acc; }, {});
renderBarChart(chartsSection.querySelector('#pdfJourneyStatusDistributionChart'), journeyStatusCountsPdf, 'status');
// Add detailed journey list table
const journeyListSection = document.createElement('div');
journeyListSection.innerHTML = `
Detailed Customer Journey Records
| ID |
Customer Name |
Journey Name |
Current Stage |
Start Date |
Last Activity |
Conversion Status |
Conversion Date |
Revenue Impact ($) |
${dashboardJourneyTableBody.innerHTML}
`;
pdfContentWrapper.appendChild(journeyListSection);
// Options for html2pdf
const options = {
margin: 10,
filename: 'Customer_Journey_Dashboard.pdf',
image: { type: 'jpeg', quality: 0.98 },
html2canvas: { scale: 2, logging: true, dpi: 192, letterRendering: true },
jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' },
pagebreak: { mode: ['avoid-all', 'css', 'legacy'] }
};
// Generate PDF from the temporary content wrapper
html2pdf().from(pdfContentWrapper).set(options).save();
// Clean up the temporary div (optional, as it's not appended to the DOM)
pdfContentWrapper.remove();
}
/**
* Loads initial sample data for the dashboard.
* Relevant to USA context.
*/
function loadSampleData() {
customerJourneyRecords = [
{ id: 'CJ001', customerName: 'Alice Smith', journeyName: 'Onboarding Flow', currentStage: 'Purchase', startDate: '2024-01-01', lastActivityDate: '2024-01-15', conversionStatus: 'Converted', conversionDate: '2024-01-15', revenueImpact: 250.00 },
{ id: 'CJ002', customerName: 'Bob Johnson', journeyName: 'Product Discovery', currentStage: 'Consideration', startDate: '2024-01-10', lastActivityDate: '2024-02-01', conversionStatus: 'In Progress', conversionDate: '', revenueImpact: 0 },
{ id: 'CJ003', customerName: 'Charlie Brown', journeyName: 'Subscription Renewal', currentStage: 'Retention', startDate: '2023-12-01', lastActivityDate: '2024-01-20', conversionStatus: 'Abandoned', conversionDate: '', revenueImpact: 0 },
{ id: 'CJ004', customerName: 'Diana Prince', journeyName: 'Onboarding Flow', currentStage: 'Advocacy', startDate: '2024-02-01', lastActivityDate: '2024-02-28', conversionStatus: 'Converted', conversionDate: '2024-02-20', revenueImpact: 100.00 },
{ id: 'CJ005', customerName: 'Ethan Hunt', journeyName: 'Product Discovery', currentStage: 'Awareness', startDate: '2024-03-01', lastActivityDate: '2024-03-05', conversionStatus: 'In Progress', conversionDate: '', revenueImpact: 0 },
{ id: 'CJ006', customerName: 'Fiona Green', journeyName: 'Purchase Funnel', currentStage: 'Decision', startDate: '2024-03-10', lastActivityDate: '2024-03-25', conversionStatus: 'Converted', conversionDate: '2024-03-25', revenueImpact: 500.00 }
];
}