Data Visualization

In this tutorial I want to describe the process of data visualization with jVectorMap. At the moment data could be visualized with jVectorMap in several ways. You can use color, opacity or marker size to represent some values on the map. I want to demonstrate jVectorMap abilities in data visualization on the example, which shows dynamic of unemployment rate in the USA from 2005 to 2009. The final result is available in the examples section.

To build our map we will use three sets of data: unemployment statistic by metropolitan areas and states and population statistic by metropolitan area. While the unemployment statistic will be presented using the color gradients, the population will be visualized using the size of markers representing metro areas. All the data used in the this tutorial is available on the site of U.S. Census Bureau with their powerful FactFinder service.

To collect all the data and convert it to a suitable format I use simple script written in Ruby language which I like for neat syntax and endless set of libraries for any purpose. The full source code of the project is available from the GitHub repository.

So once all the data is packed in one JSON file and ready to use we can start to build the visualization. First we need some html stub with all the scripts and CSS files connected. The stub will have only two elements on the page: container of the map and container for the slider which will be used to switch the

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8"/>
  <title>Maps</title>
  <link rel="stylesheet" media="all" href="../jvectormap/jquery-jvectormap.css"/>
  <link rel="stylesheet" media="all" href="css/jquery-ui-1.8.21.custom.css"/>
  <script src="../jvectormap/tests/assets/jquery-1.8.2.min.js"></script>
  <script src="../jvectormap.min.js"></script>
  <script src="../jvectormap/tests/assets/jquery-jvectormap-us-aea.js"></script>
  <script src="jquery-ui-1.8.21.custom.min.js"></script>
  <script>
    $(function(){
      // here we will place the code to initialize the map
    })
  </script>
</head>
<body>
  <div class="map" style="width: 800px; height: 600px"></div>
  <div class="slider" style="width: 280px; margin: 10px"></div>
</body>
</html>

The data in our example is received via AJAX request and once the it is loaded the map could be initialized.

$.getJSON('data.json', function(data){
  //...
}

Now the map is ready to be created:

$('.map').vectorMap({
  map: 'us_aea_en',
  markers: data.metro.coords,
  series: {
    markers: [{
      attribute: 'fill',
      scale: ['#FEE5D9', '#A50F15'],
      values: data.metro.unemployment[val],
      min: jvm.min(metroUnemplValues),
      max: jvm.max(metroUnemplValues)
    },{
      attribute: 'r',
      scale: [5, 20],
      values: data.metro.population[val],
      min: jvm.min(metroPopValues),
      max: jvm.max(metroPopValues)
    }],
    regions: [{
      scale: ['#DEEBF7', '#08519C'],
      attribute: 'fill',
      values: data.states[val],
      min: jvm.min(statesValues),
      max: jvm.max(statesValues)
    }]
  }
  //...
});

While map is created the following configuration parameters are passed to the constructor:

  • map - the name of the map. In this example we use Albers projection of the US map,
  • markers - this is just an array containing the coordinates of metropolitan areas,
  • series - this parameters describes how the data will be presented visually on the map; there are two sections: regions and markers, each of which is an array of objects with the following parameters:
    • attribute - parameter which will be used to visualize data, this could be: fill for the fill color of the marker or region, stroke for color of stroke or r for the radius of the marker,
    • values - this is default set of the values to apply,
    • scale - this parameter is used to define the minimum and maximum value which could be assigned to the attribute ([5, 20] for the r parameter means that radius of the marker will be set to 5 for the minimum input value and 20 for maximum)
    • min and max - these parameters could be just omitted in the most of the cases and calculated automatically, though in our example we need to provide them to visualize the difference between several years.

You can read more about these and other parameters in the documentation.

Now let's make make the labels which are shown when mouse cursor is over region or label more readable. To achieve this we need to set callbacks for the hover events and modify labels inside of them:

onMarkerTipShow: function(event, label, index){
  label.html(
    '<b>'+data.metro.names[index]+'</b><br/>'+'<b>Population:</b>'+data.metro.population[val][index]+'</br>'+'<b>Unemployment rate: </b>'+data.metro.unemployment[val][index]+'%'
  );
},
onRegionTipShow: function(event, label, code){
  label.html(
    '<b>'+label.html()+'</b></br>'+'<b>Unemployment rate: </b>'+data.states[val][code]+'%'
  );
}

Now the last step is to define action on the slider movement. Slider used in this example is a standard component from the jQuery UI framework. By default we visualize data for the last year in the report. If slider is moved we need to update data according to the date chosen. DataSeries class have setValues method for that:

var mapObject = $('.map').vectorMap('get', 'mapObject');
$(".slider").slider({
  value: val,
  min: 2005,
  max: 2009,
  step: 1,
  slide: function( event, ui ) {
    val = ui.value;
    mapObject.series.regions[0].setValues(data.states[ui.value]);
    mapObject.series.markers[0].setValues(data.metro.unemployment[ui.value]);
    mapObject.series.markers[1].setValues(data.metro.population[ui.value]);
  }
});