Aka canvas / SVG paradox.

This year it will be full 10 years that I officially work for various companies, and i could add 3-4 years of freelancing / solo experimenting to that. Most of that time i spent drawing various data in browser.

I visualiszed almost everything, big data sets, small data sets, real time sensory data, API responses, sql queries, you name it – i draw it. Back when i started, everything was done in server side, and just show in the browser, RRD/Cacti was the pinnacle of chart technology, and the Firefox was the best and fastest browser around. I tried to do some PHP/GD work, but writing both server and client graphics code was too much, even I was junior programmer back then i realised that this was the wrong approach, and tried to move everything to the browser.

Those were early days of JS revolution, prototype was big, and jQuery was the enemy 🙂 Since browsers were painfully slow those days, the majority of the work was in making the browser as fast as possible, so my first experiments were drawing using Js/DOM combo.

Soon enough I had to do some more complex charts and I started exploring, which led me to canvas.

Now, in early days of canvas, browsers were so slow, that you basically used it as a browser equivalent of GD library. Yo would draw some stuff on canvas, and refresh on some (usually 1+ seconds) interval or on some specific user action. Animations were almost impossible, since cutting edge browsers were able to pull 5-15 fps depending on complexity of the code/stuff being drawn.

Fast forward few years, browsers did get quite fast, Firefox started to be quite bloated, and Chrome was released. I remember trying my canvas stuff in Chrome for the first time, and not believing my eyes the responsiveness and FPS I was getting. And with every chrome update it got better and better, so I taught – this is it, this will solve all my problems. But it didn’t.

Then all of the sudden, there was Protovis, it was something completely different, and i was really excited about it, but it had a flaw. To be more precise not only Protovis, but bunch of new graphics/drawing appeared around the same time, and each and every one I tried to use for my scenario ended up ether by blowing my CPU or freezing my machine.

What was my problem? Well it was quite simple, all of my work required of me to draw a lot of data, and to draw it fast. For example, my in my latest work i was drawing scatter plot, but:

– it was interactive scatter plot (each point has name/id which is searchable via search field next to the chart)

– each point had a hover and click action

– you can brush and select rectangle selection of points on chart

So if you ask anyone out there what would they use for this, you would get unanimous response – d3. But d3 didn’t work for me, and it didn’t work for really simple reason – my scatter plot has ~24.000 elements on it. Now you must be thinking, wait there is something wrong, why would someone draw such scatter plot, but if you are in BioIT world, that number is quite normal, since that is approximate number of genes in human. That kind of charts are quite the norm in that industry.

What happens if you try to use d3/svg for that job – your browser dies. To be more precise, anything over 10k elements renders your browser quite unresponsive. So i had to fallback to canvas. I had to implement hit-test, i had to do everything from scratch (as usual). Then, I get the questions like – how do i export this chart into 300dpi resolution. Or, why does this looks blurry on retina display? And we’r back to square one 🙁

If you want to draw a lot of data, you have to use canvas.

If you want yo have vector graphics, you have yo use SVG.

What are you supposed to do when you need both? Good luck to you my friend 🙁

You are about to ether have both implementation, one for drawing and one for vector export, or you are gonna create desktop software. Oh, and if you go for canvas for drawing, don’t forget to scale for different dpi resolutions. (aka retina hell)

There is essential piece of functionality missing in current drawing API’s in the current browser engines:

vector API or at least some kind of abstraction

it shouldn’t be slower than canvas

it should handle different dpi resolutions natively

it should use GPU acceleration when possible

the number of primitives it could draw should be on par with number of polygons that web/openGL can draw on same machine.

Is there any proposal for this kind of API? Is there some other techniques that people are using for this kinds of problems?

update: this post got to Hacker News front page, and there are some great comments there https://news.ycombinator.com/item?id=6423245

update 2, March 2014:

There is great HiDPI canvas polyfill, that will fix most, if not even all your problems with canvas on retina! Really love the project, great work!