No country data available for this year.
';
return;
}
countriesForYear.forEach(countryCode => {
const countryName = this.countryData[year][countryCode].name;
const label = document.createElement('label');
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.value = countryCode;
checkbox.id = `egdp-country-${countryCode}`;
label.appendChild(checkbox);
label.appendChild(document.createTextNode(` ${countryName}`));
countryCheckboxDiv.appendChild(label);
});
},
getSelectedCountries() {
const selectedCountries = [];
const checkboxes = document.querySelectorAll('#egdp-country-select-checkboxes input[type="checkbox"]:checked');
checkboxes.forEach(cb => selectedCountries.push(cb.value));
return selectedCountries;
},
formatNumber(num, decimals = 0) {
if (typeof num !== 'number') return 'N/A';
return num.toLocaleString(undefined, { minimumFractionDigits: decimals, maximumFractionDigits: decimals });
},
compareCountries() {
const year = document.getElementById('egdp-year-select').value;
const selectedCountryCodes = this.getSelectedCountries();
const resultsContainer = document.getElementById('egdp-results-container');
const noResultsMsg = document.getElementById('egdp-no-results-message');
const tableContainer = document.getElementById('egdp-comparison-table-container');
tableContainer.innerHTML = ''; // Clear previous table
if (this.charts['gdpNominalChart']) this.charts['gdpNominalChart'].destroy();
if (this.charts['gdpPerCapitaChart']) this.charts['gdpPerCapitaChart'].destroy();
if (selectedCountryCodes.length < 2 || !this.countryData[year]) {
resultsContainer.classList.add('hidden');
noResultsMsg.classList.remove('hidden');
if (selectedCountryCodes.length < 2) noResultsMsg.textContent = "Please select at least two countries for comparison.";
else noResultsMsg.textContent = `No data available for the year ${year}.`;
return;
}
noResultsMsg.classList.add('hidden');
resultsContainer.classList.remove('hidden');
let tableHTML = `
| Indicator | `;
selectedCountryCodes.forEach(code => {
tableHTML += `${this.countryData[year][code] ? this.countryData[year][code].name : code} | `;
});
tableHTML += `
`;
const indicators = [
{ key: 'gdpNominal', label: 'GDP Nominal (Bln USD)', formatter: (val) => this.formatNumber(val,0) },
{ key: 'gdpPPP', label: 'GDP PPP (Bln USD)', formatter: (val) => this.formatNumber(val,0) },
{ key: 'gdpPerCapitaNominal', label: 'GDP p.c. Nominal (USD)', formatter: (val) => this.formatNumber(val,0) },
{ key: 'gdpGrowth', label: 'GDP Growth (%)', formatter: (val) => `${this.formatNumber(val,1)}%` },
{ key: 'population', label: 'Population (Millions)', formatter: (val) => this.formatNumber(val,1) },
{ key: 'area', label: 'Land Area (sq km)', formatter: (val) => this.formatNumber(val,0) },
{ key: 'sectors', label: 'Sectors (% of GDP)', formatter: (obj) => `
- Agri: ${obj && obj.agriculture !== undefined ? obj.agriculture : 'N/A'}%
- Ind: ${obj && obj.industry !== undefined ? obj.industry : 'N/A'}%
- Svc: ${obj && obj.services !== undefined ? obj.services : 'N/A'}%
`
}
];
indicators.forEach(ind => {
tableHTML += `| ${ind.label} | `;
selectedCountryCodes.forEach(code => {
const country = this.countryData[year][code];
const value = country ? country[ind.key] : null;
tableHTML += `${country && value !== undefined ? ind.formatter(value) : 'N/A'} | `;
});
tableHTML += `
`;
});
tableHTML += `
`;
tableContainer.innerHTML = tableHTML;
// Prepare data for charts
const chartLabels = selectedCountryCodes.map(code => this.countryData[year][code] ? this.countryData[year][code].name : code);
const gdpNominalValues = selectedCountryCodes.map(code => this.countryData[year][code] ? this.countryData[year][code].gdpNominal : 0);
const gdpPerCapitaValues = selectedCountryCodes.map(code => this.countryData[year][code] ? this.countryData[year][code].gdpPerCapitaNominal : 0);
this.renderBarChart('egdp-gdp-nominal-chart', 'gdpNominalChart', chartLabels, gdpNominalValues, 'GDP Nominal (Billions USD)');
this.renderBarChart('egdp-gdp-per-capita-chart', 'gdpPerCapitaChart', chartLabels, gdpPerCapitaValues, 'GDP per Capita (Nominal USD)');
},
renderBarChart(canvasId, chartKey, labels, data, datasetLabel) {
const ctx = document.getElementById(canvasId).getContext('2d');
if (this.charts[chartKey]) {
this.charts[chartKey].destroy();
}
this.charts[chartKey] = new Chart(ctx, {
type: 'bar',
data: {
labels: labels,
datasets: [{
label: datasetLabel,
data: data,
backgroundColor: labels.map((_, i) => `hsl(${(i * 360 / labels.length) % 360}, 70%, 60%)`), // Dynamic colors
borderColor: labels.map((_, i) => `hsl(${(i * 360 / labels.length) % 360}, 70%, 50%)`),
borderWidth: 1
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: { y: { beginAtZero: true } },
plugins: { legend: { display: true, position: 'top' } }
}
});
},
downloadComparisonPDF() {
const year = document.getElementById('egdp-year-select').value;
const selectedCountryCodes = this.getSelectedCountries();
if (selectedCountryCodes.length < 1 || !this.countryData[year]) {
alert("Please select at least one country and ensure data is available for the selected year to generate a PDF.");
return;
}
const { jsPDF } = window.jspdf;
const doc = new jsPDF('p', 'pt', 'a4'); // Portrait, points, A4
doc.setFontSize(18);
doc.setTextColor(getComputedStyle(document.documentElement).getPropertyValue('--egdp-heading-color').trim());
doc.text(`Economic GDP Comparison - ${year}`, 40, 50);
let currentY = 70;
const selectedCountriesText = "Countries: " + selectedCountryCodes.map(code => this.countryData[year][code] ? this.countryData[year][code].name : code).join(', ');
doc.setFontSize(10);
doc.setTextColor(getComputedStyle(document.documentElement).getPropertyValue('--egdp-text-color').trim());
doc.text(selectedCountriesText, 40, currentY);
currentY += 20;
// Table
const tableElement = document.querySelector('#egdp-comparison-table-container table');
if (tableElement) {
doc.autoTable({
html: tableElement,
startY: currentY,
theme: 'grid',
headStyles: {
fillColor: getComputedStyle(document.documentElement).getPropertyValue('--egdp-primary-color').trim(),
textColor: '#ffffff',
fontStyle: 'bold'
},
styles: { fontSize: 8, cellPadding: 3 },
columnStyles: { 0: { fontStyle: 'bold' } }
});
currentY = doc.lastAutoTable.finalY + 30;
} else {
doc.text("No comparison table generated on the page.", 40, currentY);
currentY += 20;
}
// Charts
const chartsToExport = [
{ instance: this.charts['gdpNominalChart'], title: 'GDP Nominal (Billions USD)' },
{ instance: this.charts['gdpPerCapitaChart'], title: 'GDP per Capita (Nominal USD)' }
];
for (const chartInfo of chartsToExport) {
if (chartInfo.instance && chartInfo.instance.canvas) {
if (currentY > doc.internal.pageSize.height - 250) { // Check if space for chart title + chart
doc.addPage();
currentY = 40;
}
doc.setFontSize(12);
doc.setTextColor(getComputedStyle(document.documentElement).getPropertyValue('--egdp-heading-color').trim());
doc.text(chartInfo.title, 40, currentY);
currentY += 15;
try {
const imgData = chartInfo.instance.toBase64Image('image/png', 1.0);
const imgProps = doc.getImageProperties(imgData);
const pdfWidth = doc.internal.pageSize.getWidth() - 80; // page width - margins
let pdfHeight = (imgProps.height * pdfWidth) / imgProps.width;
if (pdfHeight > 200) pdfHeight = 200; // Max height for chart
if (currentY + pdfHeight > doc.internal.pageSize.height - 40) {
doc.addPage();
currentY = 40;
}
doc.addImage(imgData, 'PNG', 40, currentY, pdfWidth, pdfHeight);
currentY += pdfHeight + 20;
} catch (e) { console.error("Error adding chart to PDF:", e); }
}
}
// Add generated date footer
const pageCount = doc.internal.getNumberOfPages();
for (let i = 1; i <= pageCount; i++) {
doc.setPage(i);
doc.setFontSize(8);
doc.setTextColor(100);
doc.text(`Page ${i} of ${pageCount}`, doc.internal.pageSize.width - 70, doc.internal.pageSize.height - 20);
doc.text(`Generated: ${new Date().toLocaleString()}`, 40, doc.internal.pageSize.height - 20);
}
doc.save(`GDP_Comparison_${year}.pdf`);
}
};
document.addEventListener('DOMContentLoaded', () => {
egdpTool.init();
});