class ActiveExplorer::Painter

Public Class Methods

new(exploration, file_path) click to toggle source
# File lib/painter.rb, line 3
def initialize(exploration, file_path)
  @exploration = exploration
  @file_path = file_path
  @graph = GraphViz.new(:G, :type => :digraph)
end

Public Instance Methods

paint(origin_as_root: false) click to toggle source
# File lib/painter.rb, line 9
def paint(origin_as_root: false)
  @centralized = origin_as_root
  paint_object @exploration.get_hash, @graph, nil
  save_to_file
  @graph
end

Private Instance Methods

add_edge(graph, parent_node, node, association) click to toggle source
# File lib/painter.rb, line 55
def add_edge(graph, parent_node, node, association)
  if @centralized
    graph.add_edge(parent_node, node, label: association == :belongs_to ? ' belongs to' : ' has') unless edge_exists?(graph, parent_node, node)
  else
    if association == :belongs_to
      graph.add_edge(node, parent_node) unless edge_exists?(graph, node, parent_node)
    else
      graph.add_edge(parent_node, node) unless edge_exists?(graph, parent_node, node)
    end
  end
end
add_node(hash, graph, style: nil) click to toggle source
# File lib/painter.rb, line 33
def add_node(hash, graph, style: nil)
  id = hash[:attributes][:id]
  class_name = make_safe(hash[:class_name])
  attributes = make_safe(hash[:attributes].keys.join("\n"))
  values = hash[:attributes].values.collect do |val|
    if val.nil?
      'nil'
    elsif val.is_a? String
      "\"#{make_short(val)}\""
    else
      make_short(val.to_s)
    end
  end
  values = make_safe(values.join("\n"))

  if style == :origin
    graph.add_node("#{class_name}_#{id}", shape: "record", label: "{#{class_name}|{#{attributes}|#{values}}}", labelloc: 't', style: 'filled', fillcolor: 'yellow')
  else
    graph.add_node("#{class_name}_#{id}", shape: "record", label: "{#{class_name}|{#{attributes}|#{values}}}", labelloc: 't')
  end
end
create_directory(directory) click to toggle source
# File lib/painter.rb, line 84
def create_directory(directory)
  unless directory.empty? || File.directory?(directory)
    FileUtils.mkdir_p directory
  end
end
edge_exists?(graph, node_one, node_two) click to toggle source
# File lib/painter.rb, line 67
def edge_exists?(graph, node_one, node_two)
  graph.each_edge do |edge|
    return true if edge.node_one == node_one.id && edge.node_two == node_two.id
  end

  false
end
make_safe(text) click to toggle source

Replace characters that conflict with DOT language (used in GraphViz). These: ‘{`, `}`, `<`, `>`, `|`, ``

# File lib/painter.rb, line 97
def make_safe(text)
  text.tr('{}<>|\\', '')
end
make_short(text) click to toggle source
# File lib/painter.rb, line 90
def make_short(text)
  text.length < 70 ? text : text[0..70] + " (...)"
end
paint_object(hash, graph, parent_node) click to toggle source
# File lib/painter.rb, line 18
def paint_object(hash, graph, parent_node)
  style = parent_node.nil? ? :origin : nil

  node = add_node(hash, graph, style: style)
  add_edge(graph, parent_node, node, hash[:association]) unless parent_node.nil?

  paint_subobjects graph, node, hash[:subobjects] unless hash[:subobjects].nil?
end
paint_subobjects(graph, parent_node, subhashes) click to toggle source
# File lib/painter.rb, line 27
def paint_subobjects(graph, parent_node, subhashes)
  subhashes.each do |hash|
    paint_object hash, graph, parent_node
  end
end
save_to_file() click to toggle source
# File lib/painter.rb, line 75
def save_to_file
  filename = @file_path.split(File::SEPARATOR).last
  directory = @file_path.chomp filename

  create_directory directory unless directory.empty?

  @graph.output(:png => @file_path)
end