Canvas or SVG

The choice is not easy in this case…

EDIT: just a quick note, it’s not an other SVG vs Canvas comparison. My “Canvas” version uses pure HTML+jQuery things so there’s a bias I’m totally aware of.

Recently I blogged about an experiment I was making for building logical maps of an application architecture, e.g. servers, components, arrows to represent relations between servers, etc. It was built with HTML’s Canvas and dirty Javascript code, but I was pretty sure I would switch to CoffeeScript and SVG (with RaphaelJS library).

After a day of work, I have started the switch to CoffeeScript and Jasmine. It’s not finished yet, but it’s moving fast, no problem on that side. All the code is now pure client code, I’ve migrated the few functions I had in Ruby/ERB to Javascript. I even started to tweak and read a Cakefile (doc) to ease build actions and organize my code. I’m really impressed with CoffeeScript so far, it’s amazingly concise and has some high-level concepts to make Javascript easier. Feels good !

On the SVG side, I’m not that happy. I managed to have the basic things working :

  • draw boxes
  • position boxes automatically
  • put text in each box
  • make boxes draggable
  • draw links dynamically between related boxes

Here’s a screenshot of the result :

But I miss a lot of things :

  • collision detection ? seems I have to write my own
  • grouping management ? same, SVG doesn’t support it, so I had to write some basic stuff to make pieces of text move with their box
  • text flow ? nothing, so I have to fix height manually on boxes
  • styling elements : SVG doesn’t rely on CSS (I can retrieve properties and translate them, but it’ll be tiresome)
  • can’t style rectangle borders under 2px (it’s ugly)

On the other hand, it comes with good things that I won’t have with Canvas :

  • drag/drop work on iPhone/iPad
  • vectors : you keep high-quality rendering when zooming
  • animations : not useful now, but maybe later
  • everything is an object, so I won’t have to re-draw the whole map when there’s a change

The repo is finally on github and you can watch a live demo here where both methods are displayed side by side : Canvas on the left, SVG on the right.

Now I don’t really know what to do. Everything would be easier if you could embed HTML trees in an SVG element, but it’s not possible by default. I started to play with a Raphael plugin called Infobox so I keep HTML for representing servers. The idea would be to manage a grid and the boxes only with SVG, and have HTML embedded in it so it solves styling/flow problems. It works with some effort, but it starts to become pretty complicated, and there are still a lot of problems to solve.

It seems there’s no magical solution in the SVG/Canvas world (for now). Any suggestion would be welcome.