Blog - BS Data, hackery, stories

Draw simple maps with no effort with d3.js and datamaps.js

I started working on a new project for BBC News Labs this morning, and that project heavily relies on a map. After spending these last months working around Javascript and the famous datavisualisation library d3.js, my first reflex was to jump on d3.

However, the one first I find the hardest with d3 is to find tutorials to learn how to d3.

So this morning, when coming across topoJSON, geoson and other formats, phew, it was hard. The plan was to create a simple world map template that I could reuse later with many different datasets. Then, I discovered DataMaps, a light JS library to create "customizable SVG map visualisations for the web in a single Javascript file using D3.js". Sounded cool.

DataMaps is in fact really easy to set up, with a classic constructor to fill with options. At the moment, and without too much exploration, I find some limitations to it (for example, loading data from an external file, or the format of the data required), but hey, that's a quick and simple solution.

In a handful of minutes, just throw in your and you're good to go.

<script src="d3.min.js"></script>
<script src="topojson.v1.min.js"></script>
<script src="datamaps.js"></script>

Then fill in the constructor with options from DataMaps Docs and set up your first d3 map!

  // Getting the container's dimensions
  var width = document.getElementById('container').offsetWidth;
  var height = document.getElementById('container').offsetHeight;
  // Datamap constructor, fill in the options from the docs
  var map = new Datamap({
    element: document.getElementById('container'),
      fills: {
          YES: '#666666',
          UNKNOWN: 'rgb(0,0,0)',       // These are
          defaultFill: '#CDCCCC'       // the colours
      },
           data: {                     //Place data here
          ARG: {fillKey: 'YES'},
          BEL: {fillKey: 'YES'},
          BRA: {fillKey: 'YES'},
          CAN: {fillKey: 'YES'},
          DNK: {fillKey: 'YES'},
          FRA: {fillKey: 'YES'},
          ISL: {fillKey: 'YES'},
          MEX: {fillKey: 'YES'},
          NLD: {fillKey: 'YES'},
          ZAF: {fillKey: 'YES'},
          ESP: {fillKey: 'YES'},
          SWE: {fillKey: 'YES'},
          GBR: {fillKey: 'YES'},
          URY: {fillKey: 'YES'},
          USA: {fillKey: 'YES'},
          NOR: {fillKey: 'YES'},
      },
    setProjection: function(element, options) {
      var projection, path;
      projection = d3.geo.mercator()                          // The d3 projection
                     .translate([(width/2), (height/2)])      // And some options
                     .scale( width / 2 / Math.PI)
                     .center([-15.652173913043478, 17.2734596919573]);
      path = d3.geo.path()
               .projection( projection );
      return {path: path, projection: projection};
    }
  });

This library is really handy and easy to get started with, that is definitely a product I'll reuse when I'll be in a rush and need a small map.

As an example, here is a quick map of countries accepting same-sex marriage, as of 29 March 2014 (the USA are a bit more complex than that, but I included them anyway).

Oh, and did I tell you that the maps are responsive? That's a huge plus.

Countries accepting same-sex marriage as of 29 March 2014. Source: wikipedia