Class: DotR::Digraph

Inherits:
Object
  • Object
show all
Includes:
Styled
Defined in:
lib/dotr.rb

Overview

This class represents a directed graph that can be rendered to a graphics image using its #diagram method.

Example:

d = DotR::Digraph.new do |g|
  g.node('node1') do |n|
    n.label = "MyLabel"
    n.fontsize="8"
  end
  g.node('node2', :label => 'SecondNode') do |n|
    n.connection('node1', :label => 'relates to')
  end
end
File.open('diagram.png', 'w') { |f| f.write(d.diagram(:png)) }

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Styled

#method_missing, #style

Constructor Details

#initialize(name = "diagram", style = {}) {|_self| ... } ⇒ Digraph

Create a new Digraph. If a block is provided it will be called with the graph as a parameter.

Specify styles on this object by setting instance attributes. Possible attributes include ‘label’ and ‘fontsize’; the attribute names and possible values correspond to the style attributes described in the ‘dot’ manual.

Yields:

  • (_self)

Yield Parameters:

  • _self (DotR::Digraph)

    the object that the method was called on



44
45
46
47
48
49
50
# File 'lib/dotr.rb', line 44

def initialize(name="diagram", style={}, &block)
  @name = name
  @nodes = []
  @subgraphs = []
  style_attrs.update(style)
  yield self if block
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class DotR::Styled

Instance Attribute Details

#nameObject

Returns the value of attribute name.



36
37
38
# File 'lib/dotr.rb', line 36

def name
  @name
end

Instance Method Details

#connection(from_node_name, to_node_name, style = {}, &block) ⇒ Object

Create a connection in the graph between two nodes with the given names. If a block is provided it will be called with the connection as a parameter, for convenient specification of styles.

Nodes with the given names are implicitly created if they have not been explicitly added. See Node#connection



65
66
67
68
69
# File 'lib/dotr.rb', line 65

def connection(from_node_name, to_node_name, style={}, &block)
  node(from_node_name) do |n|
    n.connection(to_node_name, style, &block)
  end
end

#diagram(format = :png) ⇒ Object

Render the diagram to a graphic image, returning the raw image data as a string.

Possible values for format include :svg, :png, :ps, :gif



96
97
98
99
100
101
102
# File 'lib/dotr.rb', line 96

def diagram(format=:png)
  Tempfile.open("diag") do |input|
    input.write(self.to_s)
    input.flush
    return IO.popen("dot -T#{format} #{input.path}", 'rb') { |dot| dot.read }
  end
end

#node(name, style = {}, &block) ⇒ Object

Create a Node in the graph with a given name. If a block is provided it will be called with the node as a parameter, for convenient adding of connections or specification of style attributes.



55
56
57
# File 'lib/dotr.rb', line 55

def node(name, style={}, &block)
  @nodes << Node.new(name, style, &block)
end

#render_to(graph_type, output_lines, indent = "") ⇒ Object



104
105
106
107
108
109
110
111
112
# File 'lib/dotr.rb', line 104

def render_to(graph_type, output_lines, indent="")
  output_lines << "#{indent}#{graph_type} \"#{name}\" {"
  @subgraphs.each { |node| node.render_to("subgraph", output_lines, indent + "  ") }
  @nodes.each { |node| node.render_to(output_lines, indent + "  ") }
  style_attrs.each do |k,v|
    output_lines << "#{indent}  #{k}=\"#{v}\";"
  end
  output_lines << "#{indent}}"
end

#subgraph(name, style = {}, &block) ⇒ Object

Create a subgraph of the same type, which can have distinct formatting and its own nodes.

Example:

d = DotR::Digraph.new('myname') do |g|
  g.subgraph('subg', :color => "lightgrey") do |s|
    s.connection("foo", "bar")
  end
end


81
82
83
# File 'lib/dotr.rb', line 81

def subgraph(name, style={}, &block)
  @subgraphs << self.class.new(name, style, &block)
end

#to_sObject

Returns the dot input script equivalent of this digraph



86
87
88
89
90
# File 'lib/dotr.rb', line 86

def to_s
  script = []
  render_to("digraph", script)
  script.flatten.join("\n") + "\n"
end