Using RaphaelJS To Create A Map

/ Javascript, jQuery / by Paul Robinson / 115 Comments
This post was published back on June 27, 2011 and may be outdated. Please use caution when following older tutorials or using older code. After reading be sure to check for newer procedures or updates to code.

The brief was actually quite simple. Create an interactive map of the United Kingdom split into regions that when hovered would show a small pop-up containing the name of the region, and when clicked would take you to a specific page. In this case it was to be a term archive page for a specific taxonomy inside WordPress, but it could really be anything (within reason).

I have received permission from the client I did the work for to use the map in this tutorial so here is a demo to show you what the finished product looks like.

Happy? Good. Now let’s start with what could be the most important part of this tutorial.

Prerequisites

You need to grab yourself an image of the map, item, or whatever it is you want to create with RaphaelJS. Not just any image though, it must be an SVG or a Scalable Vector Graphics file. For those that haven’t heard of an SVG before, it is basically an image that is created using Mathematical equations meaning it can be scaled to any size without degradation since all the computer has to do is recalculate the results to the equations.

This can be exceptionally confusing to some so here is a visual example of how vector graphics, like SVG, differ from raster graphics, like JPG or Bitmap.

As you can see, when you scale up a raster image you start to lose detail & the image starts to degrade quite badly. However the vector image stays extremely detailed and doesn’t degrade at all.

I can’t share the image I used to make the map, but there are a lot of SVG maps & other SVG images available from Stock Photo sites such as IStockPhoto.com.

HTML

Now we can move on to some actual code. First the HTML used.

Ahem. Yep, that’s it. No other HTML code is needed. The rest is all RaphaelJS.

RaphaelJS

First thing, we need to make sure jQuery is attached to the page. RaphaelJS doesn’t need jQuery, but it does help a lot to have the jQuery core functions available when using Raphael. I always use the Google CDN but you can attach it by any method you like. You also, obviously, need RaphaelJS attached to your page. You can download it from the RaphaelJS website. You will also need a small patch/plugin for RaphaelJS that creates a Pop-Up using vector graphics. I can’t remember where I found this but here is the code:

It has been minified, all you need to do is paste it onto the bottom of your RaphaelJS file that you downloaded from the RaphaelJS website, or you can put it in another JS file and attach it separately. I leave it to you.

Okay. First we need to make a path file. This file will contain the path data to create our map. Where do you get this data from? Well your just open up the SVG file in your favorite text editor (I use Notepad++). SVG files are actually just XML files, since the SVG file format is XML based. If the image has had each part grouped together when it was created you should be able to easily find the different parts you need. Here is an example of how my SVG file looked.

The highlighted areas are the important parts. The first is the name of group, this helps you identify which part of the image this code draws. The second highlighted part is the path data which is what you are looking for. You will need to copy the information between the d="". Remember though that you need the data (d=””) from every path element inside that group to create that group. This may involve joining lots of path elements together. To do that just join them together & leave a single space between each one.

There is an alternative though. Eric in the comments to this tutorial has kindly pointed out that there is a small web app that will take your SVG file & pump out the needed RaphaelJS code to make it. Kinda cool!

Now let’s get to what you need to do with that code. The easiest way to build a large image such as a map is to store the path data in a separate file as an object.

So create a file called path.js and place this inside:

This is the start of your path data file. You should have your first piece of path data in clipboard, so let’s use it.

So in our example here item would use the path data from the first group (<g id="">) element in our SVG file, and item2 the second and so on. That would normally be it, but we want to have a popup display something & we want links that go somewhere when clicked. To do that we store our data inside this JS file. So here is an example:

As you can see, info is the text the popup will show, URL is where the area of the map goes to when clicked, and path is still just the path data.

Now you just need to fill up the path file with all your path data. It can take a while but stick at it. Once you’ve done that we can continue on to our initialization code.

I keep the initialization code inside a file called init.js (original, I know) but you can easily just place it on the HTML page if you like. Let’s take a look at it before we go through it.

I know it looks complicated, but let’s try and go through it piece by piece and see if we can’t make sense of it. First off we’ll ignore the jQuery DOM ready, I’m using the No Conflict version since this was created for a WordPress based website.

Okay. First we create the canvas or paper, the parameters are the ID of the element you would like the image to be created in, and the width & height of the image. The width & height can be found in the top of the SVG file (when it’s open in a text editor) or by opening it in your favorite vector illustration program such as InkScape or Illustrator. Next we run a special fix built into Raphael to counteract a rendering problem sometimes apparent in Safari, and finally we create a popup and hide it straight away. We will use the popup a little later.

These two lines are fairly simple. The first sets up our fill color, stroke color, stroke width & how the stroke lines should be joined. The second just creates an empty array to be used a little later.

Okay this last section can get complicated. First we start a loop that goes through each item inside our path object (remember from our path.js file). We then create a path using the path data, this is stored in a variable called p. Now we store a reference to the current item inside that empty array using the ID of the current path as the key, this is to help us gain access to the data (info, url etc) we stored in the path.js file. Next we tell our newly created path what color it should be using the attributes we set earlier.

Next we add some event listeners to our path. The first is hover. On hover we animate our new color in, you could do anything you like at this point but this is the effect my client was after so I stuck with it. Next we grab the width & height information for the current path and store it in bbox. Now we setup our popup, first we set the text using the data from our path.js file, then update the position using the paths ‘x’ position & it’s ‘y’ position plus half it’s height. This will make the popup appear to the left horizontally but central vertically when it is displayed on the map. We then set it to be in front of everything & to finally show. The last part of the hover is to restore the original color & hide to popup when the mouse leaves. The click function is optional and sends the browser to the URL you set inside the path.js file.

Despite the code not being very large, to those who haven’t used Javascript much I can imagine it is daunting to look at. I’ve tried to explain it as best I can without it becoming confusing, but I doubt I’ve answered every possible question you have. If you do have a question or you need me to explain something in a little more detail, please let me know via the comments below. Also I’m am currently available to do small jobs in WordPress and sometimes other small jobs (jQuery, PHP etc) please send me an email via the contact form or via admin [at] gmail [dot] com if you are interested, no large scale jobs at the moment please as I just don’t have the time available at the moment to commit to them.

115 Comments

Author’s gravatar

Paul,
Awesome tutorial! Is there any way to change the color of the countries to different colors? For example if I hover over Ireland the color is blue and then hover over Scottland the color is red.

Thanks!

Reply
Author’s gravatar author

Hi joy,

The best way to do that would be to add a color into your Path file with the other attributes & just pull it out when creating each country and apply it to that part. So for example if you stored the color in a property called ‘color’, along with the url etc you might change the p.hover code to:

Just remember the color will need to be a hex color value.

Author’s gravatar

It was a great tutorial, Thank you very much it is working great for me.
I want to display the country name all time inside shape and in popup I will display description. please suggest me

Example in init.js:
name: “Something To Show inside shape all the time”,
info: “Something For The PopUp To Show”,
url: “http://link.com”,
path: “Path data still here”

Reply
Author’s gravatar

Hi Paul,
I know it’s been forever ago since this tutorial was posted but it was incredibly helpful for me just recently, so thank you!
I actually had the same question as Matt, about wanting to fill each country with different colors and I managed to do so with the code you provided for him, using the switch. However, the thing I can’t figure out is how to leave the color of each country just as it was before the hover action. As it is right now: country1 is originally yellow, I hover and change it to blue and it doesn’t return to yellow after leaving the mouseover, it just takes the default color value of the switch. Do you think you could help me with that? Thank you again!

Reply
Author’s gravatar author

Hi Evan,

Sorry for the delay in getting back to you.

Looking back the code I originally posted for Matt should do that. If placed in the correct places in the code it should initialise the map with the non-hover color, then show the hover color on hover and then return to the non-hover color. Could you post your code on Pastebin or something similar? If you can’t post it publicly then feel free to drop me an email via the contact form instead.

Also apologies for some of the layout mess in these comments. I’m busy building a new theme that will make things a lot nicer and more readable. It will be ready soon.

Author’s gravatar

Hi Paul,

I am trying to implement a USA map showing regions like – north east, south east, middle atlantic, moutain, pacific etc instead of individual states. Can you please let me know how can this be achieved? Appreciate your help. Thanks.

Reply
Author’s gravatar author

Hi,

That’s a complex question, but the general steps would be the same. The trickiest part would be to find the map. If there isn’t a map available that is already split up in the way you’d like you’d need to grab a map of the USA and then use an vector editing program like Inkscape (or Illustrator) to add in the regions manually.

The rest of the code should be similar if not the same since the paths your take from the SVG determine what is drawn.

Hope that helps a little.

Newer Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

I'll keep your WordPress site up-to-date and working to its best.

Find out more