27
How to Build an Interactive Flow Map in JavaScript
A step-by-step tutorial showing how to create an interactive JS Flow Map. Illustrated by visualizing data on migration to the US.
It may seem to be complicated to create an interactive Flow Map for the Web using JavaScript. But it’s not! This easy-to-follow tutorial will show you how to build beautiful JS flow maps without too much effort.
In these difficult times of the pandemic, there is a lot of confusion and concern about the immigration status of people around the globe. I decided to take a look at the immigration data of the US which has more migrants than any other country in the world. Here, I explore where these immigrants come from and represent the top 15 countries that contributed the highest number of migrants to the US in the year 2019.
A flow map seems the perfect way to showcase the inflow of migrants into the United States from various countries. Before going further, let me give you a brief idea about a flow map and its uses.
A flow map is a type of connector map that is drawn by connecting points placed on a map by straight or curved lines with an arrow or marker indicating the direction of the flow. Generally, the magnitude of the flow is represented by the thickness of the line.
Start and endpoints for the connectors in these maps are defined by the latitude and longitude parameters so it’s necessary to set these for each connector. Note that the latitude of the point should be defined first and then the longitude for each point.
For example, here’s the flow map I will have created by the end of this tutorial. [CodePen | Playground]
There are a lot of good JavaScript charting libraries that can be used to create compelling data visualizations. Many of them provide the capabilities to build maps and have their strengths. So you can use whichever library best fits your project requirements.
In this tutorial, I am using AnyChart. It looks the most suitable here with the out-of-the-box flow map option and in-depth documentation to understand the process.
A flow map is slightly more complicated than a basic chart like a bar or a pie chart but I will walk you through the lines of code to make it easier to grasp. Some background knowledge about HTML and JavaScript will help you understand faster but nonetheless, it is not too difficult. Look how you can create a beautiful interactive JavaScript flow map in 4 simple steps.
The first step is to create a blank HTML page that will hold the interactive flow map. Add a div
element with a unique id to this page which will be referenced later.
I set the width and height of the div to 100% so that the map is displayed over the entire screen. This can be modified based on the requirement and preference.
<html>
<head>
<title>JavaScript Flow Map</title>
<style type="text/css">
html, body, #container {
width: 100%; height: 100%; margin: 0; padding: 0;
}
</style>
</head>
<body>
<div id="container"></div>
</body>
</html>
To use a charting library for building a data visualization, you will need to link the appropriate JS scripts of the library you are using. All these script files are included in the HTML page.
Since the map is of the whole world, I link the file containing the world geodata, from the library’s collection of maps also available on its CDN.
In addition, I will make use of another JavaScript library — Proj4js — which, in short, takes care of plotting the coordinates over the respective geographical areas.
<html>
<head>
<title>JavaScript Flow Map</title>
<script src="https://cdn.anychart.com/releases/8.10.0/js/anychart-core.min.js"></script>
<script src="https://cdn.anychart.com/releases/8.10.0/js/anychart-map.min.js"></script>
<script src="https://cdn.anychart.com/geodata/latest/custom/world/world.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.15/proj4.js"></script>
<style type="text/css">
html, body, #container {
width: 100%; height: 100%; margin: 0; padding: 0;
}
</style>
</head>
<body>
<div id="container"></div>
<script>
// All the code for the JS flow map will come here
</script>
</body>
</html>
For the map, the data needs to have the latitude and longitude coordinates along with the other information to be displayed. I created the dataset by collating immigration information from Wikipedia and adding the coordinates from a site called Latlong.
For the flow map, I need the latitude and longitude of the source country as well as the destination country. Here, the destination country is the US for all the data points. To check out how the dataset looks, you can find the file here.
To load the data file, I will include the Data Adapter module of AnyChart in the <head>
section of the HTML page [and make use of the loadJsonFile()
method within the <script>
tag in the HTML page body to load the file with the JSON data for the flow map visualization].
<html>
<head>
<title>JavaScript Flow Map</title>
<script src="https://cdn.anychart.com/releases/8.10.0/js/anychart-core.min.js"></script>
<script src="https://cdn.anychart.com/releases/8.10.0/js/anychart-map.min.js"></script>
<script src="https://cdn.anychart.com/geodata/latest/custom/world/world.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.15/proj4.js"></script>
<script src="https://cdn.anychart.com/releases/8.10.0/js/anychart-data-adapter.min.js"></script>
<style type="text/css">
html, body, #container {
width: 100%; height: 100%; margin: 0; padding: 0;
}
</style>
</head>
<body>
<div id="container"></div>
<script>
anychart.data.loadJsonFile('https://gist.githubusercontent.com/shacheeswadia/a20ba5b62cef306ccc1a8e8857e5316a/raw/0337b16fa8dc4de97263bc0a4ededf935a529c35/migration-data.json', function (data) {
// The JS flow map's code will come here
});
</script>
</body>
</html>
Before anything else, I will enclose all the code inside the anychart.onDocumentReady()
function which will ensure that the page is fully loaded before anything is executed. Next, I will load the data using anychart.data.loadJsonFile()
function.
Now, I create the flow map using the connector function since this is a type of connector map and then set the geodata along with settings to make sure that all the regions of the world are visible clearly.
anychart.onDocumentReady(function () {
anychart.data.loadJsonFile('https://gist.githubusercontent.com/shacheeswadia/a20ba5b62cef306ccc1a8e8857e5316a/raw/0337b16fa8dc4de97263bc0a4ededf935a529c35/migration-data.json', function (data) {
// сreate a connector map chart instance
var map = anychart.connector();
// include the world map geodata
map.geoData('anychart.maps.world');
// darken all regions
map
.unboundRegions()
.enabled(true)
.fill('#E1E1E1')
.stroke('#D2D2D2');
})
});
I add a title to the chart and allow the overlap so that all the data points along with their labels are seen on the map even if they overlap.
// set the map chart title
map
.title('Migrations to the USA from the top 15 countries');
// display all labels even if there is an overlap
map
.overlapMode("allow-overlap");
Now comes the main part of creating the connector series which will represent the various connections.
For this, I create a helper function with data as its parameter. In the function, I create the series that will form the connector lines and add the arrow markers at 100% position which is the destination since our flow is from the various source countries to the destination country — the US.
I then add labels that display the source country names.
// a helper function to create the series
// that will form the connector lines
var createSeries = function (data) {
// create and customize the connector series
var connectorSeries = map
.connector(data);
connectorSeries
.markers()
.position('100%')
.size(10);
// set the labels for the source countries
connectorSeries
.labels()
.enabled(true)
.format(function () {
return this.getData('from');
});
};
I now set the data and call the function that I created with that dataset as the argument. The final steps are setting the container to reference the previously added div and drawing the map.
// create a dataset from the data
var dataSet = anychart.data.set(data).mapAs();
createSeries(dataSet);
// set the container
map.container('container');
// draw the map
map.draw();
Lo and behold! A nice, functional, JavaScript-based flow map is made! It wasn’t that tough to create such an interactive data visualization, was it?
Have a look at this initial version on CodePen [or Playground].
The existing flow map just built using JavaScript is a good representation showing where the majority of migrants come from. But the amount of immigrants from each country is not displayed. So, I will customize the map to show that and make the map more insightful, with some additional code. I will also improve the visual aesthetics and make some other minor changes.
A. Setting the colors and size of the connectors along with the legend
B. Improving the tooltip information
C. Enhancing the title and labels
CONTINUE READING HERE FOR A WALKTHROUGH OF THESE JS FLOW MAP CUSTOMIZATIONS
27