Using Datamaps for Animating Maps Overtime

The past week the data team was tasked with visualizing map statistics over a map. This seems easy for anyone who has used D3.js, but for me this was a first time for me. Most of my visualizations are done using python, so moving to javascript was an interesting adventure. From what I have heard from my colleagues who have used D3.js, the tricky part is manipulating the svg image. This blog will be split into 3:

  • Creating a basic map with data
  • Manipulating data using D3.js
  • Animating the map

Creating a basic map with data in D3.js

I found an interesting library called Datamaps . Datamaps uses Topojson.js for the mapping of the different countries. If there is a country missing and you want to add it, that is the place to edit. To create a basic map, one needs to call the datamaps object in javascript. Below is a n example of how to do that.

var map = new Datamap({
scope: 'world',
element: document.getElementById('container1'),
//height: 900,
geographyConfig: {
popupOnHover: false,
highlightOnHover: false,
borderColor: 'black',
borderWidth: 0.5});

The above code will produce a world map. If you can a specific country, change the value of the scope from world to whichever country you want. The geographyconfig key is used to change the look and feel of the map. Try to change the configurations and see what happens.

One thing that we found was a challenge was to make the map responsive. The dimensions of the map are added to the datamap class on javascript. Our work around was to fill the whole screen of the device using height 100vh. We did this on the css.


.world-map {
height: 100vh !important;
}

To add data on to the map, you first decide how you will do it visually. Is it using bubbles or different colors for the countries. For us we used bubbles, since we wanted to show the growth of population over time.


map.bubbles([
{centered: 'RWA', fillKey: 'Trouble', radius: 4},
{centered: 'AUS', fillKey: 'Visited', radius: 15}
], {})

fillkey is the color to be used and radius is how big the bubble will be. There is a bubbleconfig key that is used to configure the bubble.

Manipulating data using D3.js

With D3.js, one can manipulate data just like when using pandas. First you can load a data from different sources and file types like csv, tsv, json or url link. For csv, the code below will explain how to do it.

d3.csv( ‘csvfilepath’, function( data ) {
return data;
});

If you want to filter the data, there is a function called filter that does that. An example is, if you want to select only female participants.

var femaledata = data.filter(function(d, i)
{
if (d[‘gender’]== ‘Female’)
{
return d;
}
});

data in the code above is from the code above, meaning this piece of code should be inside that of loading data. If you want to get the max value of age:

maxAge = d3.max(femaledata, function(d) { return d.Age; });

To get the mean and min, just change the word max to what you want. Something we found interesting was working with dates. How do you get year or month from a timestamp. Or how do you normalize timezones?

new Date(d['Timestamp']).getFullYear();

The code above will give you the year, if you want the day or the month, getDate or getMonth.

Finally, we will look at how to group the data and get aggregated values.


var genderCount = d3.nest()
.key(function(d) { return d.country; })
.rollup(function(v) { return v.length; })
.entries(hourlydata);

You can find more ways in a blog by learningjsdata .

Animating the map

Animating the map is simple. All one has to do is to set the intervals you function will be called. A usecase is when one wants to go through a whole decade monitoring the change of participants in an election, you can set the interval to be 5 seconds. This means that 5 seconds represents one year. After every 5 seconds the statistics is calculated and added to the map. A code snippet of intervals is shown below:


setInterval(function(){
electionsCount()
}, 5000);

If you want to stop the animation after a certain condition, use the close  clearInterval() function. One can implement it as follows:


intervalId = setInterval(function(){
year = (Number(year) + 1).toString();
electionsCount();
if (Number(year) >= Number(maxyear) ){
clearInterval(intervalId);
}
}, 5000);
}

That is it for this blog. I hope that these tips will help you in your map visualization. Feel free to share any other discoveries that you will find.