(async () => {
const topology = await fetch(
'https://code.highcharts.com/mapdata/custom/world.topo.json'
).then(response => response.json());
const csv = await fetch(
'https://cdn.jsdelivr.net/gh/highcharts/[email protected]/samples/data/world-population-history.csv'
).then(response => response.text());
const CSVtoArray = text => text.replace(/^"/, '')
.replace(/",$/, '')
.split('","');
const csvArr = csv.split(/\n/),
countries = {},
numRegex = /^[0-9\.]+$/,
lastCommaRegex = /,\s$/,
quoteRegex = /\"/g,
categories = CSVtoArray(csvArr[2]).slice(4);
let countryChart;
csvArr.slice(3).forEach(function (line) {
var row = CSVtoArray(line),
data = row.slice(4);
data.forEach(function (val, i) {
val = val.replace(quoteRegex, '');
if (numRegex.test(val)) {
val = parseInt(val, 10);
} else if (!val || lastCommaRegex.test(val)) {
val = null;
}
data[i] = val;
});
countries[row[1]] = {
name: row[0],
code3: row[1],
data: data
};
});
const data = [];
for (const code3 in countries) {
if (Object.hasOwnProperty.call(countries, code3)) {
const itemData = countries[code3].data;
let value = null,
i = itemData.length,
year;
while (i--) {
if (typeof itemData[i] === 'number') {
value = itemData[i];
year = categories[i];
break;
}
}
data.push({
name: countries[code3].name,
code3: code3,
value: value,
year: year
});
}
}
const mapData = Highcharts.geojson(topology);
mapData.forEach(function (country) {
country.id = country.properties['hc-key'];
country.flag = country.id.replace('UK', 'GB').toLowerCase();
});
Highcharts.wrap(Highcharts.Point.prototype, 'select', function (proceed) {
proceed.apply(this, Array.prototype.slice.call(arguments, 1));
const points = this.series.chart.getSelectedPoints();
if (points.length) {
if (points.length === 1) {
document.querySelector('#info #flag')
.className = 'flag ' + points[0].flag;
document.querySelector('#info h2').innerHTML = points[0].name;
} else {
document.querySelector('#info #flag')
.className = 'flag';
document.querySelector('#info h2').innerHTML = 'Comparing countries';
}
document.querySelector('#info .subheader')
.innerHTML = '<h4>Historical population</h4><small><em>Shift + Click on map to compare countries</em></small>';
if (!countryChart) {
countryChart = Highcharts.chart('country-chart', {
chart: {
height: 250
},
credits: {
enabled: false
},
title: {
text: null
},
subtitle: {
text: null
},
xAxis: {
tickPixelInterval: 50,
crosshair: true
},
yAxis: {
title: null,
opposite: true
},
tooltip: {
split: true
},
plotOptions: {
series: {
animation: {
duration: 500
},
marker: {
enabled: false
},
threshold: 0,
pointStart: parseInt(categories[0], 10)
}
}
});
}
countryChart.series.slice(0).forEach(function (s) {
s.remove(false);
});
points.forEach(function (p) {
countryChart.addSeries({
name: p.name,
data: countries[p.code3].data,
type: points.length > 1 ? 'line' : 'area'
}, false);
});
countryChart.redraw();
} else {
document.querySelector('#info #flag').className = '';
document.querySelector('#info h2').innerHTML = '';
document.querySelector('#info .subheader').innerHTML = '';
if (countryChart) {
countryChart = countryChart.destroy();
}
}
});
const mapChart = Highcharts.mapChart('container', {
chart: {
map: topology
},
title: {
text: 'Population history by country'
},
subtitle: {
text: 'Source: <a href="http://data.worldbank.org/indicator/SP.POP.TOTL/countries/1W?display=default">The World Bank</a>'
},
mapNavigation: {
enabled: true,
buttonOptions: {
verticalAlign: 'bottom'
}
},
mapView: {
fitToGeometry: {
type: 'MultiPoint',
coordinates: [
[-164, 54],
[-35, 84],
[179, -38],
[-68, -55]
]
}
},
colorAxis: {
type: 'logarithmic',
endOnTick: false,
startOnTick: false,
min: 50000
},
tooltip: {
footerFormat: '<span style="font-size: 10px">(Click for details)</span>'
},
series: [{
data: data,
mapData: mapData,
joinBy: ['iso-a3', 'code3'],
name: 'Current population',
allowPointSelect: true,
cursor: 'pointer',
states: {
select: {
color: '#a4edba',
borderColor: 'black',
dashStyle: 'shortdot'
}
},
borderWidth: 0.5
}]
});
mapChart.get('us').select();
})();