Making Better Maps With SVG

Fairly recently I was given the opportunity to work on mostly the front-end of a product/service that consisted of atrociously legacy, poorly written vb.net code and no clear direction. This is my attempt at sharing what I learned.

Make the app responsive

Ignoring the ridiculous way my task was described, the most significant part of the front-end of this application was the ability to view pages of a catalog and interact with them. These pages were scanned or otherwise saved in a digital form, then displayed as large images on the web. The interactive part was provided in the form of image maps which were manually constructed by a person hired to draw them in a very old copy of Photoshop and then export the code which was then saved as raw HTML in a database. Everything about this bothered me.

  • The images represented scanned pages of large print catalogs.
  • The existing interface only considered screens that were about 1000px wide or so. No proper consideration for small screens.
  • No solution for a better input method None of the existing interface code could be re-used, but the general style and content could be.

Technical Requirements

  • Invisible polygons needed to be displays over top of the pages
  • The polygons needed to be positioned at all times relative to the constraints of the image below
  • The polygons needed to be clickable and link externally
  • No changes to data entry workflow could be changed
  • Most of the backend needed to stay unchanged

Sane requirements

  • Needed to be affected by CSS

Initially, I gave the problem some thought and came up dry on an approach that would handle these requirements well.

Curious about the obvious question: “Why don’t <map>’s solve this problem?”, I tested them.

Testing <map>s

When I came on, the app was in a weird state. There wasn't an interface that you would describe as responsive, but there was some strange effort to force the interface into a weird state of an incredibly ugly implementation of a desktop image based …fluid layout of some sort. The images I was dealing with scaled with the browser but it really didn't make sense given the rest of the layout and didn't attempt to actually provide value.

Still, the image maps themselves scaled proportionally with the images and the screen.

Why aren't image maps responsively capable?

  • Reliance on initial markup to set the spatial constraints of the coordinate plane
  • Lack of re-calculation of vertices if the coordinate plane changes

Why else do they suck?
Turns out, image maps only serve exactly the requirements of this particular type of interface. They don't accommodate any changes whatsoever. Want to style the polygons? Outta luck. Want to bind events to the elements? Maybe. I didn't test that extensively because I couldn't really think of a reason that would be useful. I suppose theoretically if you did get that working, you could bind clicks to address changes and subsequently change views or something with the location api. Don't try inspecting them as elements in dev tools, because that is only what they seem to be. In reality they are just coordinate mappings, though they do have real markup.

So how about a solution?

Use SVG

At first I couldn't think of a way to handle this. Drawing arbitrarily complex polygons transparently, with external links, and ideally styleable? You might not think of SVG either because typically it's used for drawing things rather than not drawing things. However it seems to excel at both, and when it comes time to do something with it you can.

Comparing the capabilities of image maps to what is possible with the SVG Api the only real work needed to be done to allow SVG to hypothetically fit into our workflow was the transformation of exisiting image map data, such as coords, into the various pieces of information needed to render the same <area> as a <poly> or <rect>. I wrote a pretty shallow abstraction library to handle this and as a nice side effect get progressive enhancement for free. Browsers that don't support SVG can be allowed to render image maps if you so choose.

In summary, the benefits of SVG are great. Below are some of the technical differences in capabilities between SVG and legacy maps.

Maps

  • Ability to create polygonal shapes based on the coordinate plane of an associated image
  • The shapes are invisisible and can't be otherwiser styled.
  • The shapes can link to things
  • No responsiveness

SVG Elements

  • Can create polygons
  • Polygons can link to things
  • Polygons can be styled with CSS or be transparent
  • Full scaling capability built in
  • No association with actual images. Use an image to set the viewBox or don't. Draw your whole map with just SVG if you want.
  • Solid JavaScript API