Dividend Aristocrats & Growth Stocks Analyzer

Dividend Aristocrats & Growth Stocks Analyzer

Stock Analysis Report

Dividend Aristocrats Summary (Mock Data)

Avg. Yield: N/A

Avg. Growth Years: N/A

Companies Displayed: 0

Growth Stocks Summary (Mock Data)

Avg. Revenue Growth: N/A

Avg. P/E Ratio: N/A

Companies Displayed: 0

${stock.sector} - Market Cap: ${formatMarketCap(stock.marketCap)}

Revenue Growth: ${formatNumber(stock.revenueGrowthYoY,1)}%
EPS Growth: ${formatNumber(stock.epsGrowthYoY,0)}%
P/E Ratio: ${formatNumber(stock.peRatio,0)}
`; growthGrid.appendChild(card); }); updateGrowthSummary(data); } // --- Summary Update Functions --- function updateAristocratsSummary(data) { if (!avgAristocratYieldEl || !avgAristocratGrowthYearsEl || !aristocratCountEl) return; if (data.length === 0) { avgAristocratYieldEl.textContent = 'N/A'; avgAristocratGrowthYearsEl.textContent = 'N/A'; aristocratCountEl.textContent = '0'; return; } const totalYield = data.reduce((sum, s) => sum + s.yield, 0); const totalGrowthYears = data.reduce((sum, s) => sum + s.growthYears, 0); avgAristocratYieldEl.textContent = `${formatNumber(totalYield / data.length, 2)}%`; avgAristocratGrowthYearsEl.textContent = formatNumber(totalGrowthYears / data.length, 1); aristocratCountEl.textContent = data.length; } function updateGrowthSummary(data) { if (!avgGrowthRevGrowthEl || !avgGrowthPERatioEl || !growthCountEl) return; if (data.length === 0) { avgGrowthRevGrowthEl.textContent = 'N/A'; avgGrowthPERatioEl.textContent = 'N/A'; growthCountEl.textContent = '0'; return; } const totalRevGrowth = data.reduce((sum, s) => sum + s.revenueGrowthYoY, 0); const totalPERatio = data.reduce((sum, s) => sum + s.peRatio, 0); avgGrowthRevGrowthEl.textContent = `${formatNumber(totalRevGrowth / data.length, 1)}%`; avgGrowthPERatioEl.textContent = formatNumber(totalPERatio / data.length, 1); growthCountEl.textContent = data.length; } // --- Filtering and Combined Render --- function filterAndRender() { if (!searchInput) { renderAristocrats(dividendAristocratsData); renderGrowthStocks(growthStocksData); return; } const searchTerm = searchInput.value.toLowerCase().trim(); if (currentTab === 'aristocrats') { const filteredAristocrats = dividendAristocratsData.filter(stock => stock.name.toLowerCase().includes(searchTerm) || stock.ticker.toLowerCase().includes(searchTerm) ); renderAristocrats(filteredAristocrats); } else if (currentTab === 'growth') { const filteredGrowth = growthStocksData.filter(stock => stock.name.toLowerCase().includes(searchTerm) || stock.ticker.toLowerCase().includes(searchTerm) ); renderGrowthStocks(filteredGrowth); } } if (searchInput) { searchInput.addEventListener('input', filterAndRender); } // --- PDF Generation --- function generatePdf() { if (!pdfContentEl || !pdfTitleForReport) { console.error("PDF content or title element not found."); // User-friendly message const msgBox = document.createElement('div'); msgBox.textContent = "Error preparing PDF content. Please try again."; msgBox.style.cssText = "position:fixed; top:20px; left:50%; transform:translateX(-50%); background:red; color:white; padding:10px; border-radius:5px; z-index:1000;"; document.body.appendChild(msgBox); setTimeout(() => msgBox.remove(), 3000); return; } // Update PDF title based on current tab const activeTabName = currentTab === 'aristocrats' ? 'Dividend Aristocrats' : 'Growth Stocks'; pdfTitleForReport.textContent = `${activeTabName} Analysis Report`; pdfTitleForReport.classList.remove('hidden-for-pdf-title'); // Make it visible for PDF // Temporarily hide the inactive tab content for PDF generation const inactiveTabId = currentTab === 'aristocrats' ? 'growthContent' : 'aristocratsContent'; const inactiveTabContent = document.getElementById(inactiveTabId); let inactiveTabOriginalDisplay = ''; if (inactiveTabContent) { inactiveTabOriginalDisplay = inactiveTabContent.style.display; inactiveTabContent.style.display = 'none'; } const opt = { margin: [0.5, 0.5, 0.5, 0.5], // inches filename: `${currentTab}_stock_analysis_report.pdf`, image: { type: 'jpeg', quality: 0.98 }, html2canvas: { scale: 2, logging: false, useCORS: true, letterRendering: true, scrollY: 0 }, jsPDF: { unit: 'in', format: 'letter', orientation: 'portrait' }, pagebreak: { mode: ['avoid-all', 'css', 'legacy'] } }; html2pdf().from(pdfContentEl).set(opt).save().then(() => { pdfTitleForReport.classList.add('hidden-for-pdf-title'); // Hide PDF title on screen again if (inactiveTabContent) { // Restore display of inactive tab inactiveTabContent.style.display = inactiveTabOriginalDisplay; } }).catch(err => { console.error("Error generating PDF:", err); pdfTitleForReport.classList.add('hidden-for-pdf-title'); if (inactiveTabContent) { // Restore display of inactive tab inactiveTabContent.style.display = inactiveTabOriginalDisplay; } // User-friendly error message const errorBox = document.createElement('div'); errorBox.textContent = "Failed to generate PDF. See console for details."; errorBox.style.cssText = "position:fixed; top:20px; left:50%; transform:translateX(-50%); background:red; color:white; padding:10px; border-radius:5px; z-index:1000;"; document.body.appendChild(errorBox); setTimeout(() => errorBox.remove(), 3000); }); } if (downloadPdfButton) { downloadPdfButton.addEventListener('click', generatePdf); } // --- Initial Render --- switchTab('aristocrats'); // Set initial tab and render updateNavButtons(); // Initialize nav button states });
Scroll to Top