Building an interactive map with jQuery instead of Flash

January 27, 2009
Development

There is an update to this post! Plese visit the new post that has a downloadable, generic plugin.

At the end of last year, we launched a website for Coastal & Marine Sciences in North Carolina with one of our Agency Partners, Liaison Design Group.  As a part of the project, the website was supposed to have an interactive map that showed some information and the location of the various Marine Science outposts across the state. The locations would be represented by dots and upon clicking one an info box would pop up and display information about the location.

JQuery Map Overview

To make the map as engaging as possible, there needed to be smooth animations and crisp graphics.  Traditionally such a project would require the use of Flash. We try to avoid Flash whenever possible, so I began to consider how the project could be accomplished in jQuery.

There were a number of advantages of using jQuery over Flash for the project:

  1. Updates were Easy: Since the map was going to be a visual representation of html, it would be easy to update the data with our Content Management Software. Each location would be a 'page' in the system with contents and attributes like pixel coordinates that would be simple to update.
  2. Content was Search Engine Friendly: Since all of the data was represented in html, it would be easy for search engines to index and spider the content.
  3. Architecture would be naturally layered: All of the data would be stored in a database by the CMS. I would then build html templates for the information that the CMS would display.  jQuery and CSS would then take the html content and display it appropriately.  Each layer would have a natural role so it would be easy to make changes to any individual component of the application without having to worry about the whole thing.

My biggest concern using jQuery was performance.  An important requirement of the project was that the map should zoom when switching between coastal areas.  In Flash this would not be a problem, since transformations like these would be executed at a very low level on computer hardware.  This is not the case with jQuery, instead the DOM would need to be manipulated and then displayed.  I knew that this could be a struggle for less efficient browers like IE6.  Fortunately this turned out not to be a problem in the end.

The Five Locations

The Five Maps

In total, there were five maps that needed to be displayed and roughly 70 location dots.  The artwork for these maps was beautifully done by Liaison. The first map would show the entire NC coast and some of the location dots that were not highly concentrated.  It would also show 4 highlighted areas that could be clicked to zoom in to the other 4 maps where there were more highly concentrated location dots.

In order to simplify the code I had to write, I came up with the following rough procedure to run when one of the five maps was shown:

  1. Load the background image
  2. Load the bullets and info boxes
  3. Place the bullets and hide the info boxes
  4. Attach events to the bullets to display the boxes
  5. Add either the "Return to NC Coast" link or the Zoom-able regions

With this decided, I just need to come up with the markup for each bullet and a couple of jQuery functions to make it all work.

The Bullets and Info Boxes

The bullets and info-boxes for each map would follow a convention that allowed some simple jQuery to link the two together:

 

As you can see, both the bullet link and the info-box have similar ids that can be used to reference each other.  The class of the bullet contains its color and its rel attribute contains its pixel coordinates.  The jQuery to display this on the map and add the info-box event is dead simple:

$(this).children('a.bullet').each(function(){
  var coords = $(this).attr('rel').split('-');
  $(this).css({left: coords[0] + 'px', top: coords[1] + 'px'})
    .hide()
    .fadeIn()
    .click(function(){showPopup($(this).attr('id'));});
});

The showPopup method is simple as well:

function showPopup(id){
  $('#map div.popup').fadeOut(); 
  var boxid = '#' + id + '-box';
  $(boxid).fadeIn();
  $('a.close').click(function(){
    $(this).parent().fadeOut();
  });
}

The code simply relies on the convention between the bullet link id and the info-box id to select and display the box.  At the same time it is sure to close any other infobox popup that may be open.

Handling the Zoomable Regions

When the NC Coast map is displayed, in addition to the location bullets, there are also four zoomable regions. Like the bullets and infoboxes I settled on a naming convention that made the code much simpler.  The id of all of the related elements as well as map images would be derivable from rules.

Since it was important not to load all of the images at once for concern about loading time, I placed and sized a simple blank gif over each of the regions:

$('

').css({
  border: 'none',
  position: 'absolute',
  width: width + 'px',
  height: height + 'px',
  top: top + 'px',
  left: left + 'px',
  cursor: 'pointer'
});

I also attached a click even to this image so that the zooming would occur when the time came:

.appendTo('#map').click(function() {
  $(this).siblings().fadeOut();
  $(this).hide()
    .attr('src', id + '_base.jpg')
    .fadeIn('slow')
    .animate({
      width: '577px',
      height: '418px',
      top: '0px',
      left: '0px'
    }, 1000, '', function(){
      $('#map').css({backgroundImage: 'url(id + '_base.jpg)'}).empty();
      loadBullets(id, true);
    });
});

You'll notice that when clicked, the blank image is swapped for the real one and it is resized to match the map and placed in the top left corner. jQuery's animate function handles these linear transforms with no problem and the map is smoothly scaled into place. It results in a simple yet nifty effect.

Conclusion

In this case, jQuery was a great alternative to Flash. Because of the beautiful artwork, the interactive map looks great with the jQuery animations. The potential performance problem was not an issue and the client is able to have control of the maps content without having to bother a web developer.

It is great to have the opportunity to work on such a fun project in partnership with a talented designer and a client that is as excited about technology as we are. Be sure to head over to the site to check out the final map and learn more about Marine Science in North Carolina.

Comments

 jamie's avatar
jamie

i'll be waiting until your plugin released.

Thanks Joel..

 Bonnie's avatar
Bonnie

Joel,

Great stuff! Are you releasing the plugin this week? I showed a client the example b4 reading you hadn't released it yet - so now I'm sitting on pins and needles ;-)

 Jamie's avatar
Jamie

Nice job.

i wonder,where i can get that plugin and example ??
can someone tell me?
i really appreciate.

Thanks.

 Geoff's avatar
Geoff

Hey there, really really nice alternative to a flashed based solution, would love a copy of the demo files please also. cheers!

 Joel Sutherland's avatar
Joel Sutherland

Brian,

The plugin has not yet been released. I am hoping to wrap it up this week. I'll post it on the blog along with some instructions when I am finished with the writeup and testing.

 Brian Lang's avatar
Brian Lang

Has the plugin been released? Where can I get it?
I've got an outstanding request for one website to build an interactive map, but it's been put on the back burner for a few months. Perhaps this may be what they're looking for. Can you send me a copy of the demo?

Thanks.

 Jason's avatar
Jason

This is pretty cool, good job. Although I would have saved myself the headache of browser testing etc. and just do it in Flash :)

Dmitri's avatar
Dmitri

Hey! Nice!
But there is one problem.
The div with id 'containershadow' (with the map) is below than normal. I see big white space with shadows detached on the right and than the map-container itself.
I'm using FF 3.0.7 on Mac.

 Shawn Dampier's avatar
Shawn Dampier

Wow, fantastic work and thanks for the tutorial - as long as people are asking for the .zip, I would love it as well. Our agency built an interactive map for Germany a few years back that was done in Flash and we encountered all of the same issues you mention. Would have loved to have had this solution then - but going forward, I would built custom maps ala the method you have shown here.
Thanks again for the tutorial.

Mr Brown's avatar
Mr Brown

Yet another person after the zip!

Need a contact map (dont need the zoom)and this looks relly nice. As I dont know squat about flash this is a nice solution.

Thanks heaps

 Padraig Boru's avatar
Padraig Boru

Joel,

You are going to get tired of doing this, but I must ask.

Would you mind also sending me your demo.zip and the instructions?

Thanks in anticipation.

 Joel Sutherland's avatar
Joel Sutherland

Wes,

An email has been sent your way with initial instructions. Be sure to post back here when you've got it running!

 Wes Crockett's avatar
Wes Crockett

Hello,

This is an AWESOME use of jQuery... With your permission, and help by sending a demo zip, I would love to implement this in our schools website to highlight the brand new library that we just opened.

Thank you and way to go!
Wes

 Joel Sutherland's avatar
Joel Sutherland

Steve,

I just sent you an email with some info! Thanks for the comments.

 Steve's avatar
Steve

Wow.. Love it... working with jquery everyday lately - this is one of the best and simple examples of a zoomable map I have ever seen. Great Job! Could you send me a zip also? I want to also play around with dragging a large map around in the window. Will keep you up on my success.

We are working on a community base snowmobile map for the region - I just love your setup!

Cheers!

 Joel Sutherland's avatar
Joel Sutherland

Micah,

Thanks for the comments -- I agree that there are some performance issues with javascript. The next generation of browsers will help that out quite a bit by speeding up DOM manipulations.

You've got a great site!!

 Micah Slavens's avatar
Micah Slavens

We use jquery quite a bit these days in our shop. It is a great alternative to Flash in many cases. However, I do think that it's got a long way to go. The above example, to me, looks much more choppy than a well built flash piece would. It's quite choppy and it doesn't load very quickly.

This is still great work and a good concept, but it may be stretching what Jquery was intended to do.

 Mike Duguid's avatar
Mike Duguid

As a flash developer I have to point out that none of the 3 advantages you list over flash are actually any different to what well developed flash could provide.

# Updates were Easy
A swf map could have it's data fed from flashvars embedded in the html or from a database (or from xml etc), and all image assets would be loaded externally.

# Content was Search Engine Friendly
Google spiders swf content now, but again the important data could be held in the html via flashvars or in alt content (see swfobject alt content)

# Architecture would be naturally layered
All of the data could be read from a database from flash too.
In flash development nowadays most developers have separate text (.as) actionscript files that handle each function so the separation of functionality is the same.

The only real advantage in using jquery is that it doesn't require a plugin.

 Graham Scragg's avatar
Graham Scragg

Thanks so much for blog entry!!
I needed something similar for a client, and was trying to do it with the OpenLayers API, using jquery is so much more intuitive.
I modified your code to allow for dynamic zoomable areas as well as different types of button.
Good work.

 Eric Wendelin's avatar
Eric Wendelin

Good work, but I second Andrew's suggestion of the GMaps API. You could likely have overridden any functions that didn't perfectly suit your needs. Very impressive work as I said, though.

 Joel Sutherland's avatar
Joel Sutherland

@gamma911

I'm sure you could use flash or JS, I found it much quicker to do in jQuery.

To place the bullets, I had the client enter pixel coordinates into our CMS. Even for someone non-technical this is easy to figure out quickly.

 gamma911's avatar
gamma911

Thanks for the tip - look at this site: http://www.visitscotland.com/guide/

I am trying to achieve a similar effect on the map but would like the client to add points to the map without me having to go to flash to do it.

So we will need 3 levels of zoom.

How achievable do you think this is, or should I just stick to flash?
"

Joel Sutherland's avatar
Joel Sutherland NMC team member

@gamma911

Three levels of zoom certainly would be possible. If you poke through the live javascript you'll see I have separate functions for placing the bullets and zoomable regions. You would just need to place more zoomable regions on each of the second level images.

Let me know if you have any questions and thanks for the comment!

gamma911's avatar
gamma911

Well done on the map integration, I would love to do this for one of my projects - my map would have three zoom levels, do you think this would be possible?

 Joel Sutherland's avatar
Joel Sutherland

@Eric

The client adds locations to the map by creating new pages within a section. Each page corresponds to an infobox and a bullet.

To place the bullet, one of the CMS fields is used:
312-50-blue

Where the first two are pixel coordinates and the last is obviously the color of the bullet. The client picked this up quickly and has added a lot of information since we launched.

Leave a comment