Friday, July 25, 2014

Clickable SVG map

I created QetriX Map with SVG in mind. But I wasn’t pleased about how to make it clickable. It requires Raphaël JS library and it’s not as friendly as I would like.

Wrong.

There’s something called “XLink”, which allows creating hyperlinks within XML documents (therefore in SVG as well).

In HTML you can use . And it works simply like that. Any SVG element works as a link – circle, line, polyline, path and more.

In plain SVG you have to also add a proper xlink namespace xmlns:xlink="http://www.w3.org/1999/xlink" in SVG tag, otherwise you’ll get an error message: “XML Parsing Error: prefix not bound to a namespace”.

Example:


HTML code:

  1. <!DOCTYPE html>
  2. <html>
  3. <body>
  4. <svg version="1.0" width="100" height="100">
  5. <a xlink:href="#ad"><circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" /></a>
  6. </svg>
  7. </body>
  8. </html>

SVG code:

  1. <svg version="1.0" id="svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100" height="100">
  2. <a xlink:href="#c1"><circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" /></a>
  3. </svg>

Anyway, not everything is bright and shiny, working CSS doesn’t mean it will behave the same, as in HTML. SVG has it’s own attributes (background become fill, border become stroke) and doesn’t support those I got used to work with in HTML – like z-index. I’d like to highlight a path by changing stroke color and width, but only part of it is visible. It’s because z-index in SVG is fixed by position of the element in XML, so part of the outline is overlapped by nearby element defined further in the XML. The only way is DOM reordering, which is quite expensive (resources-wide).