2019-01-11 17:16:50 +08:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
module Experiments
|
|
|
|
class GenerateWorkflowImageService
|
|
|
|
extend Service
|
|
|
|
require 'graphviz'
|
|
|
|
|
|
|
|
attr_reader :errors
|
|
|
|
|
2020-10-16 20:21:25 +08:00
|
|
|
def initialize(experiment:)
|
|
|
|
@exp = experiment
|
2021-03-26 00:42:57 +08:00
|
|
|
@graph_params = {
|
2021-02-03 05:23:11 +08:00
|
|
|
inputscale: 3,
|
|
|
|
size: '2,2',
|
|
|
|
pad: '0.4',
|
|
|
|
ratio: 'fill',
|
|
|
|
splines: true,
|
|
|
|
center: true,
|
|
|
|
pack: true,
|
2023-04-12 15:34:54 +08:00
|
|
|
bgcolor: 'transparent'
|
2021-02-03 05:23:11 +08:00
|
|
|
}
|
2021-03-26 00:42:57 +08:00
|
|
|
@node_params = {
|
|
|
|
color: Constants::COLOR_VOLCANO,
|
|
|
|
style: :filled,
|
|
|
|
fontcolor: Constants::COLOR_VOLCANO,
|
|
|
|
shape: 'circle',
|
|
|
|
fontname: 'Arial',
|
|
|
|
fontsize: '16.0'
|
|
|
|
}
|
|
|
|
@edge_params = {
|
|
|
|
color: Constants::COLOR_VOLCANO,
|
|
|
|
penwidth: '3.0'
|
|
|
|
}
|
2019-01-11 17:16:50 +08:00
|
|
|
|
2023-07-05 18:43:23 +08:00
|
|
|
@graph = Graphviz::Graph.new('G', **@graph_params)
|
2019-01-11 17:16:50 +08:00
|
|
|
@errors = []
|
|
|
|
end
|
|
|
|
|
|
|
|
def call
|
|
|
|
draw_diagram
|
|
|
|
save_file
|
|
|
|
self
|
|
|
|
end
|
|
|
|
|
|
|
|
def succeed?
|
|
|
|
@errors.none?
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def draw_diagram
|
|
|
|
# Draw grouped modules
|
|
|
|
@exp.my_module_groups.each_with_index do |group, gindex|
|
|
|
|
subgraph_id = "cluster-#{gindex}"
|
|
|
|
nodes = {}
|
|
|
|
|
|
|
|
group.my_modules.workflow_ordered.each_with_index do |my_module, index|
|
|
|
|
# draw nodes
|
2021-03-26 00:42:57 +08:00
|
|
|
node = @graph.add_node(
|
2019-01-11 17:16:50 +08:00
|
|
|
"#{subgraph_id}-#{index}",
|
2023-07-05 18:43:23 +08:00
|
|
|
**@node_params.merge(
|
2021-03-26 00:42:57 +08:00
|
|
|
label: '',
|
|
|
|
pos: "#{my_module.x / 10},-#{my_module.y / 10}!"
|
|
|
|
)
|
2019-01-11 17:16:50 +08:00
|
|
|
)
|
|
|
|
nodes[my_module.id] = node
|
|
|
|
end
|
|
|
|
|
|
|
|
# draw edges
|
|
|
|
group.my_modules.workflow_ordered.each do |m|
|
|
|
|
m.outputs.each do |output|
|
|
|
|
parent_node = nodes[m.id]
|
|
|
|
child_node = nodes[output.input_id]
|
2021-03-26 00:42:57 +08:00
|
|
|
parent_node.connect(child_node, @edge_params)
|
2019-01-11 17:16:50 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2021-02-03 05:23:11 +08:00
|
|
|
|
|
|
|
# Draw orphan nodes
|
|
|
|
@exp.my_modules.without_group.each do |my_module|
|
2021-03-26 00:42:57 +08:00
|
|
|
@graph.add_node(
|
2021-02-03 05:23:11 +08:00
|
|
|
"Orphan-#{my_module.id}",
|
2023-07-05 18:43:23 +08:00
|
|
|
**@node_params.merge(
|
2021-03-26 00:42:57 +08:00
|
|
|
label: '',
|
|
|
|
pos: "#{my_module.x / 10},-#{my_module.y / 10}!"
|
|
|
|
)
|
2021-02-03 05:23:11 +08:00
|
|
|
)
|
|
|
|
end
|
2019-01-11 17:16:50 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
def save_file
|
|
|
|
file = Tempfile.open(%w(wimg .png), Rails.root.join('tmp'))
|
2020-10-16 20:21:25 +08:00
|
|
|
begin
|
2021-03-26 00:42:57 +08:00
|
|
|
Graphviz.output(@graph, path: file.path, format: 'png', dot: 'neato')
|
2020-10-16 20:21:25 +08:00
|
|
|
file.rewind
|
|
|
|
@exp.workflowimg.attach(io: file, filename: File.basename(file.path))
|
|
|
|
ensure
|
|
|
|
file.close
|
|
|
|
file.unlink
|
|
|
|
end
|
2019-01-11 17:16:50 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|