`;
// Update secondary biases
const secondaryContainer = document.getElementById('secondary-bias-list');
secondaryContainer.innerHTML = '';
sortedBiases.slice(1, 4).forEach(([key, score]) => {
if (score > 0) {
const info = biasDefinitions[key];
const div = document.createElement('div');
div.className = 'border-t pt-4';
div.innerHTML = `
${info.name}
${info.description}
`; secondaryContainer.appendChild(div); } }); if (secondaryContainer.innerHTML === '') { secondaryContainer.innerHTML = 'No other significant biases detected based on your answers.
'; } } // --- CHARTING --- function createRadarChart() { const ctx = document.getElementById('biasRadarChart')?.getContext('2d'); if (ctx) { biasRadarChart = new Chart(ctx, { type: 'radar', data: { labels: Object.values(biasDefinitions).map(b => b.name), datasets: [{ label: 'Bias Strength', data: Array(Object.keys(biasDefinitions).length).fill(0), backgroundColor: 'rgba(79, 70, 229, 0.2)', borderColor: 'rgba(79, 70, 229, 1)', borderWidth: 2 }] }, options: { responsive: true, maintainAspectRatio: false, scales: { r: { angleLines: { color: '#d1d5db' }, grid: { color: '#e5e7eb' }, pointLabels: { font: { size: 12 } }, suggestedMin: 0, suggestedMax: 4 } }, plugins: { legend: { display: false } } } }); } } // --- TAB NAVIGATION --- function updateActiveTab() { tabPanels.forEach((panel, index) => panel.classList.toggle('hidden', index !== currentTabIndex)); tabs.forEach((tab, index) => { tab.classList.toggle('tab-btn-active', index === currentTabIndex); tab.classList.toggle('tab-btn-inactive', index !== currentTabIndex); tab.classList.toggle('border-indigo-600', index === currentTabIndex); tab.classList.toggle('border-transparent', index !== currentTabIndex); }); updateNavButtons(); } function updateNavButtons() { if (prevBtn) prevBtn.disabled = currentTabIndex === 0; if (nextBtn) nextBtn.disabled = currentTabIndex === tabs.length - 1; prevBtn?.classList.toggle('opacity-50', prevBtn?.disabled); nextBtn?.classList.toggle('opacity-50', nextBtn?.disabled); } function navigateNext() { if (currentTabIndex < tabs.length - 1) { currentTabIndex++; updateActiveTab(); } } function navigatePrev() { if (currentTabIndex > 0) { currentTabIndex--; updateActiveTab(); } } // --- PDF DOWNLOAD --- function downloadPDF() { const { jsPDF } = window.jspdf; const doc = new jsPDF({ orientation: 'p', unit: 'mm', format: 'a4' }); const primaryColor = '#4338CA'; // Indigo-700 const today = new Date().toLocaleDateString('en-US'); // --- Page 1: Summary & Chart --- doc.setFillColor('#F1F5F9'); // Slate-100 doc.rect(0, 0, 210, 297, 'F'); doc.setFontSize(24); doc.setTextColor(primaryColor); doc.setFont('helvetica', 'bold'); doc.text('Trading Psychology Report', 105, 25, { align: 'center' }); doc.setFontSize(11); doc.setTextColor('#475569'); // Slate-600 doc.text(`Generated on ${today}`, 105, 33, { align: 'center' }); if (biasRadarChart && biasRadarChart.data.datasets[0].data.some(d => d > 0)) { const chartImg = biasRadarChart.toBase64Image('image/jpeg', 0.85); doc.addImage(chartImg, 'JPEG', 45, 45, 120, 120); const sortedBiases = biasRadarChart.data.labels.map((label, index) => ({ name: label, score: biasRadarChart.data.datasets[0].data[index] })).sort((a, b) => b.score - a.score); const primaryBiasName = sortedBiases[0].name; const primaryBiasInfo = Object.values(biasDefinitions).find(b => b.name === primaryBiasName); doc.setFontSize(16); doc.setTextColor(primaryColor); doc.text('Primary Bias Detected:', 14, 180); doc.setFontSize(20); doc.setTextColor('#1E293B'); // Slate-800 doc.text(primaryBiasInfo.name, 14, 188); doc.setFontSize(10); const splitDesc = doc.splitTextToSize(primaryBiasInfo.description, 182); doc.text(splitDesc, 14, 196); doc.setFillColor('#EEF2FF'); // Indigo-50 doc.roundedRect(14, 215, 182, 20, 3, 3, 'F'); doc.setFontSize(11); doc.setTextColor(primaryColor); doc.setFont('helvetica', 'bold'); doc.text('Actionable Tip:', 18, 222); doc.setFont('helvetica', 'normal'); doc.setTextColor('#3730A3'); // Indigo-800 const splitTip = doc.splitTextToSize(primaryBiasInfo.tip, 174); doc.text(splitTip, 18, 228); } else { doc.text('No analysis performed. Please complete the questionnaire first.', 105, 120, { align: 'center' }); } // --- Page 2: Trade Log --- if (tradeLog.length > 0) { doc.addPage(); doc.setFontSize(18); doc.setTextColor(primaryColor); doc.text('Recent Trade Log', 14, 20); const head = [['Date', 'Asset', 'Action', 'Entry', 'Exit', 'Reason', 'Feeling']]; const body = tradeLog.map(t => Object.values(t)); doc.autoTable({ startY: 30, head: head, body: body, theme: 'striped', headStyles: { fillColor: primaryColor } }); } doc.save(`Trading_Psychology_Report_${today.replace(/\//g, '-')}.pdf`); } // --- RUN INITIALIZATION --- initialize(); });