
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!


