Executive Summary
Projected Future Value${formatCurrency(finalYear.value)}
Total Contributions${formatCurrency(results.totalContributions)}
Total Dividends Earned${formatCurrency(results.totalDividends)}
Final Share Count${formatNumber(finalYear.shares)}
Growth Chart
Annual Breakdown
| Year |
Total Shares |
Cumulative Dividends |
Share Price |
Year-End Value |
${tableRows}
`;
// Add chart image to the report container for PDF generation
if (growthChartInstance) {
const chartImg = document.getElementById('pdf-chart-image');
if(chartImg) {
chartImg.src = growthChartInstance.toBase64Image();
}
}
};
const downloadPdf = async () => {
if (!window.jspdf || !window.html2canvas) {
pdfMessage.textContent = 'Error: PDF libraries not loaded.';
return;
}
downloadPdfBtn.disabled = true;
loader.classList.remove('hidden');
pdfMessage.textContent = 'Generating PDF report, please wait...';
try {
const { jsPDF } = window.jspdf;
const canvas = await html2canvas(pdfReportContainer, { scale: 2, useCORS: true, logging: false });
const imgData = canvas.toDataURL('image/png');
const pdf = new jsPDF({ orientation: 'portrait', unit: 'mm', format: 'a4' });
const pdfWidth = pdf.internal.pageSize.getWidth();
const pdfHeight = pdf.internal.pageSize.getHeight();
const imgProps = pdf.getImageProperties(imgData);
const imgRatio = imgProps.height / imgProps.width;
const imgHeight = pdfWidth * imgRatio;
let heightLeft = imgHeight;
let position = 0;
pdf.addImage(imgData, 'PNG', 0, position, pdfWidth, imgHeight);
heightLeft -= pdfHeight;
while (heightLeft > 0) {
position -= pdfHeight;
pdf.addPage();
pdf.addImage(imgData, 'PNG', 0, position, pdfWidth, imgHeight);
heightLeft -= pdfHeight;
}
pdf.save('DRIP-investment-report.pdf');
pdfMessage.textContent = 'PDF downloaded successfully!';
} catch (error) {
console.error("PDF Generation Error:", error);
pdfMessage.textContent = 'An error occurred while generating the PDF.';
} finally {
loader.classList.add('hidden');
downloadPdfBtn.disabled = false;
setTimeout(() => { pdfMessage.textContent = ''; }, 5000);
}
};
// --- Event Listeners ---
if (calculateBtn) {
calculateBtn.addEventListener('click', () => {
const results = runSimulation();
if(results){
displayResults(results);
}
});
}
if (downloadPdfBtn) {
downloadPdfBtn.addEventListener('click', downloadPdf);
}
});