mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-11-18 15:13:21 +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_id:)
|
||
|
@exp = Experiment.find experiment_id
|
||
|
@graph = GraphViz.new(:G, type: :digraph, use: :neato)
|
||
|
|
||
|
@graph[:size] = '4,4'
|
||
|
@graph.node[color: Constants::COLOR_ALTO,
|
||
|
style: :filled,
|
||
|
fontcolor: Constants::COLOR_EMPEROR,
|
||
|
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'))
|
||
|
@graph.output(png: file.path)
|
||
|
@exp.workflowimg = file
|
||
|
file.close
|
||
|
@exp.save
|
||
|
@exp.touch(:workflowimg_updated_at)
|
||
|
rescue StandardError => ex
|
||
|
logger.error ex.message
|
||
|
end
|
||
|
end
|
||
|
end
|