November 2008

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:


Comments (2)


SMTP port 25 being blocked by my ISP?

Argh. I just discovered that all my out-going email (and my wifes) from the past several days was not delivered. Debugging the issue took a bit of patience, here’s the summary.

All outgoing mail in my home network is relayed to my hosting provider, I use exim4 as the mail-transfer agent, configured via the remote_smtp_smarthost option. It’s been working just fine that way for years…

Well, it looks like my ISP (Comcast) recently decided to start blocking SMTP (port 25) traffic, so all of a sudden, my home network can no longer talk to the SMTP server at Unfortunately, I did not find that out for several days, after Kim and I both received a bunch of “Mail delivery failed messages” like this:

This message was created automatically by mail delivery software.

A message that you sent could not be delivered to one or more of its
recipients. This is a permanent error. The following address(es) failed:
    retry time not reached for any host after a long failure period

After a bit of googling and experimenting with some different exim4 config options, I found this solution, suggesting that SMTP traffic should be sent on an alternate port that Dreamhost set up, apparently for exactly this purpose.

I’m actually not using the ‘split’ config file option for exim4, so I added the port=587 line to my exim4.conf.template instead. Email finally seems to be working again…


Comments (0)


I just started another site:

This is intended to be a set of tools for online genealogy—primarily for publishing genealogies and encouraging collaboration. It is also intended to be open-source.

To start off, I’ll mostly just be writing thoughts and plans via the blog


Comments (2)


Sxipper 3.0 demo

At the November Denver/Boulder New Tech Meetup Dick Hardt demo’d a prototype of sxipper 3.0.

Sxipper leverages your social graph (Facebook, LinkedIn, etc), and shows how it ties in to the larger web in general. For example, he showed how you might browse to a company’s site, and skipper will call out to you that someone in your graph (friend or friend of friend) is somehow connected to the site. Very cool concept.

Seeing Dick also reminded me of seeing his Identity 2.0 presentation at OSCON’05—one of the best presentations I’ve ever seen, in terms of his style. Perhaps dated now, but worth checking out.


Comments (0)