Search code examples
rubyrubygemsgraphviztransition-systems

Ruby Graphviz - Labelled Transition System's Initial State?


I'm making a tool that can do some operations on a transition system and also need to visualise them.

Though there isn't much documentation on the ruby-gem (this was the best I could get: http://www.omninerd.com/articles/Automating_Data_Visualization_with_Ruby_and_Graphviz ), I managed to make a graph from my transition system. (Feel free to use it, there ain't much example code around. comments/questions are also welcome)

# note: model is something of my own datatype, 
   # having states, labels, transitions, start_state and a name
   # I hope the code is self-explaining

@graph = GraphViz::new(model.name, "type" => "graph" )

#settings
@graph.edge[:dir]      = "forward"
@graph.edge[:arrowsize]= "0.5"

#make the graph
model.states.each do |cur_state|
  @graph.add_node(cur_state.name).label = cur_state.name

  cur_state.out_transitions.each do |cur_transition|
      @graph.add_edge(cur_transition.from.name, cur_transition.to.name).label = cur_transition.label.to_s
  end
end

#make a .pdf output (can also be changed to .eps, .png or whatever)
@graph.output("pdf" => File.join(".")+"/" + @graph.name + ".pdf")
#it's really not that hard :-)

Only one thing that I can't do: draw an arrow 'out of nothing' to the start state. Suggestions anyone?


Solution

  • credits to Jonas Elfström, this is my solution

    # note: model is something of my own datatype, 
       # having states, labels, transitions, start_state and a name
       # I hope the code is self-explaining    
    @graph = GraphViz::new(model.name, "type" => "graph" )
    
    #settings
    @graph.edge[:dir]      = "forward"
    @graph.edge[:arrowsize]= "0.5"
    
    #make the graph
    model.states.each do |cur_state|
      @graph.add_node(cur_state.name).label = cur_state.name
    
      cur_state.out_transitions.each do |cur_transition|
          @graph.add_edge(cur_transition.from.name, cur_transition.to.name).label = cur_transition.label.to_s
      end
    end
    #draw the arrow to the initial state (THE ADDED CODE)
    @graph.add_node("Start",
      "shape" => "none",
      "label" => "" )
    @graph.add_edge("Start", model.start_state.name)
    
    #make a .pdf output (can also be changed to .eps, .png or whatever)
    @graph.output("pdf" => File.join(".")+"/" + @graph.name + ".pdf")
    #it's really not that hard :-)