Module: PROIEL::Visualization::Graphviz

Defined in:
lib/proiel/visualization/graphviz.rb

Defined Under Namespace

Classes: GraphvizError, TemplateContext

Constant Summary collapse

DEFAULT_GRAPHVIZ_BINARY =
'dot'.freeze
DEFAULT_TEMPLATES =
%i(classic linearized packed modern aligned-modern).freeze
SUPPORTED_OUTPUT_FORMATS =
%i(png svg).freeze

Class Method Summary collapse

Class Method Details

.generate(template, graph, output_format, options = {}) ⇒ Object

Raises:

  • (ArgumentError)

21
22
23
24
25
26
27
28
29
30
31
# File 'lib/proiel/visualization/graphviz.rb', line 21

def self.generate(template, graph, output_format, options = {})
  raise ArgumentError, 'string or symbol expected' unless template.is_a?(String) or template.is_a?(Symbol)

  dot_code = generate_dot(template, graph, options)

  if output_format.to_sym == :dot
    dot_code
  else
    generate_image(dot_code, output_format, options)
  end
end

.generate_dot(template, graph, options) ⇒ Object


63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/proiel/visualization/graphviz.rb', line 63

def self.generate_dot(template, graph, options)
  unless options[:direction].nil? or %(TD LR).include?(options[:direction])
    raise ArgumentError, 'invalid direction'
  end

  filename = template_filename(template)

  content = File.read(filename)

  template = ERB.new(content, nil, '-')
  template.filename = filename

  TemplateContext.new(graph, options[:direction] || 'TD').generate(template)
end

.generate_image(dot_code, output_format, options = {}) ⇒ Object

Raises:

  • (ArgumentError)

40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/proiel/visualization/graphviz.rb', line 40

def self.generate_image(dot_code, output_format, options = {})
  raise ArgumentError, 'string expected' unless dot_code.is_a?(String)
  unless output_format.is_a?(String) or output_format.is_a?(Symbol)
    raise ArgumentError, 'string or symbol expected'
  end
  raise ArgumentError, 'invalid output format' unless SUPPORTED_OUTPUT_FORMATS.include?(output_format.to_sym)

  graphviz_binary = options[:graphviz_binary] || DEFAULT_GRAPHVIZ_BINARY

  result, errors = nil, nil

  Open3.popen3("dot -T#{output_format}") do |dot, img, err|
    dot.write dot_code
    dot.close

    result, errors = img.read, err.read
  end

  raise GraphvizError, "graphviz exited with errors: #{errors}" unless errors.nil? or errors == ''

  result
end

.generate_to_file(template, graph, output_format, output_filename, options = {}) ⇒ Object

Raises:

  • (ArgumentError)

11
12
13
14
15
16
17
18
19
# File 'lib/proiel/visualization/graphviz.rb', line 11

def self.generate_to_file(template, graph, output_format, output_filename, options = {})
  raise ArgumentError, 'string expected' unless output_filename.is_a?(String)

  result = PROIEL::Visualization::Graphviz.generate(template, graph, output_format, options)

  File.open(output_filename, 'w') do |f|
    f.write(result)
  end
end

.template_filename(template) ⇒ Object

Raises:

  • (ArgumentError)

33
34
35
36
37
38
# File 'lib/proiel/visualization/graphviz.rb', line 33

def self.template_filename(template)
  raise ArgumentError, 'string or symbol expected' unless template.is_a?(String) or template.is_a?(Symbol)
  raise ArgumentError, 'invalid template' unless DEFAULT_TEMPLATES.include?(template.to_sym)

  File.join(File.dirname(__FILE__), 'graphviz', "#{template}.dot.erb")
end