End Funded Status
${(endFundedStatus * 100).toFixed(1)}%
End Surplus/(Deficit)
$${(endSurplus / 1_000_000).toFixed(1)}M
`;
const tableRows = forecastData.map(d => `
| ${d.year} | $${(d.assets/1_000_000).toFixed(1)}M | $${(d.liabilities/1_000_000).toFixed(1)}M | ${(d.fundedStatus*100).toFixed(1)}% |
`).join('');
document.getElementById('forecast-table-container').innerHTML = `
| Year | Assets | Liabilities | Status |
${tableRows}
`;
const ctx = document.getElementById('forecast-chart').getContext('2d');
if (charts.forecast) charts.forecast.destroy();
charts.forecast = new Chart(ctx, { type: 'line', data: {
labels: forecastData.map(d => `Year ${d.year}`),
datasets: [
{ label: 'Assets', data: forecastData.map(d => d.assets), borderColor: '#059669', tension: 0.1 },
{ label: 'Liabilities', data: forecastData.map(d => d.liabilities), borderColor: '#dc2626', tension: 0.1 }
]
}, options: { responsive: true, maintainAspectRatio: false, scales: { y: { ticks: { callback: v => `$${(v/1_000_000)}M` } } } } });
}
// --- PDF GENERATION ---
async function generatePdfReport() {
downloadPdfBtn.disabled = true;
downloadPdfBtn.textContent = 'Generating...';
const tableRows = analysisResults.forecastData.map(d => `
| ${d.year} | $${(d.assets/1_000_000).toFixed(1)}M | $${(d.liabilities/1_000_000).toFixed(1)}M | ${(d.fundedStatus*100).toFixed(1)}% | $${(d.surplus/1_000_000).toFixed(1)}M |
`).join('');
const reportHtml = `
Strategic Asset Allocation Plan
Prepared for: ${fundData.name}
Report Date: ${new Date().toLocaleDateString()}
PROJECTED ENDING SURPLUS
$${(analysisResults.endSurplus / 1_000_000).toFixed(1)}M
PROJECTED FUNDED STATUS
${(analysisResults.endFundedStatus * 100).toFixed(1)}%
EXPECTED PORTFOLIO RETURN
${(analysisResults.blendedReturn * 100).toFixed(2)}%
Strategic Asset Allocation
AUM vs. Liabilities Projection
Year-by-Year Forecast Data
| Year | Assets | Liabilities | Funded Status | Surplus/(Deficit) |
${tableRows}
`;
const pdfTemplate = document.getElementById('pdf-template');
pdfTemplate.innerHTML = reportHtml;
pdfTemplate.classList.remove('invisible');
new Chart(document.getElementById('pdf-allocation-chart'), { type: 'pie', data: charts.allocation.data, options: { animation: { duration: 0 }, maintainAspectRatio: false } });
new Chart(document.getElementById('pdf-forecast-chart'), { type: 'line', data: charts.forecast.data, options: { animation: { duration: 0 }, maintainAspectRatio: false } });
setTimeout(async () => {
try {
const { jsPDF } = window.jspdf;
const pdf = new jsPDF({ orientation: 'p', unit: 'pt', format: 'a4' });
const pages = pdfTemplate.querySelectorAll('.pdf-page');
for (let i = 0; i < pages.length; i++) {
const canvas = await html2canvas(pages[i], { scale: 2 });
if (i > 0) pdf.addPage();
const imgData = canvas.toDataURL('image/png');
const pdfWidth = pdf.internal.pageSize.getWidth(), pdfHeight = (canvas.height * pdfWidth) / canvas.width;
pdf.addImage(imgData, 'PNG', 0, 0, pdfWidth, pdfHeight);
}
pdf.save(`Pension_Allocation_Plan_${fundData.name.replace(/\s+/g, '_')}.pdf`);
} catch (e) { console.error('PDF Generation Error:', e); } finally {
downloadPdfBtn.disabled = false;
downloadPdfBtn.textContent = 'Download Allocation Plan';
pdfTemplate.classList.add('invisible');
pdfTemplate.innerHTML = '';
}
}, 500);
}
// --- EVENT LISTENERS ---
downloadPdfBtn.addEventListener('click', generatePdfReport);
// --- INITIALIZATION ---
switchTab(0);
renderAllocationUI();
});