Confidence Level
${data.confidence}%
AI Recommendation
${data.recommendation}
Key Factors Analyzed by AI
${data.factors.map(factor => `
-
${factor.impact === 'Positive' ? '' : ''}
${factor.impact === 'Negative' ? '' : ''}
${factor.impact === 'Neutral' ? '' : ''}
${factor.text}
${factor.reason}
`).join('')}
Simulated Price Action Chart
`;
renderChart(data);
}
function renderChart(data) {
const ctx = document.getElementById('priceChart')?.getContext('2d');
if (!ctx) return;
if (chartInstance) {
chartInstance.destroy();
}
// Simulate price data for the chart
const labels = [];
const prices = [];
let currentPrice = 100; // Base price
for(let i = -data.lockupPeriod; i < 30; i++) {
const date = new Date(data.lockupExpirationDate);
date.setDate(date.getDate() + i);
labels.push(date.toLocaleDateString('en-US', { month: 'short', day: 'numeric'}));
// Simulate price trend based on performance
let trend = (data.postIpoPerformance - 0.5) * 0.1;
let volatility = (Math.random() - 0.5) * 5;
// Simulate price drop around expiration
if (i > -7 && i < 10) {
trend -= (data.confidence/100 - 0.5) * 0.2;
}
currentPrice += trend + volatility;
prices.push(currentPrice.toFixed(2));
}
chartInstance = new Chart(ctx, {
type: 'line',
data: {
labels: labels,
datasets: [{
label: `${data.stockTicker} Simulated Price ($)`,
data: prices,
borderColor: '#2563eb',
backgroundColor: 'rgba(37, 99, 235, 0.1)',
fill: true,
tension: 0.4,
borderWidth: 2,
pointRadius: 0
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: false,
ticks: {
callback: function(value) {
return '$' + value;
}
}
}
},
plugins: {
legend: {
display: true
},
annotation: {
annotations: {
lockupLine: {
type: 'line',
scaleID: 'x',
value: data.lockupExpirationDate,
borderColor: '#ef4444', // red-500
borderWidth: 2,
borderDash: [6, 6],
label: {
content: 'Lockup Expiration',
enabled: true,
position: 'start',
backgroundColor: 'rgba(239, 68, 68, 0.8)'
}
}
}
}
}
}
});
// Hacky way to add annotation as the plugin is not standard in Chart.js 3+
// For a production tool, use a proper annotation plugin.
// This visual simulation is for demonstration purposes.
setTimeout(() => {
if (chartInstance && chartInstance.options.plugins.annotation) {
const expirationIndex = labels.indexOf(data.lockupExpirationDate);
if (expirationIndex !== -1) {
const line = chartInstance.options.plugins.annotation.annotations.lockupLine;
const xScale = chartInstance.scales.x;
const yScale = chartInstance.scales.y;
ctx.save();
ctx.beginPath();
ctx.moveTo(xScale.getPixelForValue(expirationIndex), yScale.top);
ctx.lineTo(xScale.getPixelForValue(expirationIndex), yScale.bottom);
ctx.lineWidth = line.borderWidth;
ctx.strokeStyle = line.borderColor;
ctx.setLineDash(line.borderDash);
ctx.stroke();
ctx.fillStyle = line.label.backgroundColor;
ctx.fillRect(xScale.getPixelForValue(expirationIndex) - 50, yScale.top + 10, 100, 20);
ctx.fillStyle = '#fff';
ctx.textAlign = 'center';
ctx.fillText('Lockup Ends', xScale.getPixelForValue(expirationIndex), yScale.top + 24);
ctx.restore();
}
}
}, 500);
}
// --- PDF Download Functionality ---
function downloadPDF() {
const pdfElement = document.getElementById('pdf-output');
const stockTicker = document.getElementById('stockTicker')?.value.toUpperCase() || 'Strategy';
if (!pdfElement) {
alert("Could not find the content to download.");
return;
}
// Temporarily change style for PDF rendering to ensure colors are captured
pdfElement.style.backgroundColor = 'white';
const { jsPDF } = window.jspdf;
html2canvas(pdfElement, {
scale: 2, // Higher scale for better quality
useCORS: true,
backgroundColor: '#ffffff' // Explicitly set background
}).then(canvas => {
// Restore original style
pdfElement.style.backgroundColor = '';
const imgData = canvas.toDataURL('image/png');
const pdf = new jsPDF({
orientation: 'portrait',
unit: 'px',
format: [canvas.width, canvas.height]
});
pdf.addImage(imgData, 'PNG', 0, 0, canvas.width, canvas.height);
pdf.save(`${stockTicker}-IPO-Lockup-Strategy.pdf`);
}).catch(err => {
console.error("Error generating PDF:", err);
alert("An error occurred while generating the PDF. Please try again.");
// Restore original style in case of error
pdfElement.style.backgroundColor = '';
});
}