A graphical toolkit for visualization
Protovis
Overview
Examples
Documentation
Download
Index
« Previous / Next »

Map Projections

View full screen.

Although the Mercator projection is perhaps the most familiar, many different map projections exist to map the Earth's spherical surface to a two-dimensional image. Each projection introduces some type of distortion; for different purposes, some distortions may be more desirable. This example is another choropleth map, showing population density map of the world's countries. Use the drop-down menu to compare several projections supported by Protovis.

Next: Heatmaps

Source

<html>
  <head>
    <title>Choropleth Map</title>
    <link type="text/css" rel="stylesheet" href="ex.css?3.2"/>
    <script type="text/javascript" src="../protovis-r3.2.js"></script>
    <script type="text/javascript" src="countries.js"></script>
    <style type="text/css">

#fig {
  width: 860px;
  height: 550px;
}

    </style>
  </head>
  <body><div id="center"><div id="fig">
    <div align="right">
      <b>Projection:</b>
      <select id="menu" onchange="geo.projection(this.value); vis.render();">
        <option value="none">Identity projection</option>
        <option value="mercator">Mercator projection</option>
        <option value="gall-peters">Gall-Peters projection</option>
        <option value="sinusoidal">Sinusoidal projection</option>
        <option value="hammer" selected>Hammer projection</option>
      </select>
    </div>
    <script type="text/javascript+protovis">

/*
 * A diverging color scale, using previously-computed quantiles of population
 * densities; in the future, we might use a quantile scale here to do this
 * automatically. Map colors based on www.ColorBrewer.org, by Cynthia A. Brewer,
 * Penn State.
 */
var fill = pv.Scale.linear()
    .domain(140, 650, 1900)
    .range("#91bfdb", "#ffffbf", "#fc8d59");

/* Precompute the country's population density and color. */
countries.forEach(function(c) {
  c.color = stats[c.code].area
      ? fill(stats[c.code].pop / stats[c.code].area)
      : "#ccc"; // unknown
});

var w = 860,
    h = 3 / 5 * w,
    geo = pv.Geo.scale("hammer").range(w, h);

var vis = new pv.Panel()
    .width(w)
    .height(h);

/* Countries. */
vis.add(pv.Panel)
    .data(countries)
  .add(pv.Panel)
    .data(function(c) c.borders)
  .add(pv.Line)
    .data(function(b) b)
    .left(geo.x)
    .top(geo.y)
    .title(function(d, b, c) c.name)
    .fillStyle(function(d, b, c) c.color)
    .strokeStyle(function() this.fillStyle().darker())
    .lineWidth(1)
    .antialias(false);

/* Latitude ticks. */
vis.add(pv.Panel)
    .data(geo.ticks.lat())
  .add(pv.Line)
    .data(function(b) b)
    .left(geo.x)
    .top(geo.y)
    .strokeStyle("rgba(128,128,128,.3)")
    .lineWidth(1)
    .interpolate("cardinal")
    .antialias(false);

/* Longitude ticks. */
vis.add(pv.Panel)
    .data(geo.ticks.lng())
  .add(pv.Line)
    .data(function(b) b)
    .left(geo.x)
    .top(geo.y)
    .strokeStyle("rgba(128,128,128,.3)")
    .lineWidth(1)
    .interpolate("cardinal")
    .antialias(false);

vis.render();

    </script>
  </div></div></body>
</html>

Data

Due to size, the data file is omitted from this example. See countries.js.
Copyright 2010 Stanford Visualization Group