Parent

Included Modules

GraphViz

Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Gregoire Lejeune <gregoire.lejeune@free.fr>

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA


>> x = "hellont\l"world""

> "hellont\l"world""

>> puts x.inspect.gsub( "\\", "\" ) "hellontl"world""

OR

>> x = 'hellontl"world"'

> "hello\n\t\l"world""

>> puts x.inspect.gsub( "\\", "\" ) "hellontl"world""

Attributes

edge[RW]

This accessor allow you to set global edges attributs

edge_attrs[RW]

This accessor allow you to set global edges attributs

graph[RW]

This accessor allow you to set global graph attributs

graph_attrs[RW]

This accessor allow you to set global graph attributs

node[RW]

This accessor allow you to set global nodes attributs

node_attrs[RW]

This accessor allow you to set global nodes attributs

Public Class Methods

default( hOpts ) click to toggle source

Change default options (:use, :path, :errors and :output)

# File lib/graphviz.rb, line 690
def self.default( hOpts )
  hOpts.each do |k, v|
    case k.to_s
      when "use"
        @@prog = v
      when "path"
        @@path = v.split( "," ).map{ |x| x.strip }
      when "errors"
        @@errors = v
      when "extlibs"
        @@extlibs = v.split( "," ).map{ |x| x.strip }
      when "output"
        warn ":output option is deprecated!"
        @@format = v
      else
        warn "Invalide option #{k}!"
    end
  end
end
new( xGraphName, hOpts = {}, &block ) click to toggle source

Create a new graph object

Options :

  • :output : Output format (Constants::FORMATS) (default : dot)

  • :file : Output file name (default : nil)

  • :use : Program to use (Constants::PROGRAMS) (default : dot)

  • :path : Program PATH

  • :parent : Parent graph (default : nil)

  • :type : Graph type (Constants::GRAPHTYPE) (default : digraph)

  • :errors : DOT error level (default 1)

    • 0 = Error + Warning

    • 1 = Error

    • 2 = none

# File lib/graphviz.rb, line 761
def initialize( xGraphName, hOpts = {}, &block )
  @filename = nil
  @name     = xGraphName.to_s
  @format   = @@format
  @prog     = @@prog
  @path     = @@path
  @errors   = @@errors
  @extlibs  = @@extlibs
  @output   = {}
  @nothugly = false
  @strict   = false
  
  @scale        = nil
  @inverty      = nil
  @no_layout    = nil
  @reduce_graph = nil
  @Lg           = nil
  @LO           = nil
  @Ln           = nil
  @LU           = nil
  @LC           = nil
  @LT           = nil
  
  @elements_order = GraphViz::Elements::new()

  @oParentGraph = nil
  @oGraphType   = "digraph"
  
  @hoNodes  = Hash::new()
  @loEdges  = Array::new()
  @hoGraphs = Hash::new()
  
  @node  = GraphViz::Attrs::new( self, "node",  NODESATTRS  )
  @edge  = GraphViz::Attrs::new( self, "edge",  EDGESATTRS  )
  @graph = GraphViz::Attrs::new( self, "graph", GRAPHSATTRS )

  hOpts.each do |xKey, xValue|
    case xKey.to_s
      when "output"
        warn ":output option is deprecated, please use :<format> => :<file>"
        if FORMATS.index( xValue.to_s ).nil? == true
          raise ArgumentError, "output format '#{xValue}' invalid"
        end
        @format = xValue.to_s
      when "use"
        if PROGRAMS.index( xValue.to_s ).nil? == true
          raise ArgumentError, "can't use '#{xValue}'"
        end
        @prog = xValue.to_s
      when "file"
        warn ":file option is deprecated, please use :<format> => :<file>"
        @filename = xValue.to_s
      when "parent"
        @oParentGraph = xValue
      when "type"
        if GRAPHTYPE.index( xValue.to_s ).nil? == true
          raise ArgumentError, "graph type '#{xValue}' unknow"
        end
        @oGraphType = xValue.to_s
      when "path"
        @path = xValue.split( "," ).map{ |x| x.strip }
      when "strict"
        @strict = (xValue ? true : false)
      when "errors"
        @errors = xValue
      when "extlibs"
        @extlibs = xValue.split( "," ).map{ |x| x.strip }
      else
        self[xKey.to_s] = xValue.to_s
    end
  end

  yield( self ) if( block )
end
nothugly( file, save = true ) click to toggle source

Transform to pretty up the SVG output

For more information, see www.hokstad.com/making-graphviz-output-pretty-with-xsl.html and www.hokstad.com/making-graphviz-output-pretty-with-xsl-updated.html

You can use the :nothugly option to GraphViz#output :

graph.output( :svg => "myGraph.svg", :nothugly => true )

Or directly on an SVG output graph :

GraphViz.nothugly( "myGraph.svg" )
# File lib/graphviz/nothugly.rb, line 26
def self.nothugly( file, save = true )
  xslt = XML::XSLT.new()
  xslt.xml = file
  xslt.xsl = File.join( File.dirname(File.expand_path(__FILE__)), "nothugly", "nothugly.xsl" )

  out = xslt.serve()

  if save
    fname = File.join( File.dirname(File.expand_path(file)), File.basename(file))
    File.open( fname, "w" ) { |io|
      io.print out
    }
  else
    return out
  end
end
options( hOpts ) click to toggle source
# File lib/graphviz.rb, line 710
def self.options( hOpts )
  GraphViz::default( hOpts )
end
parse( xFile, hOpts = {}, &block ) click to toggle source

Create a new graph from a GraphViz File

Options :

  • :output : Output format (Constants::FORMATS) (default : dot)

  • :file : Output file name (default : none)

  • :use : Program to use (Constants::PROGRAMS) (default : dot)

  • :path : Program PATH

# File lib/graphviz.rb, line 725
def self.parse( xFile, hOpts = {}, &block ) 
  graph = Dot2Ruby::new( hOpts[:path], nil, nil ).eval( xFile )
  yield( graph ) if( block and graph.nil? == false )
  return graph
end

Public Instance Methods

-( oNode ) click to toggle source
Alias for: <<
<<( oNode ) click to toggle source

Create an edge between the current cluster and the node or cluster oNode

# File lib/graphviz.rb, line 639
def <<( oNode )
  raise( ArgumentError, "Edge between root graph and node or cluster not allowed!" ) if self.pg.nil?

  if( oNode.class == Array ) 
    oNode.each do |no|
      self << no
    end
  else
    return GraphViz::commonGraph( oNode, self ).add_edge( self, oNode )
  end
end
Also aliased as: >, -, >>
>( oNode ) click to toggle source
Alias for: <<
>>( oNode ) click to toggle source
Alias for: <<
[]( xAttrName ) click to toggle source

Get the value of the graph attribut xAttrName

# File lib/graphviz.rb, line 330
def []( xAttrName )
  if Hash === xAttrName
    xAttrName.each do |key, value|
      self[key] = value
    end
  else
    return( @graph[xAttrName].clone )
  end
end
[]=( xAttrName, xValue ) click to toggle source

Set value xValue to the graph attribut xAttrName

# File lib/graphviz.rb, line 322
def []=( xAttrName, xValue )
  xValue = xValue.to_s if xValue.class == Symbol
  @graph[xAttrName] = xValue
end
add_edge( oNodeOne, oNodeTwo, hOpts = {} ) click to toggle source

Create a new edge

In:

  • oNodeOne : First node (or node list)

  • oNodeTwo : Second Node (or node list)

  • hOpts : Edge attributs

# File lib/graphviz.rb, line 163
def add_edge( oNodeOne, oNodeTwo, hOpts = {} )
  
  if( oNodeOne.class == Array ) 
    oNodeOne.each do |no|
      add_edge( no, oNodeTwo, hOpts )
    end
  else
    if( oNodeTwo.class == Array )
      oNodeTwo.each do |nt|
        add_edge( oNodeOne, nt, hOpts )
      end
    else
      oEdge = GraphViz::Edge::new( oNodeOne, oNodeTwo, self )
      oEdge.index = @elements_order.size_of( "edge" )
      
      hOpts.each do |xKey, xValue|
        oEdge[xKey.to_s] = xValue
      end
      
      @elements_order.push( { 
        "type" => "edge", 
        "value" => oEdge
      } )
      @loEdges.push( oEdge )
      
      return( oEdge )
    end
  end
end
add_graph( xGraphName = nil, hOpts = {}, &block ) click to toggle source

Create a new graph

In:

  • xGraphName : Graph name

  • hOpts : Graph attributs

# File lib/graphviz.rb, line 228
def add_graph( xGraphName = nil, hOpts = {}, &block )
  if xGraphName.kind_of?(Hash)
    hOpts = xGraphName
    xGraphName = nil
  end

  if xGraphName.nil?
    xGraphID = String.random(11)
    xGraphName = ""
  else
    xGraphID = xGraphName
  end
  
  @hoGraphs[xGraphID] = GraphViz::new( xGraphName, {:parent => self, :type => @oGraphType}, &block )
 
  hOpts.each do |xKey, xValue|
    @hoGraphs[xGraphID][xKey.to_s] = xValue
  end
  
  @elements_order.push( { 
    "type" => "graph", 
    "name" => xGraphName,
    "value" => @hoGraphs[xGraphID] 
  } )
  
  return( @hoGraphs[xGraphID] )
end
Also aliased as: subgraph
add_node( xNodeName, hOpts = {} ) click to toggle source

Create a new node

In:

  • xNodeName : Name of the new node

  • hOpts : Node attributs

Return the GraphViz::Node object created

# File lib/graphviz.rb, line 95
def add_node( xNodeName, hOpts = {} )
  @hoNodes[xNodeName] = GraphViz::Node::new( xNodeName, self )
  @hoNodes[xNodeName].index = @elements_order.size_of( "node" )
  
  unless hOpts.keys.include?(:label) or hOpts.keys.include?("label")
    hOpts[:label] = xNodeName
  end
    
  hOpts.each do |xKey, xValue|
    @hoNodes[xNodeName][xKey.to_s] = xValue
  end
  
  @elements_order.push( { 
    "type" => "node", 
    "name" => xNodeName,
    "value" => @hoNodes[xNodeName] 
  } )
  
  return( @hoNodes[xNodeName] )
end
each_attribut(&b) click to toggle source

Calls block once for each attribut of the graph, passing the name and value to the block as a two-element array.

# File lib/graphviz.rb, line 344
def each_attribut(&b)
  @graph.each do |k,v|
    yield(k,v)
  end
end
each_edge( &block ) click to toggle source

Allow you to traverse edges

# File lib/graphviz.rb, line 196
def each_edge( &block )
  if block_given?
    @loEdges.each do |edge|
      yield(edge)
    end
  else
    return @loEdges
  end
end
each_graph( &block ) click to toggle source

Allow you to traverse graphs

# File lib/graphviz.rb, line 270
def each_graph( &block )
  if block_given?
    @hoGraphs.each do |name, graph|
      yield( name, graph )
    end
  else
    return @hoGraphs
  end
end
each_node( &block ) click to toggle source

Allow you to traverse nodes

# File lib/graphviz.rb, line 138
def each_node( &block )
  if block_given?
    @hoNodes.each do |name, node|
      yield( name, node )
    end
  else
    return( @hoNodes )
  end
end
edge_count() click to toggle source

Get the number of edges

# File lib/graphviz.rb, line 209
def edge_count
  @loEdges.size
end
get_edge_at_index( index ) click to toggle source

Return the edge object for the given index

# File lib/graphviz.rb, line 216
def get_edge_at_index( index )
  element = @elements_order[index, "edge"]
  (element.nil?) ? nil : element["value"]
end
get_graph( xGraphName, &block ) click to toggle source

Return the graph object for the given name (or nil)

# File lib/graphviz.rb, line 259
def get_graph( xGraphName, &block )
  graph = @hoGraphs[xGraphName] || nil
  
  yield( graph ) if( block and graph.nil? == false )
  
  return graph
end
get_node( xNodeName, &block ) click to toggle source

Return the node object for the given name (or nil)

# File lib/graphviz.rb, line 119
def get_node( xNodeName, &block )
  node = @hoNodes[xNodeName] || nil
  
  yield( node ) if( block and node.nil? == false )
  
  return node
end
get_node_at_index( index ) click to toggle source

Return the node object for the given index

# File lib/graphviz.rb, line 130
def get_node_at_index( index )
  element = @elements_order[index, "node"]
  (element.nil?) ? nil : element["value"]
end
graph_count() click to toggle source

Get the number of graphs

# File lib/graphviz.rb, line 289
def graph_count
  @hoGraphs.size
end
id() click to toggle source
Alias for: name
name() click to toggle source

Get the graph name

# File lib/graphviz.rb, line 631
def name 
  @name.clone
end
Also aliased as: id
node_count() click to toggle source

Get the number of nodes

# File lib/graphviz.rb, line 151
def node_count
  @hoNodes.size
end
output( hOpts = {} ) click to toggle source

Generate the graph

Options :

  • :output : Output format (Constants::FORMATS)

  • :file : Output file name

  • :use : Program to use (Constants::PROGRAMS)

  • :path : Program PATH

  • :<format> => <file> : <file> can be

    • a file name

    • nil, then the output will be printed to STDOUT

    • String, then the output will be returned as a String

  • :errors : DOT error level (default 1)

    • 0 = Error + Warning

    • 1 = Error

    • 2 = none

# File lib/graphviz.rb, line 367
def output( hOpts = {} )
  xDOTScript = ""
  xLastType = nil
  xSeparator = ""
  xData = ""
  lNotHugly = []

  @elements_order.each { |kElement|
    if xLastType.nil? == true or xLastType != kElement["type"]
      
      if xData.length > 0 
        case xLastType
          when "graph_attr"
            xDOTScript << "  " + xData + ";\n"

          when "node_attr"
            xDOTScript << "  node [" + xData + "];\n"
          
          when "edge_attr"
            xDOTScript << "  edge [" + xData + "];\n"
        end
      end
      
      xSeparator = ""
      xData = ""
    end

    xLastType = kElement["type"]

    #Modified by
    #Brandon Coleman 
    #verify value is NOT NULL
    if kElement["value"] == nil then
      raise ArgumentError, "#{kElement["name"]} has a nil value!"
    end

    case kElement["type"]
      when "graph_attr"
        xData << xSeparator + kElement["name"] + " = " + kElement["value"].to_gv
        xSeparator = "; "

      when "node_attr"
        xData << xSeparator + kElement["name"] + " = " + kElement["value"].to_gv
        xSeparator = ", "

      when "edge_attr"
        xData << xSeparator + kElement["name"] + " = " + kElement["value"].to_gv
        xSeparator = ", "

      when "node"
        xDOTScript << "  " + kElement["value"].output() + "\n"

      when "edge"
        xDOTScript << "  " + kElement["value"].output( @oGraphType ) + "\n"

      when "graph"
        xDOTScript << kElement["value"].output() + "\n"

      else
        raise ArgumentError, "Don't know what to do with element type '#{kElement['type']}'"
    end
  }
  
  if xData.length > 0 
    case xLastType
      when "graph_attr"
        xDOTScript << "  " + xData + ";\n"

      when "node_attr"
        xDOTScript << "  node [" + xData + "];\n"
      
      when "edge_attr"
        xDOTScript << "  edge [" + xData + "];\n"
    end
  end
  xDOTScript << "}"

  if @oParentGraph.nil? == false
    xDOTScript = "subgraph #{GraphViz.escape(@name, :unquote_empty => true)} {\n" << xDOTScript

    return( xDOTScript )
  else
    hOutput = {}
    
    hOpts.each do |xKey, xValue|
      xValue = xValue.to_s unless xValue.nil? or [Class, TrueClass, FalseClass].include?(xValue.class)
      case xKey.to_s
        when "output"
          warn ":output option is deprecated, please use :<format> => :<file> -- BE CAREFUL, it will be removed in the 1.0 version!"
          if FORMATS.index( xValue ).nil? == true
            raise ArgumentError, "output format '#{xValue}' invalid"
          end
          @format = xValue
        when "file"
          warn ":file option is deprecated, please use :<format> => :<file> -- BE CAREFUL, it will be removed in the 1.0 version!"
          @filename = xValue
        when "use"
          if PROGRAMS.index( xValue ).nil? == true
            raise ArgumentError, "can't use '#{xValue}'"
          end
          @prog = xValue
        when "path"
          @path = xValue.split( "," ).map{ |x| x.strip }
        when "errors"
          @errors = xValue
        when "extlib"
          @extlibs = xValue.split( "," ).map{ |x| x.strip }
        when "scale"
          # Scale input by 'v' (=72)
          @scale = xValue
        when "inverty"
          # Invert y coordinate in output
          @inverty = xValue
        when "no_layout"
          # No layout mode 'v' (=1)
          @no_layout = xValue
        when "reduce"
          # Reduce graph
          @reduce_graph = xValue
        when "Lg"
          # Don't use grid
          @Lg = xValue
        when "LO"
          # Use old attractive force
          @LO = xValue
        when "Ln"
          # Set number of iterations to i
          @Ln = xValue
        when "LU"
          # Set unscaled factor to i
          @LU = xValue
        when "LC"
          # Set overlap expansion factor to v
          @LC = xValue
        when "LT"
          # Set temperature (temperature factor) to v
          @LT = xValue
        when "nothugly"
          begin
            require 'graphviz/nothugly'
            @nothugly = true
          rescue
            warn "You must install ruby-xslt to use nothugly option!"
            @nothugly = false
          end
        else
          if FORMATS.index( xKey.to_s ).nil? == true
            raise ArgumentError, "output format '#{xValue}' invalid"
          end
          hOutput[xKey.to_s] = xValue
      end
    end
    
    @output = hOutput if hOutput.size > 0

    xStict = ((@strict && @oGraphType == "digraph") ? "strict " : "")
    xDOTScript = ("#{xStict}#{@oGraphType} #{GraphViz.escape(@name, :unquote_empty => true)} {\n" << xDOTScript).gsub( "\00"", "" )

    xOutputString = (@filename == String ||
      @output.any? {|format, file| file == String })
      
    xOutput = ""
    if @format.to_s == "none" or @output.any? {|fmt, fn| fmt.to_s == "none"}
      if xOutputString
        xOutput << xDOTScript
      else
        xFileName = @output["none"] || @filename
        open( xFileName, "w" ) do |h|
          h.puts xDOTScript
        end
      end
    end
    
    if (@format.to_s != "none" and not @format.nil?) or (@output.any? {|format, file| format != "none" } and @output.size > 0)
      ## Act: Save script and send it to dot
      t = Tempfile::open( File.basename(__FILE__) )
      t.print( xDOTScript )
      t.close
      
      cmd = find_executable( @prog, @path )
      if cmd == nil
        raise StandardError, "GraphViz not installed or #{@prog} not in PATH. Install GraphViz or use the 'path' option"
      end

      cmd = escape_path_containing_blanks(cmd) if IS_JRUBY

      xOutputWithFile = ""
      xOutputWithoutFile = ""
      unless @format.nil? or @format == "none"
        lNotHugly << @filename if @format.to_s == "svg" and @nothugly
        if @filename.nil? or @filename == String
          xOutputWithoutFile = "-T#{@format} "
        else
          xOutputWithFile = "-T#{@format} -o#{@filename} "
        end
      end
      @output.each_except( :key => ["none"] ) do |format, file|
        lNotHugly << file if format.to_s == "svg" and @nothugly
        if file.nil? or file == String
          xOutputWithoutFile << "-T#{format} "
        else
          xOutputWithFile << "-T#{format} -o#{file} "
        end
      end
      
      xExternalLibraries = ""
      @extlibs.each do |lib|
        xExternalLibraries << "-l#{lib} "
      end
      
      xOtherOptions = ""        
      xOtherOptions += " -s#{@scale}" unless @scale.nil?
      xOtherOptions += " -y" if @inverty == true
      unless @no_layout.nil?
        xOtherOptions += " -n"
        xOtherOptions += "2" if @no_layout.to_i == 2
      end
      xOtherOptions += " -x" if @reduce_graph == true
      xOtherOptions += " -Lg" if @Lg == true
      xOtherOptions += " -LO" if @LO == true
      xOtherOptions += " -Ln#{@Ln}" unless @LN.nil?
      xOtherOptions += " -LU#{@LU}" unless @LU.nil?
      xOtherOptions += " -LC#{@LC}" unless @LC.nil?
      xOtherOptions += " -LT#{@LT}" unless @LT.nil?
      
      if IS_JRUBY
        xCmd = "#{cmd} -q#{@errors} #{xExternalLibraries} #{xOtherOptions} #{xOutputWithFile} #{xOutputWithoutFile} #{t.path}"
      elsif IS_CYGWIN
        tmpPath = t.path
        begin
          tmpPath = "'" + `cygpath -w #{t.path}`.chomp + "'"
        rescue
          warn "cygpath is not installed!"
        end
        xCmd = "\"#{cmd}\" -q#{@errors} #{xExternalLibraries} #{xOtherOptions} #{xOutputWithFile} #{xOutputWithoutFile} #{tmpPath}"
      else
        xCmd = "\"#{cmd}\" -q#{@errors} #{xExternalLibraries} #{xOtherOptions} #{xOutputWithFile} #{xOutputWithoutFile} #{t.path}"
      end

      xOutput << output_from_command( xCmd )
    end
    
    # Not Hugly
    lNotHugly.each do |f|
      if f.nil? or f == String
        xOutput = GraphViz.nothugly( xOutput, false )
      else
        GraphViz.nothugly( f, true )
      end
    end
    
    if xOutputString
      xOutput
    else
      print xOutput
    end
  end
end
Also aliased as: save
root_graph() click to toggle source

Return the root graph

# File lib/graphviz.rb, line 661
def root_graph
  return( (self.pg.nil?) ? self : self.pg.root_graph )
end
save( hOpts = {} ) click to toggle source
Alias for: output
subgraph( xGraphName = nil, hOpts = {}, &block ) click to toggle source
Alias for: add_graph
type() click to toggle source

Return the graph type (graph digraph)

# File lib/graphviz.rb, line 282
def type
  @oGraphType
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.