svgpngmapsvisualizationprotovis

Best way to serve / produce silhoutte of the US States?


I'm responsible for delivering pages to display primary results for the US elections State by State. Each page needs a banner with an image of the State, approx 250px by 250px. Now all I need to do is figure out how to serve / generate those images...

  1. I've dug into the docs / examples for Protovis and think I could probably lift the State coordinate outlines- I would have to manually transform the coordinate data to be justified and sized properly (ick)

  2. At the other end of the clever/brute spectrum is an enormous sprite or series of sprites. Even with png 8 compression the file size of a grid of 50 non-overlapping 250x250px sprites is a concern, and sadly such a file doesn't seem to exist so I'd have to create it from hand. Also unpleasant.

Who's got a better idea?

Answered: the right solution is to switch to d3.

What we hacked in for now:

 drawStateInBox = function(box, state, color) {
   var w = $("#" + box).width(),
           h = $("#" + box).height(),
           off_x = 0,
           off_y = 0;
           borders = us_lowres[state].borders;

   //Preserve aspect ratio
   delta_lat = pv.max(borders[0], function(b) b.lat) - pv.min(borders[0], function(b) b.lat);
   delta_lng = pv.max(borders[0], function(b) b.lng) - pv.min(borders[0], function(b) b.lng);

   if (delta_lat / h > delta_lng / w) {
     scaled_h = h;
     scaled_w = w * delta_lat / delta_lng;
     off_x = (w - scaled_w) / 2;
   } else {
     scaled_h = h * delta_lat / delta_lng;
     scaled_w = w;
     off_y = (h - scaled_h) / 2;
   }

   var scale = pv.Geo.scale()
           .domain(us_lowres[state].borders[0])
           .range({x: off_x, y: off_y},
           {x: scaled_w + off_x, y: scaled_h + off_y});


   var vis = new pv.Panel(state)
           .canvas(box)
           .width(w)
           .height(h)
           .data(borders)
           .add(pv.Line)
           .data(function(l) l)
           .left(scale.x)
           .top(scale.y)
           .fillStyle(function(d, l, c) {
             return(color);
           })
           .lineWidth(0)
           .strokeStyle(color)
           .antialias(false);

   vis.render();
 };

Solution

  • d3 seems to have the capability to do maps similar to what you want. The example shows both counties and states so you would just omit the counties and then provide the election results in the right format.