Today I’m tired of server-side programming.. And yes, I’m looking at you, SQL ! It’s a pain to persist objects naturally when you have complex data structures. And switching to smarter alternatives such as Riak is not an option since I’m coding for $WORK. So I decided to work on something else.
There are a lot of things to explore in my sysadmin world : high availability, security, monitoring, capacity planning, logs correlation, performance tuning, databases, automated deployments, networking, backups, storage, messaging, virtualization, config management, versionning, etc. There are also many subjects on the management or client relations sides : basically it’s everything that is treated under ITIL, including configuration database (CMDB), provisioning, treating support requests/incidents/problems/changes, building reporting/dashboards, contracts, etc.
I don’t love them all the same way. I even hate a few of them because of the stupid way they’re treated. Anyway, I can’t explore all of the remaining ones. These days I’m really passionate about CMDB and config management, and how I can integrate it with the gazillions of tools we use every day. It’s a hard thing, and I think visualizing things is one of the major lack in today tools. There are some cool things in Service-Now though, but I’m not that rich (and the “diagrams” part is not worth the price).
This night, I started to work on a visual output for the CMDB I build these days. I want to be able to build diagrams for the applications I host, at least semi-automatically. They should represent servers, arrows for network traffic, active/passive clustering, and basic components on each server. Later, I plan to make it dynamic so we can display either components, network parameters, physical machine, location, and maybe even integrate it with the monitoring system so that it eases problems resolution. But enough for the dreams.
I started with a basic canvas and some jQuery to make elements “draggable”, with collision detection. I already had boxes, with some piece of code for dynamically drawing arrows between the boxes. Then with ruby and erb, I made it a bit more dynamic (data are in nested hashes/arrays for now, but it could well have been data extracted from a database). I added some intelligence (on the ruby side, maybe I’ll need to port it to javascript) to position elements automatically, depending on the number of elements on the line, and the elements type. Then I added signs to represent active/passive clusters (hearts for heartbeat and “R” for redhat clusters).
Here’s the result for now :

Boxes are auto-positionned, draggable, they cannot collide, and they’re re-drawn with each drag event. Cluster signs don’t follow their boxes though, because boxes in a same cluster are not linked together for now.
But now I have a problem : I’d like to be able to click on links between servers, to group elements, to provide animations… and it seems it’s not that easy with canvas. Tomorrow I’ll try to explore SVG with the awesome raphaeljs library, and see where it leads.
The second problem I have is my (very) limited skills in Javascript. My code is ugly and not so organized, not even tested. It’s mainly because I always find javascript syntax itself ugly. I’ll try to use CoffeeScript as a therapy to build a smarter component, and if it looks good, I’ll put it on Github.
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.