Posted on March 24, 2006 at 6:21 pm

Graphviz is a nice piece of software that automated the layout of directed or undirected graphs, given a set of connected nodes. Last night I decided to see if I could make a chart of all my ancestors using Graphviz. I didn’t want to have to parse a gedcom file for this, and I already have a database containing all the data I need, so I whipped up something in Ruby. I used the ActiveRecord gem so that I wouldn’t have to write any SQL. It took me about 30 minutes to come up with nice solution and here it is:

require 'rubygems'
require_gem 'activerecord'

ActiveRecord::Base.connection = {
  :adapter => 'mysql',
  :database => 'retrospect',
  :username => 'root',
  :password => ''
}
ActiveRecord::Base.table_name_prefix = 'rgds_'
ActiveRecord::Base.pluralize_table_names = false

class Indiv < ActiveRecord::Base
  set_primary_key 'indkey'
  has_and_belongs_to_many :families, :join_table => 'rgds_children',
                          :association_foreign_key => 'famkey',
                          :foreign_key => 'indkey'
end

class Family < ActiveRecord::Base
  set_primary_key 'famkey'
  belongs_to :father, :class_name => 'Indiv', :foreign_key => 'spouse1'
  belongs_to :mother, :class_name => 'Indiv', :foreign_key => 'spouse2'
end

File::open("/Users/keithm/Desktop/test.dot", "w+") do |file|

  indivs = Indiv.find_all
  file.puts "digraph G {"
  file.puts "node [style=filled, height=1, width=1]"

  indivs.each do |i|
    i.families.each do |f|
      if f.father || f.mother
        shape = (i.sex == 'M') ? 'box' : 'ellipse'
        color = (i.sex == 'M') ? 'lightblue' : 'lightpink'
        file.puts "#{i.id} [shape=#{shape}, fillcolor=#{color}, label="#{i.name}"]"
      end

      if !f.father.nil?
        file.puts "#{f.father.id} [shape=box, fillcolor=lightblue, label="#{f.father.name}"]"
        file.puts "#{f.father.id} -> #{i.id}"
      end

      if !f.mother.nil?
        file.puts "#{f.mother.id} [shape=ellipse, fillcolor=lightpink, label="#{f.mother.name}"]"
        file.puts "#{f.mother.id} -> #{i.id}"
      end
    end
  end

  file.puts '}'

end

You just open up the resulting .dot file with Graphviz and a couple of seconds later you have a huge chart (4Mb). If you open up the full image, don’t be surprised when you find that it’s almost 20K pixels wide!

Leave a comment

You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>