Retail Investor Activity Heatmap

Retail Investor Activity Heatmap

Heatmap Output

Select parameters and click "Generate Heatmap" to view data.

Note: This tool uses randomly generated mock data for demonstration purposes. Financial decisions should not be based on this output.

No data available for selected sector.

'; return; } if (!dataToDisplay || dataToDisplay.length === 0) { heatmapContainer.innerHTML = '

No data to display for the selected criteria.

'; return; } dataToDisplay.forEach(item => { const cell = document.createElement('div'); cell.className = 'heatmap-cell'; cell.style.backgroundColor = getColorForValue(item.value, metric); // Adjust text color for better contrast on dark backgrounds const bgColor = cell.style.backgroundColor; // Basic check: if color is dark (e.g. red, dark green), use white text. // This is a simplified check. A more robust solution would calculate luminance. if (bgColor.includes('rgb(215, 48, 39)') || bgColor.includes('rgb(26, 152, 80)') || bgColor.includes('rgb(215,48,39)') || bgColor.includes('rgb(26,152,80)')) { // d73027 or 1a9850 cell.style.color = '#fff'; } else { cell.style.color = '#333'; // Dark text for lighter backgrounds } const nameSpan = document.createElement('span'); nameSpan.className = 'heatmap-cell-name'; nameSpan.textContent = item.name; cell.appendChild(nameSpan); const valueSpan = document.createElement('span'); valueSpan.className = 'heatmap-cell-value'; let displayValue = item.value; if (metric === 'TRADING_VOLUME' || metric === 'NET_FLOW') { displayValue = `$${Math.abs(item.value).toLocaleString()}`; if (metric === 'NET_FLOW' && item.value < 0) { displayValue = `-$${Math.abs(item.value).toLocaleString()}`; } } valueSpan.textContent = displayValue; cell.appendChild(valueSpan); heatmapContainer.appendChild(cell); }); // Populate Legend const legendData = getLegendData(metric); legendData.forEach(item => { const legendItem = document.createElement('div'); legendItem.className = 'legend-item'; const colorBox = document.createElement('div'); colorBox.className = 'legend-color-box'; colorBox.style.backgroundColor = item.color; legendItem.appendChild(colorBox); const label = document.createElement('span'); label.textContent = item.label; legendItem.appendChild(label); heatmapLegend.appendChild(legendItem); }); showMessage('Heatmap generated successfully with mock data.', 'success'); }); } else { console.error("Generate Heatmap button not found."); } // Event Listener for Download PDF Button if (downloadPdfBtn) { downloadPdfBtn.addEventListener('click', function () { const pdfContent = document.getElementById('pdfContent'); if (!pdfContent) { showMessage('PDF content area not found. Cannot generate PDF.', 'error'); console.error("PDF content element not found."); return; } if (heatmapContainer.children.length === 0 || heatmapContainer.textContent.includes("Select parameters")) { showMessage('Please generate a heatmap first before downloading PDF.', 'info'); return; } showMessage('Generating PDF... Please wait.', 'info'); // Temporarily adjust styles for PDF rendering if needed (e.g. ensure all content is visible) // Example: ensure heatmap cells are laid out for capture. // This might involve temporarily changing grid-template-columns for #heatmapContainer // if html2canvas has issues with the 'auto-fill' or 'auto-fit' values. // For this example, we assume html2canvas handles it well. const { jsPDF } = window.jspdf; html2canvas(pdfContent, { scale: 2, useCORS: true, backgroundColor: '#ffffff' }).then(canvas => { try { const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF({ orientation: 'portrait', unit: 'pt', // points format: 'a4' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const pdfHeight = pdf.internal.pageSize.getHeight(); const canvasWidth = canvas.width; const canvasHeight = canvas.height; // Calculate the aspect ratio const ratio = canvasWidth / canvasHeight; let imgWidth = pdfWidth - 40; // With margins let imgHeight = imgWidth / ratio; // If image height exceeds page height, scale down if (imgHeight > pdfHeight - 40) { imgHeight = pdfHeight - 40; imgWidth = imgHeight * ratio; } const x = (pdfWidth - imgWidth) / 2; const y = 20; // Top margin pdf.addImage(imgData, 'PNG', x, y, imgWidth, imgHeight); // Generate a filename const sector = marketSectorSelect.value; const metric = activityMetricSelect.value; const date = new Date().toISOString().split('T')[0]; const filename = `RetailActivityHeatmap_${sector}_${metric}_${date}.pdf`; pdf.save(filename); showMessage('PDF downloaded successfully.', 'success'); } catch (e) { console.error("Error generating PDF:", e); showMessage('Error generating PDF. See console for details.', 'error'); } }).catch(error => { console.error("Error with html2canvas:", error); showMessage('Error capturing content for PDF. See console for details.', 'error'); }); }); } else { console.error("Download PDF button not found."); } });
Scroll to Top