Hey friends! I gave in and finally integrated <canvas> support into JSViz, and just in time for the Safari 3 Beta (which I’m really digging so far)!
Note: To render with canvas, you’ll need Firefox 1.5, Safari 2.0, or Opera 9. JSViz gracefully degrades to alternative rendering platforms (SVG, HTML) when support is not present.
One more note: I’ll add VML support to this demo shortly. I’m just waiting on the next build of svg2vml.
I’ve been reluctant to integrate canvas support into JSViz, so let me explain why this has been a long time coming.
HTML, SVG, and VML each similarly represent drawings as a set of “elements”. In HTML these elements include DIVs and TABLEs, and in the SVG/VML these include circles, rectangles, and complex paths. In terms of time and system resources, creating elements is expensive, but once we place an element in the DOM we can change it’s position and other characteristics with less overhead. Over the lifetime of a graph we may change the position of an element 100s or 1000s of times, so we want to minimize the cost of these operations. DOM updates and rendering are the primary inhibitors to scaling JSViz past 100 or so nodes per graph.
Canvas works differently than these other graphics platforms. Once we draw on the canvas, we can’t change what we’ve drawn. We can only draw more or clear the canvas. So if we draw a node at one set of coordinates and then want to move it to another, we have to clear the whole canvas and redraw. Also the drawing operations are rather primitive. Canvas supports lines, rectangles and arcs, but that’s about it. Even basic drawings can require many operations.
In short, this means that JSViz needs to redraw every node and edge in the graph at each cycle in the organization, even if the node didn’t move. I’ve been skeptical about canvas’ ability to keep up, but it turns out that it really kicks! Check out this first person shooter written for canvas. So I’m sold. This is my first pass at integrating canvas support into JSViz.
I’ll gladly take feedback on the API. In the current implementation, each node view is represented by a function. From the demo, here’s a view function that draws a node as a circle with a radius of 6pixels, filled with the indicated color attribute. “this.node_twod” is the local name for the canvas’ 2d context.
function(particle) {
this.node_twod.strokeStyle = dataNode.color;
this.node_twod.fillStyle = dataNode.color;
this.node_twod.beginPath();
this.node_twod.arc(
(particle.positionX*this.skewX) + this.centerX,
(particle.positionY*this.skewY) + this.centerY,
6, 0,
Math.PI*2,true); // Outer circle
this.node_twod.stroke();
this.node_twod.fill();
}
JSViz 0.3.4 is brewing, and canvas support will be included. Lorien and I will be posting over the next few weeks with updates as we prepare a release.