require 'graphviz' module Hanuman class Graphvizzer attr_accessor :hanuman_graph, :visual def initialize(hanuman_graph) @hanuman_graph = hanuman_graph @visual = GraphViz.new(@hanuman_graph.label, :type => :digraph) end def create hanuman_graph.directed_sort.each{ |stage| visual.add_nodes(stage.to_s) } hanuman_graph.links.each{ |link| visual.add_edges(link.from.to_s, link.into.to_s) } visual.output(:png => 'test.png') end end end # module Hanuman # module Graphvizzer # include Gorillib::Builder # class Item # include Gorillib::Builder # alias_method :configurate, :receive! # field :name, Symbol # field :label, String, :default => ->{ name } # field :owner, Item # def initialize(attrs={}, &block) # receive!(attrs, &block) # end # def depth # owner.depth + 1 # end # def indent(adj=0) # " " * (depth + adj) # end # def quote(str) # return str if str.to_s.include?('"') # %Q{"#{str}"} # end # def line(str, attrs={}, term=';') # if attrs.empty? # attr_strs = '' # else # width = 40 - indent.length # str = "%-#{width}s" % str # attr_strs = attrs.map{|attr, val| attrib(attr, val) } # attr_strs = "[ #{attr_strs.join(",")} ]" # end # [indent, str, attr_strs, term].join # end # def attrib(attr, val) # "#{attr} = #{val}" # end # def brace(str) # "#{indent}#{str} {" # end # def close_brace # "#{indent}}" # end # def pad_with_attributes(text, attrs=nil) # width = 40 - (2 * graph.depth) # if attrs then # attr_strs = attrs.map{|attr, val| attribute_str(attr, val) } # "%-#{width}s [ %s ]" % [text, attr_strs.join(',')] # else # text # end # end # end # class Node < Item # field :inslots, Array, :default => [] # field :outslots, Array, :default => [] # field :shape, Symbol, :default => :Mrecord # def graph_attribs # { # :shape => shape, # :label => quote(shape =~ /record/ ? structured_label : label), # # :fixedsize => true, :width => "1.0", # } # end # def inslots_str # inslots.map{|slot| "<#{slot}>#{slot[0..0]}"}.join("|") # end # def outslots_str # outslots.map{|slot| "#{slot[0..0]}"}.join("|") # end # def label # super.to_s.gsub(/_\d+$/, '').gsub(/[_\.]+/, "\\n") # end # def structured_label # str = "{" # str << "{" << inslots_str << "}|" unless inslots.empty? # str << label # str << "|{" << outslots_str << "}" unless outslots.empty? # str << "}" # end # def to_s # str = [] # str << line(quote(name), graph_attribs) # str.join("\n") # end # end # class Edge < Item # magic :from, String # magic :into, String # def to_s # str = "" # str << quote(from) # str << " -> " # str << quote(into) # line(str) # end # end # class Graph < Item # field :items, Array, :default => [] # field :edges, Array, :default => [] # def graph(name, attrs={}) # obj = Graph.new(attrs.merge(:name => name, :owner => self)) # items << obj # yield(obj) if block_given? # obj # end # def node(name, attrs={}) # obj = Node.new(attrs.merge(:name => name, :owner => self)) # items << obj # yield(obj) if block_given? # obj # end # def edge(from, into, from_slot=nil, into_slot=nil) # obj = Edge.new( # :name => name, :owner => self, # :from => from, :into => into, # :from_slot => from_slot, :into_slot => into_slot) # edges << obj # yield(obj) if block_given? # obj # end # def to_s # str = [] # str << brace("subgraph #{quote("cluster_#{name}")}") # str << line(attrib(" label", quote(label))) # items.each do |item| # str << item.to_s # end # edges.each do |edge| # str << edge.to_s # end # str << close_brace # str.join("\n") # end # end # class Universe < Graph # field :orient, Symbol, :doc => 'one of :TB, :BT, :LR, :RL', :default => :TB # field :engine, Symbol, :default => :dot # def to_s # str = [] # str << brace("digraph #{name}") # str << line(" rankdir = #{orient}") # items.each do |item| # str << item.to_s # end # str << close_brace # str.join("\n") # end # def depth() 0; end # def save(path, type=nil) # File.open "#{path}.dot", "w" do |f| # f.puts self.to_s # end # system "#{engine} -T#{type} #{path}.dot > #{path}.#{type}" if type # end # end # end # end