Client-side MVC frameworks usually bind model elements with DOM elements. But for more graphical applications, the view layer cannot be restricted to div and span tags. How can we bind Model elements with SVG charts?
Complex frontend applications require a decoupled MVC architecture, just like for the backend part. Recently, a few frameworks emerged like Angluar, Backbone.js & ExtJs, each with their own benefits. For this article, we've chosen Backbone, both for his maturity and his lightness.
Rahpael.js is a well known library used to display SVG in a web page easily. It encapsulates some methods to draw SVG elements independently of the browser.
Now that we have chosen those 2 powerful components, how can we combine both?
We are going to see this through a simple example: Display a snowman and change the color if its parts when clicking on it. The sownman information will be stored in localstorage to save modifications for the future.
I know it's not the good season to make a snowman but here in France the weather will soon let it be possible.
To do so, we will have to focus on various aspects:
Theses files will be included this way:
We can now use these libraries to draw our snowman.
We will create a Model which will store 3 circles that represents the snowman. It should store the center of a circle, the radius and fill color:
A Backbone collection is created to group our 3 circles:
localStorage property points out the storage method for our collection (here in the localStorage thanks to the
backbone.localStorage library) with a specific name.
Each backbone view needs a DOM element to apply changes on. In our case this element is the same as the SVG container.
initialize() method works like a constructor of the view. Here we retrieve the collection and if it's empty we will store the circles:
Now that we've got our circles, let display them:
We have loaded the collection on the
initialize() method, we can loop on each elements. Raphael's
paper.add() method needs an array of properties (position, radius, length, ...) and the type of shape.
We contruct this array with the retrieved data and add a type 'circle' property.
Handling events on Raphael’s objects is similar to regular DOM events. The key is to keep an association between the Raphael’s object and the DOM element.
To do so, the Raphael element’s id is set on the DOM element.
When catching an event, as it returns the DOM element, we can easily get the Raphael element from its id.
Be sure to handle every case.
In this example, we also deal with click on text tags. The event doesn’t return the text element, but its child (a tspan tag). That's why we get the
raphaelId from the parent’s element.
An alternative would be to use Raphael's event binding methods. But it doesn't use event delegation, and it diverges from the usual Backbone behavior, so we found preferable to stick with Backbone event handlers.
Although Backbone's collections and Raphael sets allow to handle a group of elements, do not get confused about theses.
A Backbone collection handles Backbone models (allowing saving / updating and retrieving them) and a Raphael set aims to group SVG elements to apply transformations on them directly:
A Backbone collection can be converted as a Raphael set the same way as we have done in the
I hope this introduction to the integration of Raphael with Backbone will convince you to make beautiful and interactive masterpieces in SVG.