30-Day Price Forecast
${formatter.format(forecastData.priceForecast.low)} - ${formatter.format(forecastData.priceForecast.high)}
Based on an IPO price of ${formatter.format(forecastData.inputs.ipoPrice)}
Forecast Factor Analysis
`;
// Render Chart
const chartCtx = document.getElementById('forecastChart').getContext('2d');
if (forecastChart) forecastChart.destroy();
forecastChart = new Chart(chartCtx, {
type: 'bar',
data: {
labels: ['Industry', 'Growth', 'Profitability', 'Sentiment', 'Underwriter'],
datasets: [{
label: 'Score Contribution',
data: [
forecastData.scoreBreakdown.industry,
forecastData.scoreBreakdown.revenueGrowth,
forecastData.scoreBreakdown.profitMargin,
forecastData.scoreBreakdown.marketSentiment,
forecastData.scoreBreakdown.underwriterQuality
],
backgroundColor: 'rgba(0, 123, 255, 0.6)',
borderColor: 'rgba(0, 123, 255, 1)',
borderWidth: 1
}]
},
options: {
indexAxis: 'y',
responsive: true,
plugins: { legend: { display: false } },
scales: {
x: { beginAtZero: true, max: 25 }
}
}
});
};
const updateExportPreview = () => {
if (!forecastData) {
summaryContainer.innerHTML = `
Generate a forecast on the 'Forecast Dashboard' tab to see the report preview.
`;
return;
}
const formatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' });
summaryContainer.innerHTML = `
Company
${forecastData.inputs.companyName}
Forecast Score
${forecastData.finalScore}/100 (${forecastData.forecastLabel})
30-Day Price Forecast
${formatter.format(forecastData.priceForecast.low)} - ${formatter.format(forecastData.priceForecast.high)}
`;
};
const downloadPDF = () => {
if (!forecastData) {
alert('Please generate a forecast first on the "Forecast Dashboard" tab.');
return;
}
const { jsPDF } = window.jspdf;
const doc = new jsPDF({ orientation: 'p', unit: 'pt', format: 'a4' });
const theme = document.querySelector('input[name="theme"]:checked').value;
const page = { width: doc.internal.pageSize.getWidth(), height: doc.internal.pageSize.getHeight() };
const margin = 50;
let y = 0;
const formatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' });
const colors = theme === 'growth'
? { bg: '#047857', text: '#FFFFFF', primary: '#1f2937', secondary: '#4b5563', accent: '#10b981' }
: { bg: '#0056b3', text: '#FFFFFF', primary: '#212529', secondary: '#495057', accent: '#007bff' };
// --- Header ---
doc.setFillColor(colors.bg);
doc.rect(0, 0, page.width, 90, 'F');
doc.setFont('helvetica', 'bold');
doc.setFontSize(22);
doc.setTextColor(colors.text);
doc.text('IPO Performance Forecast Report', margin, 55);
doc.setFontSize(12);
doc.text(`Company: ${forecastData.inputs.companyName}`, margin, 75);
y = 130;
// --- Summary Section ---
doc.setFont('helvetica', 'bold');
doc.setFontSize(14);
doc.setTextColor(colors.primary);
doc.text('Forecast Summary', margin, y);
y += 20;
doc.autoTable({
startY: y,
theme: 'grid',
headStyles: { fillColor: colors.accent },
body: [
['Forecast Score', `${forecastData.finalScore} / 100`],
['Forecast Outlook', forecastData.forecastLabel],
['IPO Price', formatter.format(forecastData.inputs.ipoPrice)],
['30-Day Price Forecast', `${formatter.format(forecastData.priceForecast.low)} - ${formatter.format(forecastData.priceForecast.high)}`],
]
});
y = doc.autoTable.previous.finalY + 30;
// --- Chart ---
if (y > page.height - 220) {
doc.addPage(); y = margin;
}
doc.setFont('helvetica', 'bold');
doc.setFontSize(14);
doc.setTextColor(colors.primary);
doc.text('Forecast Factor Analysis', margin, y);
y += 20;
const chartImage = forecastChart.toBase64Image();
doc.addImage(chartImage, 'PNG', margin, y, page.width - margin*2, (page.width - margin*2) / 2.5);
y += (page.width - margin*2) / 2.5 + 30;
// --- Input Factors Table ---
if (y > page.height - 150) {
doc.addPage(); y = margin;
}
doc.setFont('helvetica', 'bold');
doc.setFontSize(14);
doc.setTextColor(colors.primary);
doc.text('Input Factors', margin, y);
y += 20;
doc.autoTable({
startY: y,
theme: 'striped',
headStyles: { fillColor: colors.accent },
head: [['Factor', 'Input']],
body: [
['Industry', forecastData.inputs.factors.industry.label],
['YoY Revenue Growth', forecastData.inputs.factors.revenueGrowth.label],
['Net Profit Margin', forecastData.inputs.factors.profitMargin.label],
['Market Sentiment', forecastData.inputs.factors.marketSentiment.label],
['Underwriter Quality', forecastData.inputs.factors.underwriterQuality.label],
['Deal Size', forecastData.inputs.factors.dealSize.label],
]
});
doc.save(`ipo-forecast-${forecastData.inputs.companyName.replace(/\s+/g, '-')}.pdf`);
};
// --- Event Listeners ---
tabs.forEach((tab, index) => tab.addEventListener('click', () => showTab(index)));
prevBtn.addEventListener('click', () => navigateTab(-1));
nextBtn.addEventListener('click', () => navigateTab(1));
forecastBtn.addEventListener('click', generateForecast);
downloadPdfBtn.addEventListener('click', downloadPDF);
// --- Initialization ---
showTab(0);
});