mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-11-14 05:05:55 +08:00
88 lines
2.2 KiB
Ruby
88 lines
2.2 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Experiments
|
|
class GenerateWorkflowImageService
|
|
extend Service
|
|
require 'graphviz'
|
|
|
|
attr_reader :errors
|
|
|
|
def initialize(experiment:)
|
|
@exp = experiment
|
|
@graph = GraphViz.new(:G, type: :digraph, use: :neato)
|
|
|
|
@graph[:size] = '4,4'
|
|
@graph.node[color: Constants::COLOR_ALTO,
|
|
style: :filled,
|
|
fontcolor: Constants::COLOR_VOLCANO,
|
|
shape: 'circle',
|
|
fontname: 'Arial',
|
|
fontsize: '16.0']
|
|
|
|
@graph.edge[color: Constants::COLOR_ALTO]
|
|
@errors = []
|
|
end
|
|
|
|
def call
|
|
draw_diagram
|
|
save_file
|
|
self
|
|
end
|
|
|
|
def succeed?
|
|
@errors.none?
|
|
end
|
|
|
|
private
|
|
|
|
def draw_diagram
|
|
# Draw orphan nodes
|
|
@exp.my_modules.without_group.each do |my_module|
|
|
@graph.subgraph(rank: 'same').add_nodes(
|
|
"Orphan-#{my_module.id}",
|
|
label: '',
|
|
pos: "#{my_module.x / 10},-#{my_module.y / 10}!"
|
|
)
|
|
end
|
|
|
|
# Draw grouped modules
|
|
subg = {}
|
|
@exp.my_module_groups.each_with_index do |group, gindex|
|
|
subgraph_id = "cluster-#{gindex}"
|
|
subg[subgraph_id] = @graph.subgraph(rank: 'same')
|
|
nodes = {}
|
|
|
|
group.my_modules.workflow_ordered.each_with_index do |my_module, index|
|
|
# draw nodes
|
|
node = subg[subgraph_id].add_nodes(
|
|
"#{subgraph_id}-#{index}",
|
|
label: '',
|
|
pos: "#{my_module.x / 10},-#{my_module.y / 10}!"
|
|
)
|
|
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]
|
|
subg[subgraph_id].add_edges(parent_node, child_node)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def save_file
|
|
file = Tempfile.open(%w(wimg .png), Rails.root.join('tmp'))
|
|
begin
|
|
@graph.output(png: file.path)
|
|
file.rewind
|
|
@exp.workflowimg.attach(io: file, filename: File.basename(file.path))
|
|
ensure
|
|
file.close
|
|
file.unlink
|
|
end
|
|
end
|
|
end
|
|
end
|