Class: T2Flow::Dot

Inherits:
Object
  • Object
show all
Defined in:
lib/t2flow/dot.rb

Overview

This class enables you to write the script will will be used by dot (which is part of GraphViz) to generate the image showing the structure of a given model. To get started quickly, you could try:

out_file = File.new("path/to/file/you/want/the/dot/script/to/be/written", "w+")
workflow = File.new("path/to/workflow/file", "r").read
model = T2Flow::Parser.new.parse(workflow)
T2Flow::Dot.new.write_dot(out_file, model)
`dot -Tpng -o"path/to/the/output/image" #{out_file.path}`

Constant Summary collapse

@@processor_colours =
{
'apiconsumer' => 'palegreen',
'beanshell' => 'burlywood2',
'biomart' => 'lightcyan2',                      
'local' => 'mediumorchid2',
'biomobywsdl' => 'darkgoldenrod1',
'biomobyobject' => 'gold',
'biomobyparser' => 'white',
'inferno' => 'violetred1',
'notification' => 'mediumorchid2',
'rdfgenerator' => 'purple',
'rserv' => 'lightgoldenrodyellow',
'seqhound' => '#836fff',
'soaplabwsdl' => 'lightgoldenrodyellow',
'stringconstant' => 'lightsteelblue',
'talisman' => 'plum2',
'bsf' => 'burlywood2',
'abstractprocessor' => 'lightgoldenrodyellow',
'rshell' => 'lightgoldenrodyellow',
'arbitrarywsdl' => 'darkolivegreen3',
'workflow' => 'crimson'}
@@fill_colours =
%w{white aliceblue antiquewhite beige}
@@ranksep =
'0.22'
@@nodesep =
'0.05'

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeDot

Creates a new dot object for interaction.



42
43
44
45
# File 'lib/t2flow/dot.rb', line 42

def initialize
  # @port_style IS CURRENTLY UNUSED. IGNORE!!!
  @port_style = 'none' # 'all', 'bound' or 'none'
end

Class Method Details

.is_processor?(processor_name) ⇒ Boolean

Returns true if the given name is a processor; false otherwise

Returns:

  • (Boolean)


244
245
246
# File 'lib/t2flow/dot.rb', line 244

def Dot.is_processor?(processor_name)
  true if @@processor_colours[processor_name]
end

Instance Method Details

#get_colour(processor_name) ⇒ Object

:nodoc:



234
235
236
237
238
239
240
241
# File 'lib/t2flow/dot.rb', line 234

def get_colour(processor_name) # :nodoc:
  colour = @@processor_colours[processor_name]
  if colour
    colour
  else 
    'white'
  end  
end

#write_coordination(stream, coordination, dataflow, prefix) ⇒ Object

:nodoc:



217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
# File 'lib/t2flow/dot.rb', line 217

def write_coordination(stream, coordination, dataflow, prefix) # :nodoc:
  stream.write " \"#{prefix}#{coordination.control}" 
  processor = dataflow.processors.select{|p| p.name == coordination.control}[0]
  
  stream.write 'WORKFLOWINTERNALSINKCONTROL' if "#{processor.type}" == "workflow"
  stream.write '"->"'
  stream.write "#{prefix}#{coordination.target}"
  processor = dataflow.processors.select{|p| p.name == coordination.target}[0]
  stream.write 'WORKFLOWINTERNALSOURCECONTROL' if "#{processor.type}" == "workflow"
  stream.write "\""
  stream.puts ' ['
  stream.puts '  color="gray",'
  stream.puts '  arrowhead="odot",'
  stream.puts '  arrowtail="none"'
  stream.puts ' ];'
end

#write_dataflow(stream, dataflow, prefix = "", name = "", depth = 0) ⇒ Object

:nodoc:



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/t2flow/dot.rb', line 89

def write_dataflow(stream, dataflow, prefix="", name="", depth=0) # :nodoc:
  if name != ""
    stream.puts "subgraph cluster_#{prefix}#{name} {"
    stream.puts " label=\"#{name}\""
    stream.puts ' fontname="Helvetica"'
    stream.puts ' fontsize="10"'
    stream.puts ' fontcolor="black"'
    stream.puts ' clusterrank="local"'
    stream.puts " fillcolor=\"#{@@fill_colours[depth % @@fill_colours.length]}\""
    stream.puts ' style="filled"'
  end
  dataflow.processors.each {|processor| write_processor(stream, processor, prefix, depth)}
  write_source_cluster(stream, dataflow.sources, prefix)
  write_sink_cluster(stream, dataflow.sinks, prefix)
  dataflow.datalinks.each {|link| write_link(stream, link, dataflow, prefix)}
  dataflow.coordinations.each {|coordination| write_coordination(stream, coordination, dataflow, prefix)}
  if name != ""
    stream.puts '}'
  end
end

#write_dot(stream, model) ⇒ Object

Writes to the given stream (File, StringIO, etc) the script to generate the image showing the internals of the given workflow model.

Usage

stream = File.new("path/to/file/you/want/the/dot/script/to/be/written", "w+")
workflow = .......
model = T2Flow::Parser.new.parse(workflow)
T2Flow::Dot.new.write_dot(stream, model)


54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/t2flow/dot.rb', line 54

def write_dot(stream, model)
  @t2flow_model = model
  stream.puts 'digraph t2flow_graph {'
  stream.puts ' graph ['
  stream.puts '  style=""'
  stream.puts '  labeljust="left"'
  stream.puts '  clusterrank="local"'
  stream.puts "  ranksep=\"#@@ranksep\""
  stream.puts "  nodesep=\"#@@nodesep\""
  stream.puts ' ]'
  stream.puts
  stream.puts ' node ['
  stream.puts '  fontname="Helvetica",'
  stream.puts '  fontsize="10",'
  stream.puts '  fontcolor="black", '
  stream.puts '  shape="box",'
  stream.puts '  height="0",'
  stream.puts '  width="0",'
  stream.puts '  color="black",'
  stream.puts '  fillcolor="lightgoldenrodyellow",'
  stream.puts '  style="filled"'
  stream.puts ' ];'
  stream.puts
  stream.puts ' edge ['
  stream.puts '  fontname="Helvetica",'
  stream.puts '  fontsize="8",'
  stream.puts '  fontcolor="black",'
  stream.puts '  color="black"'
  stream.puts ' ];'
  write_dataflow(stream, model.top_level)
  stream.puts '}'
  
  stream.flush
end

:nodoc:



189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/t2flow/dot.rb', line 189

def write_link(stream, link, dataflow, prefix) # :nodoc:
  if dataflow.sources.select{|s| s.name == link.source} != []
    stream.write " \"#{prefix}WORKFLOWINTERNALSOURCE_#{link.source}\""
  else 
    processor = dataflow.processors.select{|p| p.name == link.source.split(':')[0]}[0]
    if "#{processor.type}" == "workflow"
      df = @t2flow_model.dataflow(processor.dataflow_id)
      stream.write " \"#{prefix}#{df.annotations.name}WORKFLOWINTERNALSINK_#{link.source.split(':')[1]}\""
    else
      stream.write " \"#{prefix}#{processor.name}\""
    end
  end
  stream.write '->'
  if dataflow.sinks.select{|s| s.name == link.sink} != []
    stream.write "\"#{prefix}WORKFLOWINTERNALSINK_#{link.sink}\""
  else 
    processor = dataflow.processors.select{|p| p.name == link.sink.split(':')[0]}[0]
    if "#{processor.type}" == "workflow"
      df = @t2flow_model.dataflow(processor.dataflow_id)
      stream.write "\"#{prefix}#{df.annotations.name}WORKFLOWINTERNALSOURCE_#{link.sink.split(':')[1]}\""
    else
      stream.write "\"#{prefix}#{processor.name}\""
    end
  end
  stream.puts ' ['
  stream.puts ' ];'
end

#write_processor(stream, processor, prefix, depth) ⇒ Object

:nodoc:



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/t2flow/dot.rb', line 110

def write_processor(stream, processor, prefix, depth) # :nodoc:
  # nested workflows
  if "#{processor.type}" == "workflow"
    dataflow = @t2flow_model.dataflow(processor.dataflow_id)
    write_dataflow(stream, dataflow, prefix + dataflow.annotations.name, dataflow.annotations.name, depth.next)
  else
    stream.puts " \"#{prefix}#{processor.name}\" ["
    stream.puts "  fillcolor=\"#{get_colour processor.type}\","
    stream.puts '  shape="box",'
    stream.puts '  style="filled",'
    stream.puts '  height="0",'
    stream.puts '  width="0",'
    stream.puts "  label=\"#{processor.name}\""
    stream.puts ' ];'
  end
end

#write_sink(stream, sink, prefix) ⇒ Object

:nodoc:



179
180
181
182
183
184
185
186
187
# File 'lib/t2flow/dot.rb', line 179

def write_sink(stream, sink, prefix) # :nodoc:
  stream.puts " \"#{prefix}WORKFLOWINTERNALSINK_#{sink.name}\" ["
  stream.puts '   shape="box",'
  stream.puts "   label=\"#{sink.name}\""
  stream.puts '   width="0",'
  stream.puts '   height="0",'
  stream.puts '   fillcolor="lightsteelblue2"'
  stream.puts ' ]'     
end

#write_sink_cluster(stream, sinks, prefix) ⇒ Object

:nodoc:



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/t2flow/dot.rb', line 158

def write_sink_cluster(stream, sinks, prefix) # :nodoc:
  if sinks.length > 0
    stream.puts " subgraph cluster_#{prefix}sinks {"
    stream.puts '  style="dotted"'
    stream.puts '  label="Workflow Outputs"'
    stream.puts '  fontname="Helvetica"'
    stream.puts '  fontsize="10"'
    stream.puts '  fontcolor="black"'
    stream.puts '  rank="same"'
    stream.puts " \"#{prefix}WORKFLOWINTERNALSINKCONTROL\" ["
    stream.puts '  shape="invtriangle",'
    stream.puts '  width="0.2",'
    stream.puts '  height="0.2",'
    stream.puts '  fillcolor="chartreuse3"'
    stream.puts '  label=""'
    stream.puts ' ]'
    sinks.each {|sink| write_sink(stream, sink, prefix)}
    stream.puts ' }'
  end
end

#write_source(stream, source, prefix) ⇒ Object

:nodoc:



148
149
150
151
152
153
154
155
156
# File 'lib/t2flow/dot.rb', line 148

def write_source(stream, source, prefix) # :nodoc:
  stream.puts " \"#{prefix}WORKFLOWINTERNALSOURCE_#{source.name}\" ["
  stream.puts '   shape="box",'
  stream.puts "   label=\"#{source.name}\""
  stream.puts '   width="0",'
  stream.puts '   height="0",'
  stream.puts '   fillcolor="skyblue"'
  stream.puts ' ]' 
end

#write_source_cluster(stream, sources, prefix) ⇒ Object

:nodoc:



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/t2flow/dot.rb', line 127

def write_source_cluster(stream, sources, prefix) # :nodoc:
  if sources.length > 0
    stream.puts " subgraph cluster_#{prefix}sources {"
    stream.puts '  style="dotted"'
    stream.puts '  label="Workflow Inputs"'
    stream.puts '  fontname="Helvetica"'
    stream.puts '  fontsize="10"'
    stream.puts '  fontcolor="black"'
    stream.puts '  rank="same"'
    stream.puts " \"#{prefix}WORKFLOWINTERNALSOURCECONTROL\" ["
    stream.puts '  shape="triangle",'
    stream.puts '  width="0.2",'
    stream.puts '  height="0.2",'
    stream.puts '  fillcolor="brown1"'
    stream.puts '  label=""'
    stream.puts ' ]'
    sources.each {|source| write_source(stream, source, prefix)}
    stream.puts ' }'
  end
end