Initial Value: $${initialValue.toLocaleString()}
Stressed Value: $${stressedValue.toLocaleString()}
Value Change: $${totalValueChange.toLocaleString(undefined, {maximumFractionDigits:0})}
Portfolio Impact: ${(totalImpactPercentage*100).toFixed(1)}%
Detailed Impact Analysis
| Holding |
Initial Value |
Value Change |
Impact |
`;
stressTestResults.resultsByHolding.sort((a,b) => a.valueChange - b.valueChange).forEach(h => {
reportHTML += `
| ${h.name} (${h.sector}) |
$${h.investment.toLocaleString()} |
$${h.valueChange.toLocaleString(undefined, {maximumFractionDigits:0})} |
${(h.impactPercentage * 100).toFixed(1)}% |
`;
});
reportHTML += `
`;
reportingContent.innerHTML = reportHTML;
}
// --- PDF GENERATION ---
async function generatePdf() {
if (!stressTestResults) {
alert("Please run a stress test before downloading a report.");
return;
}
const { jsPDF } = window.jspdf;
const pdfContent = document.getElementById('pdf-content');
const pdfButton = document.getElementById('pdf-download-button');
pdfButton.style.visibility = 'hidden';
try {
const canvas = await html2canvas(pdfContent, { scale: 2, backgroundColor: '#ffffff' });
const imgData = canvas.toDataURL('image/png');
const pdf = new jsPDF({ orientation: 'p', unit: 'mm', format: 'a4' });
const pdfWidth = pdf.internal.pageSize.getWidth();
const pdfHeight = pdf.internal.pageSize.getHeight();
const imgProps= pdf.getImageProperties(imgData);
const imgHeight = (imgProps.height * pdfWidth) / imgProps.width;
let heightLeft = imgHeight;
let position = 15;
pdf.setFontSize(18);
pdf.setTextColor(getComputedStyle(document.documentElement).getPropertyValue('--primary-color').trim());
pdf.text("Climate Risk Stress Test Report", pdfWidth / 2, 10, { align: 'center' });
pdf.addImage(imgData, 'PNG', 0, position, pdfWidth, imgHeight);
heightLeft -= pdfHeight;
while (heightLeft >= 0) {
position = heightLeft - imgHeight;
pdf.addPage();
pdf.addImage(imgData, 'PNG', 0, position, pdfWidth, imgHeight);
heightLeft -= pdfHeight;
}
pdf.save('Climate_Risk_Report.pdf');
} catch (error) {
console.error("Error generating PDF:", error);
alert("Could not generate PDF.");
} finally {
pdfButton.style.visibility = 'visible';
}
}
// --- HELPER FUNCTIONS ---
function getRiskBadge(score) {
let colorClass = 'bg-risk-low';
if (score > 6) colorClass = 'bg-risk-medium';
if (score > 8) colorClass = 'bg-risk-high';
return `
`;
}
function getRiskLabel(score) {
if (score > 8) return 'High';
if (score > 6) return 'Medium';
return 'Low';
}
// --- START ---
init();
});