🕷 zenspider.com

by ryan davis



sitemap
Looking for the Ruby Quickref?

Stoopid Simple Graphing Library

Published 2005-02-24 @ 18:40

Tagged ruby, toys

At Eric’s behest, I’m releasing the code that I used to generate the ABC colored graphs that I posted about earlier. It allows for quick and dirty (I prefer the term “clean”) graphs through Graphviz’s dot language.

1
2
3
graph = Graph.new
graph["from"] << "to"
puts graph.to_s

when processed becomes:

graph.png

It has other bells and whistles, when a plain graph just won’t do, but the emphasis is on simplicity and getting things done. Best of all, it is only 65 lines long.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#!/usr/local/bin/ruby -w

class Graph < Hash

  attr_reader :attribs
  attr_reader :prefix
  attr_reader :order
  def initialize
    super { |h,k| h[k] = [] }
    @prefix = []
    @attribs = Hash.new { |h,k| h[k] = [] }
    @order = []
  end

  def []=(key, val)
    @order << key unless self.has_key? key
    super(key, val)
  end
  
  def each_pair
    @order.each do |from|
      self[from].each do |to|
        yield(from, to)
      end
    end
  end
  
  def invert
    result = self.class.new
    each_pair do |from, to|
      result[to] << from
    end
    result
  end

  def counts
    result = Hash.new(0)
    each_pair do |from, to|
      result[from] += 1
    end
    result
  end
  
  def keys_by_count
    counts.sort_by { |x,y| y }.map {|x| x.first }
  end

  def to_s
    result = []
    result << "digraph absent"
    result << "  {"
    @prefix.each do |line|
      result << line
    end
    @attribs.sort.each do |node, attribs|
      result << "    #{node.inspect} [ #{attribs.join(',')} ]"
    end
    each_pair do |from, to|
      result << "    #{from.inspect} -> #{to.inspect};"
    end
    result << "  }"
    result.join("\n")
  end
end