Map Timeline
This is a demo visualizing event timeline on a map. Drag the year slider below the map and countries on a map light up as the slider crosses the year when that country joined a [fictional] treaty.
Key implementation details
We create a Slider
with year range from our data. Then when the value (range) of the slider changes we update our country polygons and set active
on the countries that joined the treaty that year or earlier.
Related tutorials
Demo source
<!-- Styles -->
<style>
#chartdiv {
width: 100%;
height: 900px;
}
</style>
<!-- Resources -->
<script src="https://cdn.amcharts.com/lib/5/index.js"></script>
<script src="https://cdn.amcharts.com/lib/5/map.js"></script>
<script src="https://cdn.amcharts.com/lib/5/geodata/worldLow.js"></script>
<script src="https://cdn.amcharts.com/lib/5/themes/Animated.js"></script>
<!-- Chart code -->
<script>
am5.ready(function() {
// Country data
var data = [
{ year: 2004, country: "AF" },
{ year: 2001, country: "AL" },
{ year: 1989, country: "DZ" },
{ year: 2015, country: "AD" },
{ year: 2017, country: "AO" },
{ year: 1989, country: "AG" },
{ year: 1989, country: "AR" },
{ year: 1997, country: "AM" },
{ year: 1975, country: "AU" },
{ year: 1961, country: "AT" },
{ year: 2000, country: "AZ" },
{ year: 2006, country: "BS" },
{ year: 1988, country: "BH" },
{ year: 1992, country: "BD" },
{ year: 1993, country: "BB" },
{ year: 1960, country: "BY" },
{ year: 1975, country: "BE" },
{ year: 2021, country: "BZ" },
{ year: 1974, country: "BJ" },
{ year: 2014, country: "BT" },
{ year: 1995, country: "BO" },
{ year: 1993, country: "BA" },
{ year: 1971, country: "BW" },
{ year: 2002, country: "BR" },
{ year: 1996, country: "BN" },
{ year: 1961, country: "BG" },
{ year: 1987, country: "BF" },
{ year: 2014, country: "BI" },
{ year: 2018, country: "CV" },
{ year: 1960, country: "KH" },
{ year: 1988, country: "CM" },
{ year: 1986, country: "CA" },
{ year: 1962, country: "CF" },
{ year: 1975, country: "CL" },
{ year: 1987, country: "CN" },
{ year: 1979, country: "CO" },
{ year: 2015, country: "KM" },
{ year: 2009, country: "CK" },
{ year: 1987, country: "CR" },
{ year: 1991, country: "CI" },
{ year: 1993, country: "HR" },
{ year: 1974, country: "CU" },
{ year: 1980, country: "CY" },
{ year: 1993, country: "CZ" },
{ year: 2014, country: "CD" },
{ year: 1972, country: "DK" },
{ year: 1983, country: "DJ" },
{ year: 1988, country: "DM" },
{ year: 2002, country: "DO" },
{ year: 1962, country: "EC" },
{ year: 1959, country: "EG" },
{ year: 1998, country: "SV" },
{ year: 1993, country: "EE" },
{ year: 2020, country: "ET" },
{ year: 2010, country: "FJ" },
{ year: 1962, country: "FI" },
{ year: 1959, country: "FR" },
{ year: 2006, country: "GA" },
{ year: 1994, country: "GE" },
{ year: 1975, country: "DE" },
{ year: 1968, country: "GH" },
{ year: 1962, country: "GR" },
{ year: 1984, country: "GT" },
{ year: 1991, country: "GN" },
{ year: 2014, country: "GY" },
{ year: 1983, country: "HT" },
{ year: 1975, country: "VA" },
{ year: 2000, country: "HN" },
{ year: 1962, country: "HU" },
{ year: 2002, country: "IS" },
{ year: 1960, country: "IN" },
{ year: 1981, country: "ID" },
{ year: 2001, country: "IR" },
{ year: 2021, country: "IQ" },
{ year: 1981, country: "IE" },
{ year: 1959, country: "IL" },
{ year: 1969, country: "IT" },
{ year: 2002, country: "JM" },
{ year: 1961, country: "JP" },
{ year: 1979, country: "JO" },
{ year: 1995, country: "KZ" },
{ year: 1989, country: "KE" },
{ year: 1978, country: "KW" },
{ year: 1996, country: "KG" },
{ year: 1998, country: "LA" },
{ year: 1992, country: "LV" },
{ year: 1998, country: "LB" },
{ year: 1989, country: "LS" },
{ year: 2005, country: "LR" },
{ year: 2011, country: "LI" },
{ year: 1995, country: "LT" },
{ year: 1983, country: "LU" },
{ year: 1962, country: "MG" },
{ year: 2021, country: "MW" },
{ year: 1985, country: "MY" },
{ year: 2019, country: "MV" },
{ year: 1994, country: "ML" },
{ year: 2000, country: "MT" },
{ year: 2006, country: "MH" },
{ year: 1997, country: "MR" },
{ year: 1996, country: "MU" },
{ year: 1971, country: "MX" },
{ year: 1982, country: "MC" },
{ year: 1994, country: "MN" },
{ year: 2006, country: "ME" },
{ year: 1959, country: "MA" },
{ year: 1998, country: "MZ" },
{ year: 2013, country: "MM" },
{ year: 1998, country: "NP" },
{ year: 1964, country: "NL" },
{ year: 1983, country: "NZ" },
{ year: 2003, country: "NI" },
{ year: 1964, country: "NE" },
{ year: 1970, country: "NG" },
{ year: 1994, country: "MK" },
{ year: 1961, country: "NO" },
{ year: 1999, country: "OM" },
{ year: 2005, country: "PK" },
{ year: 2020, country: "PW" },
{ year: 1984, country: "PA" },
{ year: 2019, country: "PG" },
{ year: 1997, country: "PY" },
{ year: 1988, country: "PE" },
{ year: 1967, country: "PH" },
{ year: 1961, country: "PL" },
{ year: 1994, country: "PT" },
{ year: 2002, country: "QA" },
{ year: 1973, country: "KR" },
{ year: 1998, country: "MD" },
{ year: 1961, country: "RO" },
{ year: 1960, country: "RU" },
{ year: 2008, country: "RW" },
{ year: 1979, country: "SM" },
{ year: 2012, country: "ST" },
{ year: 1994, country: "SA" },
{ year: 1994, country: "SN" },
{ year: 2001, country: "RS" },
{ year: 2020, country: "SC" },
{ year: 2020, country: "SL" },
{ year: 1986, country: "SG" },
{ year: 1993, country: "SK" },
{ year: 1992, country: "SI" },
{ year: 1976, country: "ZA" },
{ year: 1977, country: "ES" },
{ year: 1962, country: "LK" },
{ year: 2000, country: "VC" },
{ year: 2015, country: "PS" },
{ year: 2018, country: "SD" },
{ year: 1972, country: "SE" },
{ year: 1965, country: "CH" },
{ year: 1959, country: "SY" },
{ year: 2012, country: "TJ" },
{ year: 1959, country: "TH" },
{ year: 2020, country: "TO" },
{ year: 1966, country: "TT" },
{ year: 1967, country: "TN" },
{ year: 1992, country: "TR" },
{ year: 1992, country: "UG" },
{ year: 1960, country: "UA" },
{ year: 2006, country: "AE" },
{ year: 1975, country: "GB" },
{ year: 1964, country: "TZ" },
{ year: 1970, country: "US" },
{ year: 1983, country: "UY" },
{ year: 1996, country: "UZ" },
{ year: 1995, country: "VE" },
{ year: 1995, country: "VN" },
{ year: 2002, country: "ZM" },
{ year: 1994, country: "ZW" }
];
// Create root element
// https://www.amcharts.com/docs/v5/getting-started/#Root_element
var root = am5.Root.new("chartdiv");
// Set themes
// https://www.amcharts.com/docs/v5/concepts/themes/
root.setThemes([
am5themes_Animated.new(root)
]);
// Create the map chart
// https://www.amcharts.com/docs/v5/charts/map-chart/
var chart = root.container.children.push(am5map.MapChart.new(root, {
panX: "rotateX",
panY: "translateY",
projection: am5map.geoNaturalEarth1()
}));
// Title
chart.children.unshift(am5.Label.new(root, {
text: "A timeline of countries joining treaty X",
fontSize: 22,
fontWeight: "400",
textAlign: "center",
x: am5.percent(50),
centerX: am5.percent(50)
}));
// Create main polygon series for countries
// https://www.amcharts.com/docs/v5/charts/map-chart/map-polygon-series/
var polygonSeries = chart.series.push(am5map.MapPolygonSeries.new(root, {
geoJSON: am5geodata_worldLow,
exclude: ["AQ"]
}));
polygonSeries.mapPolygons.template.setAll({
tooltipText: "{name}",
toggleKey: "active",
interactive: true
});
polygonSeries.mapPolygons.template.states.create("hover", {
fill: root.interfaceColors.get("primaryButtonHover")
});
polygonSeries.mapPolygons.template.states.create("active", {
fill: root.interfaceColors.get("primaryButtonActive")
});
// Set clicking on "water" to zoom out
chart.chartContainer.get("background").events.on("click", function() {
chart.goHome();
})
// Make stuff animate on load
chart.appear(1000, 100);
// Aggregate data
var years = {};
var firstYear = 99999;
var lastYear = 0;
for(var i = 0; i < data.length; i++) {
var row = data[i];
var year = row.year;
if (years[year] == undefined) {
years[year] = [];
}
years[year].push(row.country);
if (firstYear > year) {
firstYear = year;
}
if (lastYear < year) {
lastYear = year;
}
}
// Create controls
var container = chart.children.push(am5.Container.new(root, {
y: am5.p100,
centerX: am5.p50,
centerY: am5.p100,
x: am5.p50,
width: am5.percent(90),
layout: root.horizontalLayout,
paddingBottom: 10
}));
var playButton = container.children.push(am5.Button.new(root, {
themeTags: ["play"],
centerY: am5.p50,
marginRight: 40,
icon: am5.Graphics.new(root, {
themeTags: ["icon"]
})
}));
playButton.events.on("click", function () {
if (playButton.get("active")) {
slider.set("start", slider.get("start") + 0.0001);
} else {
slider.animate({
key: "start",
to: 1,
duration: 15000 * (1 - slider.get("start"))
});
}
});
var slider = container.children.push(am5.Slider.new(root, {
//width: am5.percent(80),
orientation: "horizontal",
start: 0,
centerY: am5.p50
}));
slider.startGrip.get("icon").set("forceHidden", true);
slider.startGrip.set("label", am5.Label.new(root, {
text: firstYear + "",
paddingTop: 0,
paddingRight: 0,
paddingBottom: 0,
paddingLeft: 0
}));
updateCountries(firstYear);
slider.events.on("rangechanged", function () {
var year = firstYear + Math.round(slider.get("start", 0) * (lastYear - firstYear));
slider.startGrip.get("label").set("text", year + "");
updateCountries(year);
console.log(year)
// updateSeriesData(
// firstYear + Math.round(slider.get("start", 0) * (lastYear - firstYear))
// );
});
function updateCountries(year) {
am5.object.each(years, function(joinYear, countries) {
//console.log(countries)
am5.array.each(countries, function(country) {
var dataItem = polygonSeries.getDataItemById(country);
if (dataItem) {
dataItem.get("mapPolygon").set("active", joinYear <= year)
}
})
})
}
}); // end am5.ready()
</script>
<!-- HTML -->
<div id="chartdiv"></div>