mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-03-04 19:53:19 +08:00
Refactor workflow_image_generation and move to service class
This commit is contained in:
parent
686f10cbd0
commit
47cc6a9d10
4 changed files with 103 additions and 116 deletions
|
@ -221,123 +221,8 @@ class Experiment < ApplicationRecord
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
# This method generate the workflow image and saves it as
|
|
||||||
# experiment attachment
|
|
||||||
def generate_workflow_img
|
def generate_workflow_img
|
||||||
require 'graphviz'
|
WorkflowImageGenerator.execute(experiment_id: 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]
|
|
||||||
|
|
||||||
label = ''
|
|
||||||
subg = {}
|
|
||||||
|
|
||||||
# Draw orphan modules
|
|
||||||
my_modules.without_group.each do |my_module|
|
|
||||||
graph
|
|
||||||
.subgraph(rank: 'same')
|
|
||||||
.add_nodes("Orphan-#{my_module.id}",
|
|
||||||
label: label,
|
|
||||||
pos: "#{my_module.x / 10},-#{my_module.y / 10}!")
|
|
||||||
end
|
|
||||||
|
|
||||||
# Draw grouped modules
|
|
||||||
if my_module_groups.many?
|
|
||||||
my_module_groups.each_with_index do |group, gindex|
|
|
||||||
subgraph_name = "cluster-#{gindex}"
|
|
||||||
subg[subgraph_name] = graph.subgraph(rank: 'same')
|
|
||||||
group.ordered_modules.each_with_index do |my_module, index|
|
|
||||||
if my_module.outputs.any?
|
|
||||||
parent = subg[subgraph_name]
|
|
||||||
.add_nodes("#{subgraph_name}-#{index}",
|
|
||||||
label: label,
|
|
||||||
pos: "#{my_module.x / 10},-#{my_module.y / 10}!")
|
|
||||||
|
|
||||||
my_module.outputs.each_with_index do |output, i|
|
|
||||||
child_mod = MyModule.find_by_id(output.input_id)
|
|
||||||
child_node = subg[subgraph_name]
|
|
||||||
.add_nodes("#{subgraph_name}-O#{child_mod.id}-#{i}",
|
|
||||||
label: label,
|
|
||||||
pos: "#{child_mod.x / 10},-#{child_mod.y / 10}!")
|
|
||||||
|
|
||||||
subg[subgraph_name].add_edges(parent, child_node)
|
|
||||||
end
|
|
||||||
elsif my_module.inputs.any?
|
|
||||||
parent = subg[subgraph_name]
|
|
||||||
.add_nodes("#{subgraph_name}-#{index}",
|
|
||||||
label: label,
|
|
||||||
pos: "#{my_module.x / 10},-#{my_module.y / 10}!")
|
|
||||||
|
|
||||||
my_module.inputs.each_with_index do |input, i|
|
|
||||||
child_mod = MyModule.find_by_id(input.output_id)
|
|
||||||
child_node = subg[subgraph_name]
|
|
||||||
.add_nodes("#{subgraph_name}-I#{child_mod.id}-#{i}",
|
|
||||||
label: label,
|
|
||||||
pos: "#{child_mod.x / 10},-#{child_mod.y / 10}!")
|
|
||||||
|
|
||||||
subg[subgraph_name].add_edges(child_node, parent)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
my_module_groups.each do |group|
|
|
||||||
group.ordered_modules.each_with_index do |my_module, index|
|
|
||||||
if my_module.outputs.any?
|
|
||||||
parent = graph.add_nodes("N-#{index}",
|
|
||||||
label: label,
|
|
||||||
pos: "#{my_module.x / 10},-#{ my_module.y / 10}!")
|
|
||||||
|
|
||||||
my_module.outputs.each_with_index do |output, i|
|
|
||||||
child_mod = MyModule.find_by_id(output.input_id)
|
|
||||||
child_node = graph
|
|
||||||
.add_nodes("N-O#{child_mod.id}-#{i}",
|
|
||||||
label: label,
|
|
||||||
pos: "#{child_mod.x / 10},-#{child_mod.y / 10}!")
|
|
||||||
graph.add_edges(parent, child_node)
|
|
||||||
end
|
|
||||||
elsif my_module.inputs.any?
|
|
||||||
parent = graph.add_nodes("N-#{index}",
|
|
||||||
label: label,
|
|
||||||
pos: "#{my_module.x / 10},-#{my_module.y / 10}!")
|
|
||||||
my_module.inputs.each_with_index do |input, i|
|
|
||||||
child_mod = MyModule.find_by_id(input.output_id)
|
|
||||||
child_node = graph
|
|
||||||
.add_nodes("N-I#{child_mod.id}-#{i}",
|
|
||||||
label: label,
|
|
||||||
pos: "#{child_mod.x / 10},-#{child_mod.y / 10}!")
|
|
||||||
graph.add_edges(child_node, parent)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
file_location = Tempfile.open(['wimg', '.png'],
|
|
||||||
Rails.root.join('tmp'))
|
|
||||||
|
|
||||||
graph.output(png: file_location.path)
|
|
||||||
|
|
||||||
begin
|
|
||||||
file = File.open(file_location)
|
|
||||||
self.workflowimg = file
|
|
||||||
file.close
|
|
||||||
save
|
|
||||||
touch(:workflowimg_updated_at)
|
|
||||||
rescue => ex
|
|
||||||
logger.error ex.message
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Clone this experiment to given project
|
# Clone this experiment to given project
|
||||||
|
|
7
app/services/executable_service.rb
Normal file
7
app/services/executable_service.rb
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module ExecutableService
|
||||||
|
def execute(*args)
|
||||||
|
new(*args).execute
|
||||||
|
end
|
||||||
|
end
|
89
app/services/workflow_image_generator.rb
Normal file
89
app/services/workflow_image_generator.rb
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class WorkflowImageGenerator
|
||||||
|
extend ExecutableService
|
||||||
|
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 execute
|
||||||
|
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
|
||||||
|
t_file = Tempfile.open(%w(wimg .png), Rails.root.join('tmp'))
|
||||||
|
@graph.output(png: t_file.path)
|
||||||
|
|
||||||
|
begin
|
||||||
|
file = File.open(t_file)
|
||||||
|
@exp.workflowimg = file
|
||||||
|
file.close
|
||||||
|
@exp.save
|
||||||
|
@exp.touch(:workflowimg_updated_at)
|
||||||
|
rescue StandardError => ex
|
||||||
|
logger.error ex.message
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
6
spec/services/workflow_image_generator_spec.rb
Normal file
6
spec/services/workflow_image_generator_spec.rb
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
describe WorkflowImageGenerator do
|
||||||
|
end
|
Loading…
Reference in a new issue