D3 – Mapping with D3



D3 – Mapping with D3

0 1


d3-maps

d3-maps presentation

On Github zbskii / d3-maps

D3

Mapping with D3

Created by Brett Carter / @zbskii

I work at Janrain

We do cool stuff. Mostly logins.

Background

I mostly do backend work. Databases, servers, DevOps, etc.

Background

I'm not a JavaScript programmer :)

Ugh...

So once there was a hackathon at work

I wanted to make something cool

Let's build a dashboard!

My team was awesome - Backbone.js, Angular

Within a few hours they had live updating stats, a great design, and a deployable server. What could I do?

I could make a map.

// Create map projection
_projection = d3.geo.equirectangular()
.scale(100)
.translate([width / 2, height / 2])
.precision(.1);
                                    
                                    
// Add the svg
var svg = d3.select('#map').append('svg')
  .attr('width', width)
  .attr('height', height);
                                    
                                    
// Convert projection to a path
var path = d3.geo.path()
  .projection(_projection);
                                    
                                    
// Add the countries via topojson
_g = svg.append('g');
d3.json('js/world-110m.json', function(error, topology) {
  _g.selectAll('path')
  .data(topojson.object(topology, topology.objects.countries)
  .geometries)
  .enter()
  .append('path')
  .attr('d', path);
                                    
                                    

I could show logins on this map.

// Load data from JSON
d3.json('cities_small.json', function(error, logins) {
   if (logins.hasOwnProperty('stat') && logins.stat.fail === 'error') {
       return false;
   }
                                    
                                    
// Bind SVG circles to current data set
var circles = overlay.selectAll('circle')
    .data(logins, function(d) { return [d.lon, d.lat] });
                                    
                                    
// Update the view
circles.enter()
    .append('circle')
    .attr('cx', function(d) {
        return _projection([d.lon, d.lat])[0];
    })
    .attr('cy', function(d) {
        return _projection([d.lon, d.lat])[1];
    })
    .style('opacity', '.5')
    .attr('r', 4)
    .style('fill', '#77B849');
                                    
                                    

Yawn.

Dashboards need to be COOL.

Ok, let's Animate

(D3 makes this crazy easy)

Scorched Earth

// Update the view
circles.enter()
    .append('circle')
    .attr('cx', function(d) {
        return _projection([d.lon, d.lat])[0];
    })
    .attr('cy', function(d) {
        return _projection([d.lon, d.lat])[1];
    })
    .attr('r', 15)
    .style('fill', '#77B849').style('opacity', '0')
     // Animate!
    .transition()
    .style('opacity', '.5')
    .attr('r', 4)
    .style('fill', '#77B849')
    .duration(1000).delay(function(d, i) {
        return i / logins.length * 60000});
circles.exit().remove();
                                    
                                    

Summary

  • Create a projection
  • Use data to bind data element as normal
  • Use the projection to draw data on map
  • Animate it with transition()
  • All this in ~50 lines of JavaScript

Questions?