Economic Indicator Dashboard

Economic Indicator Dashboard

A snapshot of key U.S. economic performance metrics.

U.S. Economic Snapshot

As of September 2025

${indicator.title}

${indicator.latestValuePrefix} ${latestData.value.toFixed(2)}${indicator.unit}

${change.toFixed(2)}${indicator.unit} vs. previous
`; kpiContainer.innerHTML += kpiCard; // Render Chart const chartCard = `

${indicator.title} Trend

`; chartsContainer.innerHTML += chartCard; } // Post-render chart creation for (const key in economicData) { renderChart(key); } lucide.createIcons(); } function renderChart(key) { const indicator = economicData[key]; const ctx = document.getElementById(`chart-${key}`).getContext('2d'); const labels = indicator.data.map(d => d.label); const data = indicator.data.map(d => d.value); const chartConfig = { type: indicator.chartType, data: { labels, datasets: [{ label: indicator.title, data, backgroundColor: indicator.chartType === 'bar' ? '#3b82f6' : 'transparent', borderColor: '#1d4ed8', borderWidth: 2, borderRadius: 4, tension: 0.1, fill: false, pointBackgroundColor: '#1d4ed8', }] }, options: { responsive: true, maintainAspectRatio: false, scales: { y: { beginAtZero: false, ticks: { callback: value => `${value.toFixed(1)}${indicator.unit}` } } }, plugins: { legend: { display: false } } } }; if (chartInstances[key]) chartInstances[key].destroy(); chartInstances[key] = new Chart(ctx, chartConfig); } // --- DATA CONFIGURATION RENDERING --- function renderDataConfig() { const container = document.getElementById('data-config-container'); container.innerHTML = ''; for (const key in economicData) { const indicator = economicData[key]; const section = document.createElement('div'); section.className = 'card p-6'; let dataRowsHtml = indicator.data.map((d, index) => `
`).join(''); section.innerHTML = `

${indicator.title}

${dataRowsHtml}
`; container.appendChild(section); } // Attach event listeners after rendering container.querySelectorAll('.data-label, .data-value').forEach(input => input.addEventListener('input', updateData)); container.querySelectorAll('.remove-data-btn').forEach(btn => btn.addEventListener('click', removeData)); container.querySelectorAll('.add-data-btn').forEach(btn => btn.addEventListener('click', addData)); lucide.createIcons(); } // --- DATA MANIPULATION HANDLERS --- function updateData(e) { const { key, index } = e.target.parentElement.dataset; const field = e.target.classList.contains('data-label') ? 'label' : 'value'; const value = field === 'value' ? parseFloat(e.target.value) || 0 : e.target.value; economicData[key].data[index][field] = value; renderDashboard(); // Re-render dashboard on data change } function removeData(e) { const { key, index } = e.currentTarget.parentElement.dataset; economicData[key].data.splice(index, 1); renderAll(); } function addData(e) { const { key } = e.currentTarget.dataset; economicData[key].data.push({ label: 'New Label', value: 0 }); renderAll(); } function renderAll() { renderDashboard(); renderDataConfig(); } // --- UI & PDF --- window.changeTab = function(tabNumber) { document.querySelectorAll('.tab-btn, .tab-content').forEach(el => el.classList.remove('active')); document.getElementById(`tab-btn-${tabNumber}`).classList.add('active'); document.getElementById(`tab-content-${tabNumber}`).classList.add('active'); document.getElementById('prev-btn').style.display = (tabNumber === 2) ? 'inline-flex' : 'none'; document.getElementById('next-btn').style.display = (tabNumber === 1) ? 'inline-flex' : 'none'; } window.downloadPDF = function() { const { jsPDF } = window.jspdf; const pdfElement = document.getElementById('pdf-output'); Object.values(chartInstances).forEach(chart => { if (chart) chart.options.animation = false; }); html2canvas(pdfElement, { scale: 2, backgroundColor: '#f0f2f5' }).then(canvas => { Object.values(chartInstances).forEach(chart => { if (chart) chart.options.animation = true; }); const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF({ orientation: 'landscape', unit: 'px', format: 'a4' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const pageMargin = 40; const contentWidth = pdfWidth - (pageMargin * 2); const canvasRatio = canvas.height / canvas.width; const contentHeight = contentWidth * canvasRatio; pdf.addImage(imgData, 'PNG', pageMargin, pageMargin, contentWidth, contentHeight); pdf.save('Economic-Dashboard.pdf'); }); } init(); });
Scroll to Top