*

Creating an interactive map with SVG

Created by Jonathan Petitcolas / @Sethpolma

Creating maps, the old way

Edward Arthur Walton

Using Flash

Sample: www.inaxys.com

France map using Flash

Using HTML map tag

Sample: www.planete-maison-de-retraite.fr

France map using HTML map tag

Code source not for the faint-hearted!

Let's give SVG a try!

SVG Logo SVG

SVG: Scalable Vector Graphic

SVG beer PNG beer

A skilled technology

  • Good looking, whatever zoom or resolution
  • Maintened by W3C SVG Working Group
  • Royalty free
  • Editable even with Notepad, no need of expensive editor
  • Interpreted language, no very famous "where did I put the source" issue
  • True XML: interoperability, Unicode support, mixing well with webservices, etc.

Helped by Raphaël.js

Created with Raphaël 2.1.2

Lot of examples on raphaeljs.com

Let's create a modern map

Bootstraping Raphaël.js

<!DOCTYPE html5>
<html>
  <head>
    <meta charset="utf-8" />
    <title>France regions map in SVG with Raphaël.js</title>
  </head>
  <body>
    <div id="map"></div>
    <script src="js/raphael-min.js"></script>
    <script src="js/map.js"></script>
  </body>
</html>
var MAP_WIDTH  = 620;
var MAP_HEIGHT = 600;

var mapContainer = document.getElementById("map");
var map = new Raphael(mapContainer, MAP_WIDTH, MAP_HEIGHT);

Drawing our first region

var style = {
  fill: "#ddd",
  stroke: "#aaa",
  "stroke-width": 1,
  "stroke-linejoin": "round",
  cursor: "pointer"
};

map
  .path("m 69.78125,123.21875 /*...*/ -1.15625,-2.71875 z")
  .attr(style);

Several line joins available:
SVG line joins

Drawing our first region

Retrieving these creepy coordinates

m 390.125,86.53125 -1.375,2.25 -1.75,1.15625 -1.375,-1.34375 -2.9375,0 -0.5625,-0.78125 -1.96875,3.6875 -0.78125,1.375 2.34375,2.9375 -0.78125,3.90625 -2.15625,1.75 0.21875,1.375 0.75,1.9375 -1.15625,1.1875 -2.34375,1.15625 0.375,2.15625 1,0.1875 -1.75,1.5625 1.34375,2.9375 1.375,4.3125 -1.75,1.9375 3.125,-0.1875 -1.5625,4.875 -2.15625,0.96875 -1.1875,2.9375 1.1875,0.96875 -1.375,2.34375 0.40625,1.5625 3.71875,2.9375 0.1875,6.84375 4.09375,0.59375 2.53125,2.71875 4.6875,2.34375 1.75,0.59375 4.125,4.5 -1.75,1.75 1.34375,1.9375 3.125,0.21875 2.75,3.6875 2.34375,0 0.5625,2.5625 2.5625,0.375 0.5625,1.75 -1.75,1.1875 -1.15625,5.28125 5.46875,2.71875 0,4.09375 2.125,-0.78125 1.78125,1.40625 1.34375,-0.8125 -0.75,-1.15625 0.96875,-0.59375 1.34375,1.5625 1.96875,-1.375 0.59375,-1.9375 3.6875,-0.59375 1,0.78125 -0.1875,2.15625 2.53125,1.9375 1.5625,-0.1875 1.75,-1.375 4.09375,0 2.9375,3.3125 0.96875,0 1.5625,-0.96875 0.21875,-1.15625 1.5625,-0.78125 1.75,1.15625 1.75,1.96875 6.15625,3.25 2.4375,-2.09375 0.1875,-7.625 3.34375,-2.90625 1.9375,-4.5 -0.59375,-2.9375 2.34375,-4.6875 2.15625,-4.875 L 459.25,155 l -0.78125,-5.28125 0.78125,-3.53125 -1.375,-1.34375 2.15625,0.1875 3.90625,-3.90625 1.1875,-4.09375 -1.5625,-1.5625 -0.1875,-1.375 2.3125,-4.3125 -5.4375,-3.125 -3.125,2.34375 -1.78125,-1.15625 0.78125,-1.75 -1.9375,-1.375 -2.5625,-1.1875 0,-2.53125 2.5625,-0.78125 0.96875,-4.5 1.75,-1.9375 0.78125,2.9375 2.15625,0.96875 3.71875,0.59375 1.9375,1.9375 2.34375,0 1.96875,-1.375 2.53125,1.78125 1.375,0 1.5625,-1.375 0,-2.9375 1.71875,-3 -0.40625,0.125 -1.34375,-1.9375 -3.90625,-2.34375 -1.375,-2.15625 -4.6875,0.40625 -2.75,2.53125 -6.625,0.1875 -1.96875,-1.375 c -0.13199,-0.23943 -1.09313,-1.93562 -1.9375,-2.40625 -0.0327,-0.0174 -0.0865,-0.0457 -0.125,-0.0625 -0.0285,-0.0117 -0.0699,-0.0243 -0.0937,-0.0313 -0.0107,-0.005 -0.0512,-0.0255 -0.0625,-0.0313 -0.003,1e-5 -0.0278,-1.4e-4 -0.0313,0 -0.025,-10e-4 -0.0737,0 -0.0937,0 -0.91552,1e-5 -2.6881,-1.0275 -2.90625,-1.15625 l -2.75,1.15625 -0.1875,2.34375 -3.3125,0.40625 -1.96875,-3.71875 -1.15625,-0.40625 0,-2.71875 -2.75,-1.1875 -0.1875,-4.6875 -1.96875,-1.9375 -4.09375,-1.96875 -1.9375,0 -0.59375,0.40625 -1.96875,0 -2.71875,-2.34375 -2.9375,0.1875 -2.34375,1.96875 -0.59375,0.96875 -3.3125,0 -1.15625,-1.1875 -3.125,0 -3.53125,-3.90625 -4.5,0 -2.34375,2.15625 -3.3125,0.1875 -1.15625,1.1875 -1.1875,0 -0.7813,-3.71865 -1.5625,-1.5625 -1.125,-0.15625 z

(Vital) tip: copy/paste picture XML. For instance, from Wikipedia.

Drawing the other regions

SVG and DOM events

Adding hover effect

var animationSpeed = 500;
var hoverStyle = {
    fill: "#A8BED5"
}

for(var regionName in regions) {
    var region = regions[regionName];

    region[0].addEventListener("mouseover", function() {
        region.animate(hoverStyle, animationSpeed);
    }, true);

    region[0].addEventListener("mouseout", function() {
        region.animate(style, animationSpeed);
    }, true);
}

Resulting map

Got you! Closure required!

for(var regionName in regions) {
    (function (region) {
        region.attr(style);

        region[0].addEventListener("mouseover", function() {
            region.animate(hoverStyle, animationSpeed);
        }, true);

        region[0].addEventListener("mouseout", function() {
          region.animate(style, animationSpeed);
        }, true);

    })(regions[regionName]);
}

Working resulting map

Any questions?*

Questions?

*: except region localization questions

THE END

Creating a clickable SVG France regions map
www.jonathan-petitcolas.com