Layout test — experimenting with Raphael

I’ve been looking for a light-weight, cross-platform Javascript library for doing 2D vector graphics. I specifically wanted vector graphics with a full DOM for handling events and such, vs raster graphics (e.g. canvas). I think I found what I’m looking for in Raphael.js.

As a proof of concept, I wrote a little demo app presented here. It uses jQuery + Raphael for the interface, which is just a simple chip floorplan viewer. The boundaries of the various sections of the chip are drawn as rectilinear polygons (layout.js):

LT.prototype._drawBlock = function(g,block) {
  if ( block.path ) return;

  var linewidth = 1;
  if ( this.scale < 1.0 ) linewidth /= this.scale;
   var p = g.path({stroke:'white', 'stroke-width':linewidth+"px"});
   block.path = p;

  var boundary = block.boundary.split(':');
  for ( var i=0, n=boundary.length; i<n; i++ ) {
    var pt = boundary[i].split(',');
    if ( i == 0 ) p.moveTo(pt[0],pt[1]);
    else p.lineTo(pt[0],pt[1]);

  var m = block.m;
  if ( m ) p.matrix(m[0],m[1],m[2],m[3],m[4],m[5]);

  p[0].onmouseover = function() { p.attr({fill:'red'}); };
  p[0].onmouseout = function() { p.attr({fill:''}); };


All the block boundaries are given in chip coordinates, so the whole view has to be scaled to fit in the canvas. All the polygons are drawn as a group, and then the group is translated and scaled to fit (layout.js):

LT.prototype.draw = function() {
  this.g =;

  // Calculate dimensions
  this.bbox.w = this.bbox.x2 - this.bbox.x1;
  this.bbox.h = this.bbox.y2 - this.bbox.y1;
  this.elem_w = this.jq.width();
  this.elem_h = this.jq.height();

  this.scale_w = this.bbox.w / this.elem_w;
  this.scale_h = this.bbox.h / this.elem_h;
  this.scale = this.scale_w > this.scale_h ? this.scale_w : this.scale_h;
  this.scale = (1 / this.scale) * 0.90;

  // Draw block outlines
  for ( var i=0, n=this.blocks.length; i<n; i++ ) {
    var block = this.blocks[i];

  // normalize all drawing to 0,0

  // Scale to fit
  this.g.scale ( this.scale, this.scale );

  // center all drawing in the paper
  this.g.translate((this.elem_w - this.bbox.w)*.5,
           (this.elem_h - this.bbox.h)*.5);

The polygons are given onmouseover / onmouseout handlers to fill them red when hovered, but that is the extent of the interactivity in this example.

The data for the block boundaries is pulled from mysql on the server side. It is all driven by a CGI script written in ruby. I chose this as a simpler alternative to Rails or Merb or Camping—showing the full stack of operations (database queries, template formatting, etc) without much of the hidden ‘magic’ of those frameworks (index.cgi):

class LayoutTest
  def main
  rescue => e
    fatals_to_browser e


  def init
    @cgi ='html3')
    print @cgi.header

  def parse_opts
    @block = @cgi['block']
    @block = 'pcore' if @block.empty?
    @parent = @cgi['parent']

  def read_layout_info
    @instance = {}
    @layout = {}

    instances = query("select * from layout_instance " +
                      "where `cell` = '#{@block}'")
    instances.each do |inst|
      @instance[inst['instance']] = inst

    chillins ={|c| "'#{c}'"}.join(',')
    layouts = query("select * from layout_info " +
                    "where `cell` in ('#{@block}',#{chillins})")
    layouts.each do |lo|
      @layout[lo['cell']] = lo


  def query sql
    rows = []
    sth = @dbi.execute(sql)
    sth.fetch_hash do |row|
      rows << row.dup

The HTML output is generated using ERB. It loads the necessary javascript libraries (jQuery, Raphael, and my own layout code), then generates the necessary calls to LT.block() to define each block to be shown. The raw block boundary data has to be transformed (translated + rotated / mirrored) to account for placement relative to the containing block—that’s all handled in layout.js). The template (index.html.erb):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "">
    <title>layout test: <%= @block %></title>
    <link rel="stylesheet" href="layout.css" type="text/css" charset="utf-8" media="screen,projection"></link>
    <h1>layout test: <%= @block %></h1>
<% if @parent %>
<a href="?block=<%= @parent %>"><%= @parent %></a>
<% end %>
<span id="info"></span>
<div id="layout">
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="raphael.js"></script>
<script type="text/javascript" src="layout.js"></script>
<script type="text/javascript">
var layout = new LT("layout");
<%= layout_block %>
<% @children.each do |child| %>
<%= layout_child child %>
<% end %>

The full code is available here. Not very useful without a database to feed the data, but should serve as a reasonable example: