Global Inflation & Hyperinflation Watchlist

Global Inflation & Hyperinflation Watchlist

Track and analyze simulated annual inflation trends across various countries, identifying potential hyperinflation risks.

Analysis Setup

Generating AI insights...

`; const selectedCountryKeys = Array.from(document.querySelectorAll('#country-selection input:checked')).map(cb => cb.dataset.countryKey); const startYear = parseInt(startYearInput.value); const endYear = parseInt(endYearInput.value); // Input Validation if (selectedCountryKeys.length === 0) { showMessageBox("Selection Error", "Please select at least one country/region for analysis."); resetButtonState(trackBtn, trackBtnText, trackSpinner); return; } if (isNaN(startYear) || isNaN(endYear) || startYear < 1950 || endYear > 2023 || startYear >= endYear) { showMessageBox("Input Error", "Please enter valid start and end years (1950-2023) where the start year is before the end year."); resetButtonState(trackBtn, trackBtnText, trackSpinner); return; } // Generate simulated data for all selected countries const allInflationData = {}; selectedCountryKeys.forEach(countryKey => { allInflationData[countryKey] = generateSimulatedInflationData(countryKey, startYear, endYear); }); displayInflationTrends(allInflationData, selectedCountryKeys, startYear, endYear); populateWatchlistTable(allInflationData, selectedCountryKeys); const resultsSectionElement = document.getElementById('results-section'); if (resultsSectionElement) { resultsSectionElement.classList.remove('hidden'); resultsSectionElement.scrollIntoView({ behavior: 'smooth' }); } if (downloadPdfBtn) downloadPdfBtn.disabled = false; // Generate AI insights await getAIAnalysis(allInflationData, selectedCountryKeys, startYear, endYear); resetButtonState(trackBtn, trackBtnText, trackSpinner); }; // --- Display Results --- /** * Displays the inflation trends in a Chart.js line chart. */ function displayInflationTrends(allInflationData, selectedCountryKeys, startYear, endYear) { const ctx = inflationTrendChartCanvas?.getContext('2d'); if (!ctx) return; if (inflationChartInstance) { inflationChartInstance.destroy(); } const labels = Array.from({ length: endYear - startYear + 1 }, (_, i) => startYear + i); const datasets = selectedCountryKeys.map((countryKey, index) => { const countryData = allInflationData[countryKey].map(d => d.inflation); const colors = [ 'rgb(79, 70, 229)', // Indigo 'rgb(234, 88, 12)', // Orange 'rgb(16, 185, 129)', // Emerald 'rgb(59, 130, 246)', // Blue 'rgb(124, 58, 237)', // Violet 'rgb(244, 63, 94)', // Rose 'rgb(6, 182, 212)', // Cyan 'rgb(107, 114, 128)',// Gray 'rgb(251, 191, 36)', // Yellow 'rgb(185, 28, 28)', // Red 'rgb(2, 132, 199)' // Sky blue ]; return { label: COUNTRIES[countryKey].displayName, data: countryData, borderColor: colors[index % colors.length], backgroundColor: colors[index % colors.length], fill: false, tension: 0.1 // Smooth lines }; }); inflationChartInstance = new Chart(ctx, { type: 'line', data: { labels: labels, datasets: datasets }, options: { responsive: true, maintainAspectRatio: false, plugins: { tooltip: { callbacks: { label: function(context) { let label = context.dataset.label || ''; if (label) { label += ': '; } if (context.parsed.y !== null) { label += context.parsed.y.toFixed(2) + '%'; } return label; } } } }, scales: { x: { title: { display: true, text: 'Year' } }, y: { title: { display: true, text: 'Annual Inflation Rate (%)' }, beginAtZero: false } } } }); } /** * Populates the watchlist table with summary inflation metrics. */ function populateWatchlistTable(allInflationData, selectedCountryKeys) { if (!watchlistTableBody || !noWatchlistMessage) return; watchlistTableBody.innerHTML = ''; // Clear previous results let flaggedCountriesCount = 0; selectedCountryKeys.forEach(countryKey => { const countryData = allInflationData[countryKey]; const inflationRates = countryData.map(d => d.inflation); if (inflationRates.length === 0) return; // Skip if no data for this country const averageInflation = inflationRates.reduce((sum, val) => sum + val, 0) / inflationRates.length; const maxInflation = Math.max(...inflationRates); let status = 'Stable'; let rowClass = ''; // Initialize as empty if (maxInflation >= HYPERINFLATION_THRESHOLD_ANNUAL) { status = 'Hyperinflation Risk'; rowClass = 'hyperinflation-flag'; flaggedCountriesCount++; } else if (averageInflation >= HIGH_INFLATION_THRESHOLD_ANNUAL) { status = 'High Inflation'; rowClass = 'high-inflation-flag'; flaggedCountriesCount++; } else if (maxInflation >= HIGH_INFLATION_THRESHOLD_ANNUAL) { // If max was high but average was not status = 'Volatile (Spikes)'; rowClass = 'high-inflation-flag'; flaggedCountriesCount++; } const row = watchlistTableBody.insertRow(); // Only add the class if rowClass is not empty. This fixes the SyntaxError. if (rowClass) { row.classList.add(rowClass); } row.innerHTML = ` ${COUNTRIES[countryKey].displayName} ${averageInflation.toFixed(2)}% ${maxInflation.toFixed(2)}% ${status} `; }); if (flaggedCountriesCount === 0) { noWatchlistMessage.classList.remove('hidden'); } else { noWatchlistMessage.classList.add('hidden'); } } // --- AI Integration --- /** * Calls the Gemini API to get AI-powered insights on the simulated inflation trends. */ const getAIAnalysis = async (allInflationData, selectedCountryKeys, startYear, endYear) => { const aiContainer = document.getElementById('ai-insights-content'); if (!aiContainer) return; let dataSummary = `Simulated Annual Inflation Rate (%) data for countries: ${selectedCountryKeys.map(key => COUNTRIES[key].displayName).join(', ')} from ${startYear} to ${endYear}.\n\n`; const watchlistData = []; // Collect data for AI to easily process watchlist info selectedCountryKeys.forEach(countryKey => { const countryData = allInflationData[countryKey]; const inflationRates = countryData.map(d => d.inflation); if (inflationRates.length > 0) { const averageInflation = inflationRates.reduce((sum, val) => sum + val, 0) / inflationRates.length; const maxInflation = Math.max(...inflationRates); let status = 'Stable'; if (maxInflation >= HYPERINFLATION_THRESHOLD_ANNUAL) { status = 'Hyperinflation Risk'; } else if (averageInflation >= HIGH_INFLATION_THRESHOLD_ANNUAL) { status = 'High Inflation'; } else if (maxInflation >= HIGH_INFLATION_THRESHOLD_ANNUAL) { status = 'Volatile (Spikes)'; } watchlistData.push({ country: COUNTRIES[countryKey].displayName, average: averageInflation, max: maxInflation, status: status }); dataSummary += `- ${COUNTRIES[countryKey].displayName}: Average ${averageInflation.toFixed(2)}%, Max ${maxInflation.toFixed(2)}%\n`; } }); const prompt = ` You are an economic analyst specializing in global inflation. A user has simulated annual inflation data for several countries. Analysis Period: ${startYear} to ${endYear} Countries Analyzed: ${selectedCountryKeys.map(key => COUNTRIES[key].displayName).join(', ')} Here is a summary of the simulated inflation data and watchlist statuses: ${dataSummary} Provide a brief, actionable analysis (around 300-400 words) covering: 1. Key Observations: Highlight significant trends, including which countries show stable inflation, high inflation, or potential hyperinflation (referencing the watchlist statuses). 2. Economic Factors: Briefly discuss hypothetical economic factors that *could* lead to such inflation patterns (e.g., aggressive money printing, supply chain disruptions, political instability, strong demand, exchange rate depreciation). Do NOT claim these are actual causes for the simulated data, but rather discuss them as general principles. 3. Implications: What are the potential implications of these inflation trends for investors, consumers, and economic stability in affected regions? 4. Caveats: Remind the user that these are simplified simulations and real-world outcomes are influenced by complex, interacting factors. Format the response in simple HTML using only

for titles and
  • for lists. `; try { const payload = { contents: [{ role: "user", parts: [{ text: prompt }] }] }; const apiKey = ""; // API key is handled by the Canvas environment at runtime const apiUrl = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${apiKey}`; const response = await fetch(apiUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); const result = await response.json(); let text = "

    Could not generate AI analysis. Please try again.

    "; if (result.candidates && result.candidates[0] && result.candidates[0].content && result.candidates[0].content.parts[0]) { text = result.candidates[0].content.parts[0].text; } aiContainer.innerHTML = text; } catch (error) { console.error("Error fetching AI insights:", error); aiContainer.innerHTML = `

    Error generating AI insights.

    `; } }; // --- PDF Export Logic --- /** * Exports the visible analysis summary (chart, watchlist table, and AI insights) to a PDF document. */ window.downloadPDF = async () => { // Make it global for onclick attribute const btn = document.getElementById('pdf-button-container')?.querySelector('button'); if (!btn) return; btn.disabled = true; btn.textContent = 'Generating PDF...'; const content = document.getElementById('summary-for-pdf'); if (!content) { showMessageBox("PDF Error", "Content for PDF not found."); btn.disabled = false; btn.textContent = 'Download Analysis as PDF'; return; } try { // Temporarily adjust chart and table sizes for better PDF rendering const chartCanvas = inflationTrendChartCanvas; const originalChartWidth = chartCanvas.style.width; const originalChartHeight = chartCanvas.style.height; chartCanvas.style.width = '1000px'; // Larger size for better quality capture chartCanvas.style.height = '500px'; if (inflationChartInstance) { inflationChartInstance.resize(); // Trigger Chart.js to redraw with new dimensions } const watchlistTable = document.getElementById('watchlist-table'); const originalTableWidth = watchlistTable.style.width; watchlistTable.style.width = 'fit-content'; // Allow table to expand naturally for capture const canvas = await html2canvas(content, { scale: 2, // Increase scale for better resolution useCORS: true, logging: false, backgroundColor: '#ffffff' // Ensure the background is white for PDF }); // Restore original chart and table sizes chartCanvas.style.width = originalChartWidth; chartCanvas.style.height = originalChartHeight; if (inflationChartInstance) { inflationChartInstance.resize(); } watchlistTable.style.width = originalTableWidth; const imgData = canvas.toDataURL('image/png'); const { jsPDF } = window.jspdf; // Determine orientation based on content width. If the captured canvas is very wide, use landscape. const orientation = canvas.width > canvas.height * 1.5 ? 'landscape' : 'portrait'; const pdf = new jsPDF({ orientation: orientation, unit: 'mm', format: 'a4' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const pdfHeight = pdf.internal.pageSize.getHeight(); const imgWidth = pdfWidth - 20; // 10mm margin on each side let imgHeight = (canvas.height * imgWidth) / canvas.width; let finalImgWidth = imgWidth; let finalImgHeight = imgHeight; if (finalImgHeight > pdfHeight - 20) { // If image is taller than page height finalImgHeight = pdfHeight - 20; finalImgWidth = (canvas.width * finalImgHeight) / canvas.height; } const x = (pdfWidth - finalImgWidth) / 2; const y = (pdfHeight - finalImgHeight) / 2; pdf.addImage(imgData, 'PNG', x, y, finalImgWidth, finalImgHeight); pdf.save(`Inflation_Watchlist_Analysis_${new Date().toISOString().slice(0, 10)}.pdf`); showMessageBox("PDF Generated", "Your Global Inflation Watchlist analysis PDF has been successfully downloaded."); } catch(e) { console.error("PDF Generation Error: ", e); showMessageBox("PDF Error", "An error occurred while generating the PDF. Please ensure all content is visible and try again."); } finally { btn.disabled = false; btn.textContent = 'Download Analysis as PDF'; } }; // --- Initial Setup --- initCountryCheckboxes(); // Optionally, run initial analysis on page load // runAnalysis(); });

Scroll to Top