class DataMapper::Visualizer::GraphViz

Visualizes projects by generating a [GraphViz](www.graphviz.org/) diagram.

Attributes

colors[R]

The colors to use

file[RW]

The output file

format[RW]

The output file format (‘:svg`)

labels[R]

The labels to use

Public Class Methods

new(options={}) click to toggle source

Creates a new GraphViz object.

@param [Hash] options

Additional options.

@option options [String] :file

The output file path.

@option options [Symbol] :format (:svg)

The format of the generated graph.

@option options [Hash] :colors

The colors to use for `:one_to_many` and `:one_to_one`
relationship edges.

@option options [Hash] :labels

The labels to use for `:one_to_many` and `:one_to_one`
relationship edges.
Calls superclass method
# File lib/dm-visualizer/graphviz.rb, line 51
def initialize(options={})
  super(options)

  @format = :svg

  @colors = {
    :one_to_many => 'blue',
    :one_to_one  => 'red',
    :inheritence => 'cyan'
  }
  @labels = {
    :one_to_many => '1:m',
    :one_to_one  => '1:1'
  }

  if options[:file]
    @file = File.expand_path(options[:file])
  end

  if options[:format]
    @format = options[:format].to_sym
  end

  if options[:colors]
    options[:colors].each do |name,value|
      @colors[name.to_sym] = value.to_s
    end
  end

  if options[:labels]
    options[:labels].each do |name,value|
      @labels[name.to_sym] = value.to_s
    end
  end
end

Public Instance Methods

path() click to toggle source

The full output path.

@return [String]

The full output path, including file extension.
# File lib/dm-visualizer/graphviz.rb, line 93
def path
  "#{@file}.#{@format}"
end

Protected Instance Methods

visualize() click to toggle source

Generates a GraphViz diagram for a project.

@param [String] path

The path to save the graph image to.
# File lib/dm-visualizer/graphviz.rb, line 105
def visualize
  graph = ::GraphViz.new(:G, :type => :digraph)

  # Create node for each model
  project.each_model do |model|
    properties = project.each_property(model).map do |property|
      "#{property_name(property)}: #{property_type_name(property)}"
    end

    foreign_keys = project.each_foreign_key(model).map do |key,value|
      "#{foreign_key_name(key)}: #{model_name(value)}"
    end

    columns = (properties + foreign_keys)
    label = "{ #{model_name(model)} | #{columns.join("\n")} }"

    graph.add_nodes(
      model_name(model),
      :shape => 'record',
      :label => label
    )
  end

  # Connect model nodes together by relationship
  project.each_relationship do |relationship,model|
    source_node = graph.get_node(model_name(model))
    target_node = graph.get_node(model_name(relationship.target_model))

    case relationship
    when DataMapper::Associations::OneToMany::Relationship
      graph.add_edges(
        source_node,
        target_node,
        :color => @colors[:one_to_many],
        :label => " #{@labels[:one_to_many]}"
      )
    when DataMapper::Associations::OneToOne::Relationship
      graph.add_edges(
        source_node,
        target_node,
        :color => @colors[:one_to_one],
        :label => " #{@labels[:one_to_one]}"
      )
    end
  end

  # Connect model nodes by inheritence
  project.each_model_inheritence do |model,ancestor|
    source_node = graph.get_node(model_name(ancestor))
    target_node = graph.get_node(model_name(model))

    graph.add_edges(
      source_node,
      target_node,
      :color => @colors[:inheritence]
    )
  end

  graph.output(@format => self.path)
end