GraphvizR 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +6 -0
- data/lib/graphviz_r.rb +180 -359
- data/test/test_graphviz_r.rb +191 -189
- metadata +2 -2
data/History.txt
CHANGED
data/lib/graphviz_r.rb
CHANGED
@@ -140,364 +140,53 @@
|
|
140
140
|
# c -> d [ltail = cluster0];
|
141
141
|
# c -> f [lhead = cluster1];
|
142
142
|
#
|
143
|
-
class GraphvizR
|
144
|
-
VERSION = '0.
|
143
|
+
class GraphvizR
|
144
|
+
VERSION = '0.5.0'
|
145
145
|
INDENT_UNIT = ' '
|
146
146
|
|
147
|
-
|
148
|
-
class Attributes
|
149
|
-
def initialize(name, dot)
|
150
|
-
@name = name
|
151
|
-
@dot = dot
|
152
|
-
end
|
153
|
-
|
154
|
-
def [](attr)
|
155
|
-
@dot.send :"#{@name}=", attr
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
# This represents graphviz node.
|
160
|
-
class Node
|
161
|
-
attr_reader :attr, :name
|
162
|
-
|
163
|
-
def initialize(name, port, dot)
|
164
|
-
@name = name
|
165
|
-
@port = port || []
|
166
|
-
@dot = dot
|
167
|
-
@attr = {}
|
168
|
-
|
169
|
-
if !@port.empty? and @port[0].is_a? Array and @port[0][0].is_a? Hash
|
170
|
-
@dot[@name] = @port[0][0]
|
171
|
-
end
|
172
|
-
end
|
173
|
-
|
174
|
-
# This generates a directed edge from this node to given node.
|
175
|
-
def >>(node)
|
176
|
-
@dot.directed!
|
177
|
-
add_edge_on_dot node
|
178
|
-
end
|
179
|
-
|
180
|
-
# This generates a undirected edge from this node to given node.
|
181
|
-
def -(node)
|
182
|
-
@dot.undirected!
|
183
|
-
add_edge_on_dot node
|
184
|
-
end
|
185
|
-
|
186
|
-
def add_edge_on_dot(node)
|
187
|
-
attr = nil
|
188
|
-
if node.is_a? Array
|
189
|
-
node = NodeGroup.new node
|
190
|
-
attr = @attr
|
191
|
-
else
|
192
|
-
attr = @attr.merge node.attr
|
193
|
-
end
|
194
|
-
edge = Edge.new([self, node], @dot, attr)
|
195
|
-
@dot.add_edge edge
|
196
|
-
edge
|
197
|
-
end
|
198
|
-
|
199
|
-
def [](attr)
|
200
|
-
@dot[@name] = attr
|
201
|
-
@attr.merge! attr
|
202
|
-
self
|
203
|
-
end
|
204
|
-
|
205
|
-
def <=>(other)
|
206
|
-
@name <=> other.name
|
207
|
-
end
|
208
|
-
|
209
|
-
def to_sym
|
210
|
-
self
|
211
|
-
end
|
212
|
-
|
213
|
-
def to_dot
|
214
|
-
name = @port.dup
|
215
|
-
name.unshift @name
|
216
|
-
name.map{|e| e.to_dot}.join(':')
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
|
-
# Aggregate some nodes.
|
221
|
-
class NodeGroup
|
222
|
-
def initialize(nodes, attr={})
|
223
|
-
@nodes = nodes
|
224
|
-
@attributes = attr
|
225
|
-
end
|
226
|
-
|
227
|
-
def to_sym
|
228
|
-
to_dot.to_sym
|
229
|
-
end
|
230
|
-
|
231
|
-
def to_dot
|
232
|
-
dot = "{"
|
233
|
-
dot += @attributes.to_a.map{|e| "#{e[0]} = #{e[1]};"}.join(' ') unless @attributes.empty?
|
234
|
-
dot += ' ' unless @attributes.empty?
|
235
|
-
dot += @nodes.map{|e| "#{e.to_dot};"}.join(' ')
|
236
|
-
dot += "}"
|
237
|
-
end
|
238
|
-
end
|
239
|
-
|
240
|
-
# This represents a graphviz edge.
|
241
|
-
class Edge
|
242
|
-
def initialize(nodes, dot, attr={})
|
243
|
-
@nodes = nodes
|
244
|
-
@dot = dot
|
245
|
-
@attribute = attr
|
246
|
-
end
|
247
|
-
|
248
|
-
def [](attr)
|
249
|
-
@attribute.merge! attr
|
250
|
-
end
|
251
|
-
|
252
|
-
def >>(node, attr={})
|
253
|
-
@nodes << node
|
254
|
-
self[attr]
|
255
|
-
self
|
256
|
-
end
|
257
|
-
|
258
|
-
def node_to_dot(node)
|
259
|
-
node.is_a?(Array) ? node.map{|e| e.to_sym.to_dot}.join(':') : node.to_sym.to_dot
|
260
|
-
end
|
261
|
-
|
262
|
-
def to_dot
|
263
|
-
dot = @nodes.map{|e| node_to_dot e}.join " #{@dot.arrow} "
|
264
|
-
dot += " #{@attribute.to_dot}" unless @attribute.empty?
|
265
|
-
dot
|
266
|
-
end
|
267
|
-
|
268
|
-
def <=>(other)
|
269
|
-
to_dot <=> other.to_dot
|
270
|
-
end
|
271
|
-
end
|
272
|
-
|
273
|
-
# This returns dot formatted string from given attributes. To know more about <tt>attr</tt>,
|
274
|
-
# please see GraphvizR.new .
|
275
|
-
def self.dot(name, attr)
|
276
|
-
GraphvizR.new(name, attr).to_dot
|
277
|
-
end
|
147
|
+
attr_reader :statements, :graph_type
|
278
148
|
|
279
149
|
# This initialzes a GraphvizR instance.
|
280
150
|
# +name+:: the name of the graph
|
281
|
-
# +attr+:: <b>!deprecated!</b> all attributes for a graph can be given as a hash instance.
|
282
|
-
# Please guess the contents of the hash from the test or examples below:
|
283
|
-
# gvr = GraphvizR.dot(:sample,
|
284
|
-
# :graph => {:size => "1.5, 2.5"},
|
285
|
-
# :label => 'example',
|
286
|
-
# :node_attributes => {
|
287
|
-
# :beta => {:shape => :box},
|
288
|
-
# },
|
289
|
-
# :alpha => :beta,
|
290
|
-
# {:alpha => :gamma} => {:label => 'label1'},
|
291
|
-
# :beta => :delta,
|
292
|
-
# :delta => 'size'
|
293
|
-
# )
|
294
|
-
#
|
295
|
-
# gvr = GraphvizR.dot(:sample,
|
296
|
-
# :graph => {:size => "1.5, 2.5"},
|
297
|
-
# :node => {:shape => :record},
|
298
|
-
# :node_attributes => {
|
299
|
-
# :node1 => {:label => "<p_left> left|<p_center>center|<p_right> right"},
|
300
|
-
# :node2 => {:label => "left|center|right"}
|
301
|
-
# },
|
302
|
-
# :node1 => :node2,
|
303
|
-
# [:node1, :p_left] => :node2,
|
304
|
-
# :node2 => [:node1, :p_center],
|
305
|
-
# {:node2 => [:node1, :p_right]} => {:label => 'record'}
|
306
|
-
# )
|
307
|
-
#
|
308
|
-
# gvr = GraphvizR.dot(:sample,
|
309
|
-
# :subgraphs => {
|
310
|
-
# :cluster0 => {
|
311
|
-
# :color => :blue,
|
312
|
-
# :style => :bold,
|
313
|
-
# :label => "area 0",
|
314
|
-
# {:a => :b} => {},
|
315
|
-
# :a => :c
|
316
|
-
# },
|
317
|
-
# :cluster1 => {
|
318
|
-
# :fillcolor => "#cc9966",
|
319
|
-
# :style => :filled,
|
320
|
-
# :label => "area 1",
|
321
|
-
# [:d] => :e,
|
322
|
-
# :d => :f
|
323
|
-
# }
|
324
|
-
# },
|
325
|
-
# :b => :d,
|
326
|
-
# {:c => :d} => {:ltail => :cluster0},
|
327
|
-
# {:c => :f} => {:lhead => :cluster1},
|
328
|
-
# {:a => :f} => {:ltail => :cluster0, :lhead => :cluster1}
|
329
|
-
# )
|
330
151
|
# +parent+:: a parent graph is given when this graph is a subgraph.
|
331
152
|
# +indent+:: indent level when this instance is converted to rdot.
|
332
|
-
def initialize(name,
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
@indent = indent + 1
|
345
|
-
@parent = parent
|
346
|
-
@directed = true
|
347
|
-
interprete attr
|
348
|
-
end
|
349
|
-
end
|
350
|
-
|
351
|
-
def interprete(attr) #:nodoc:
|
352
|
-
attr.each do |k, v|
|
353
|
-
case k
|
354
|
-
when :node_attribute, :node_attributes
|
355
|
-
add_node_attributes v
|
356
|
-
when :graph
|
357
|
-
@default_graph_attributes.merge! v
|
358
|
-
when :label, :size, :color, :fillcolor, :style
|
359
|
-
@default_graph_attributes[k] = v
|
360
|
-
when :node
|
361
|
-
@default_node_attributes[k] = v
|
362
|
-
when :edge
|
363
|
-
@default_edge_attributes[k] = v
|
364
|
-
when :subgraphs
|
365
|
-
add_subgraph(v)
|
366
|
-
else
|
367
|
-
add_edge k, v
|
368
|
-
end
|
369
|
-
end
|
370
|
-
end
|
371
|
-
|
372
|
-
# add attributes for nodes
|
373
|
-
def add_node_attributes(attrs)
|
374
|
-
@node_attributes = attrs
|
375
|
-
end
|
376
|
-
|
377
|
-
# add an edge to the graph
|
378
|
-
def add_edge(from, to=nil)
|
379
|
-
if from.is_a? Hash
|
380
|
-
f = from.keys[0]
|
381
|
-
t = from[f]
|
382
|
-
p = to
|
383
|
-
@edges << Edge.new([f, t], self, p)
|
384
|
-
elsif to.nil?
|
385
|
-
# from is Edge instance
|
386
|
-
@edges << from
|
387
|
-
else
|
388
|
-
@edges << Edge.new([from, to], self)
|
389
|
-
end
|
390
|
-
end
|
391
|
-
|
392
|
-
# add subgraph
|
393
|
-
def add_subgraph(graphs)
|
394
|
-
graphs.to_a.sort.each do |key_attr|
|
395
|
-
@subgraphs << self.class.new(key_attr[0], key_attr[1], self, @indent)
|
396
|
-
end
|
397
|
-
end
|
398
|
-
|
399
|
-
# is this graph subgraph or not.
|
400
|
-
def subgraph?
|
401
|
-
not @parent.nil?
|
402
|
-
end
|
403
|
-
|
404
|
-
# make this graph directed
|
405
|
-
def directed!
|
406
|
-
if subgraph?
|
407
|
-
@parent.directed!
|
408
|
-
else
|
409
|
-
@directed = true
|
410
|
-
end
|
411
|
-
end
|
412
|
-
|
413
|
-
# make this graph undirected
|
414
|
-
def undirected!
|
415
|
-
if subgraph?
|
416
|
-
@parent.undirected!
|
417
|
-
else
|
418
|
-
@directed = false
|
419
|
-
end
|
420
|
-
end
|
421
|
-
|
422
|
-
# is this graph directed?
|
423
|
-
def directed?
|
424
|
-
if subgraph?
|
425
|
-
@parent.directed?
|
426
|
-
else
|
427
|
-
@directed
|
428
|
-
end
|
429
|
-
end
|
430
|
-
|
431
|
-
# is this graph undirected?
|
432
|
-
def undirected?
|
433
|
-
if subgraph?
|
434
|
-
@parent.undirected?
|
435
|
-
else
|
436
|
-
!@directed
|
437
|
-
end
|
438
|
-
end
|
439
|
-
|
440
|
-
def arrow
|
441
|
-
directed? ? '->' : '--'
|
442
|
-
end
|
443
|
-
|
444
|
-
# When block is given, create new subgraph. Otherwise, create new node.
|
445
|
-
def [](key, *args, &block)
|
153
|
+
def initialize(name, parent=nil, indent=0)
|
154
|
+
@name = name
|
155
|
+
@parent = parent
|
156
|
+
@graph_type = 'digraph'
|
157
|
+
@indent = indent
|
158
|
+
@directed = true
|
159
|
+
@statements = []
|
160
|
+
end
|
161
|
+
|
162
|
+
# if block is not given, this generates a node.
|
163
|
+
# if block given, generates a subgraph.
|
164
|
+
def [](name, *args, &block)
|
446
165
|
if block
|
447
|
-
subgraph = self.class.new
|
166
|
+
subgraph = self.class.new name, self, @indent + 1
|
448
167
|
block.call subgraph
|
449
|
-
@
|
168
|
+
@statements << subgraph
|
450
169
|
else
|
451
|
-
Node.new
|
170
|
+
node = Node.new name, args, self
|
171
|
+
@statements << node
|
172
|
+
node
|
452
173
|
end
|
453
174
|
end
|
454
175
|
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
end
|
459
|
-
|
460
|
-
[:label, :size, :color, :fillcolor, :style].each do |method|
|
461
|
-
define_method :"#{method}=" do |v|
|
462
|
-
@default_graph_attributes[method] = v
|
176
|
+
['digraph', 'graph', 'subgraph'].each do |graph_type|
|
177
|
+
define_method :"to_#{graph_type}" do
|
178
|
+
@graph_type = graph_type
|
463
179
|
end
|
464
180
|
end
|
465
181
|
|
466
|
-
# set
|
467
|
-
def
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
self.graph = args[0][0]
|
182
|
+
# set all nodes as same level
|
183
|
+
def rank(same, nodes=[])
|
184
|
+
group = NodeGroup.new nodes, :rank => same
|
185
|
+
nodes.size.times do
|
186
|
+
@statements.pop
|
472
187
|
end
|
473
|
-
|
474
|
-
|
475
|
-
# set graph attributes
|
476
|
-
def graph=(attr)
|
477
|
-
@default_graph_attributes.merge! attr
|
478
|
-
end
|
479
|
-
|
480
|
-
def rank(same, nodes)
|
481
|
-
@node_groups << (NodeGroup.new nodes, {:rank => same})
|
482
|
-
end
|
483
|
-
|
484
|
-
# convert this instance to dot
|
485
|
-
def to_dot
|
486
|
-
graph_type = if subgraph?; 'subgraph'elsif directed?; 'digraph' else 'graph' end
|
487
|
-
dot = indent_enter("#{graph_type} #{@name} {", true)
|
488
|
-
dot += indent_enter("graph #{@default_graph_attributes.to_dot};") unless @default_graph_attributes.empty?
|
489
|
-
dot += @subgraphs.map{|e| e.to_dot}.join('') unless @subgraphs.empty?
|
490
|
-
dot += attributes_to_dot(@default_node_attributes) unless @default_node_attributes.empty?
|
491
|
-
dot += attributes_to_dot(@default_edge_attributes) unless @default_edge_attributes.empty?
|
492
|
-
dot += attributes_to_dot(@node_attributes) unless @node_attributes.empty?
|
493
|
-
dot += @edges.sort.map{|e| indent_enter("#{e.to_dot};")}.join("")
|
494
|
-
dot += @node_groups.map{|e| indent_enter("#{e.to_dot};")}.join("")
|
495
|
-
dot += indent_enter("}", true)
|
496
|
-
dot
|
497
|
-
end
|
498
|
-
|
499
|
-
def indent_enter(str, is_first=false) #:nodoc:
|
500
|
-
"#{INDENT_UNIT * (@indent - (is_first ? 1 : 0))}#{str}\n"
|
188
|
+
@statements << group
|
189
|
+
group
|
501
190
|
end
|
502
191
|
|
503
192
|
# If <tt>format</tt> is 'dot', a dot string is generated. Otherwise, this generates image file
|
@@ -527,25 +216,152 @@ class GraphvizR
|
|
527
216
|
end
|
528
217
|
end
|
529
218
|
|
219
|
+
# convert this instance to dot
|
220
|
+
def to_dot(indent=@indent)
|
221
|
+
to_subgraph if @parent
|
222
|
+
dot = INDENT_UNIT * indent
|
223
|
+
dot += "#{@graph_type} #{@name} {\n"
|
224
|
+
@statements.each do |statement|
|
225
|
+
dot += statement.to_dot(indent + 1)
|
226
|
+
end
|
227
|
+
dot += INDENT_UNIT * indent
|
228
|
+
dot += "}\n"
|
229
|
+
dot
|
230
|
+
end
|
231
|
+
|
232
|
+
# redirect to [] method.
|
530
233
|
def method_missing(name, *args, &block) #:nodoc:
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
234
|
+
self.send(:"[]", name, *args, &block)
|
235
|
+
end
|
236
|
+
|
237
|
+
# This represents graphviz node.
|
238
|
+
class Node
|
239
|
+
attr_reader :name, :parent
|
240
|
+
|
241
|
+
def initialize(name, args, parent)
|
242
|
+
@parent = parent
|
243
|
+
@name = name
|
244
|
+
@edge = nil
|
245
|
+
@port = nil
|
246
|
+
@attributes = {}
|
247
|
+
unless args.empty?
|
248
|
+
arg = args[0]
|
249
|
+
if arg.is_a? Symbol
|
250
|
+
@port = arg
|
251
|
+
@attributes = {}
|
252
|
+
elsif arg.is_a? Array
|
253
|
+
@port = nil
|
254
|
+
@attributes = arg[0]
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
# if blank between node and attributes does not exist, this method is used.
|
260
|
+
# otherwise GraphvizR#[] is used.
|
261
|
+
# ex) gvr.graph[:label => 'example', :size => '1.5, 2.5']
|
262
|
+
def [](attributes)
|
263
|
+
@attributes = attributes
|
264
|
+
end
|
265
|
+
|
266
|
+
# generate an edge from self to given node.
|
267
|
+
# this generates a directed edge.
|
268
|
+
def >>(node)
|
269
|
+
@parent.to_digraph
|
270
|
+
@edge = Edge.new self, node, @parent
|
271
|
+
end
|
272
|
+
|
273
|
+
# generate an edge from self to given node.
|
274
|
+
# this generates a undirected edge.
|
275
|
+
def -(node)
|
276
|
+
@parent.to_graph
|
277
|
+
@edge = Edge.new self, node, @parent, '--'
|
278
|
+
end
|
279
|
+
|
280
|
+
# to string
|
281
|
+
def to_s
|
282
|
+
if @port
|
283
|
+
"#{@name}:#{@port}"
|
284
|
+
else
|
285
|
+
@name
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
# to dot format
|
290
|
+
def to_dot(indent=0)
|
291
|
+
attributes = @attributes.empty? ? '' : ' ' + @attributes.to_dot
|
292
|
+
"#{INDENT_UNIT * indent}#{@name}#{attributes};\n"
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
# This represents a graphviz edge.
|
297
|
+
class Edge
|
298
|
+
def initialize(from, to, parent, arrow='->')
|
299
|
+
@attributes = {}
|
300
|
+
@nodes = [from, to]
|
301
|
+
@arrow = arrow
|
302
|
+
@parent = parent
|
303
|
+
(from.is_a?(Array) ? from : [from]).size.times do
|
304
|
+
@parent.statements.pop
|
305
|
+
end
|
306
|
+
(to.is_a?(Array) ? to : [to]).size.times do
|
307
|
+
@parent.statements.pop
|
308
|
+
end
|
309
|
+
@parent.statements << self
|
310
|
+
end
|
311
|
+
|
312
|
+
# set attributes for the edge
|
313
|
+
def [](attributes)
|
314
|
+
@attributes = attributes
|
315
|
+
end
|
316
|
+
|
317
|
+
# consequent directed edge
|
318
|
+
def >>(node)
|
319
|
+
@parent.to_digraph
|
320
|
+
(node.is_a?(Array) ? node : [node]).size.times do
|
321
|
+
@parent.statements.pop
|
322
|
+
end
|
323
|
+
@nodes << node
|
324
|
+
self
|
325
|
+
end
|
326
|
+
|
327
|
+
# consequent undirected edge
|
328
|
+
def -(node)
|
329
|
+
@parent.to_graph
|
330
|
+
(node.is_a?(Array) ? node : [node]).size.times do
|
331
|
+
@parent.statements.pop
|
332
|
+
end
|
333
|
+
@nodes << node
|
334
|
+
self
|
335
|
+
end
|
336
|
+
|
337
|
+
# to dot
|
338
|
+
def to_dot(indent)
|
339
|
+
edge = @nodes.map{|e| e.is_a?(Array) ? e.to_dot : e.to_s}.join(" #{@arrow} ")
|
340
|
+
attributes = @attributes.empty? ? '' : ' ' + @attributes.to_dot
|
341
|
+
"#{INDENT_UNIT * indent}#{edge}#{attributes};\n"
|
537
342
|
end
|
538
|
-
self.send(method, name, *args, &block)
|
539
343
|
end
|
540
344
|
|
541
|
-
|
345
|
+
# this represent a group of nodes
|
346
|
+
class NodeGroup
|
347
|
+
def initialize(nodes, opts)
|
348
|
+
@nodes = nodes
|
349
|
+
@opts = opts
|
350
|
+
end
|
542
351
|
|
543
|
-
|
544
|
-
|
352
|
+
def to_dot(indent)
|
353
|
+
options = @opts.to_a.map{|e| "#{e[0]} = #{e[1]};"}.join ' '
|
354
|
+
nodes = @nodes.map{|e| "#{e.to_s};"}.join ' '
|
355
|
+
"#{INDENT_UNIT * indent}{#{options} #{nodes}};\n"
|
356
|
+
end
|
545
357
|
end
|
546
358
|
end
|
547
359
|
|
548
|
-
class
|
360
|
+
class Symbol #:nodoc:
|
361
|
+
def <=>(other)
|
362
|
+
to_s <=> other.to_s
|
363
|
+
end
|
364
|
+
|
549
365
|
def to_dot
|
550
366
|
to_s
|
551
367
|
end
|
@@ -557,18 +373,23 @@ class String #:nodoc:
|
|
557
373
|
end
|
558
374
|
end
|
559
375
|
|
560
|
-
class
|
376
|
+
class Hash #:nodoc:
|
561
377
|
def to_dot
|
562
|
-
|
378
|
+
"[#{to_a.sort.map{|e| "#{e[0].to_dot} = #{e[1].to_dot}"}.join(', ')}]"
|
563
379
|
end
|
380
|
+
end
|
564
381
|
|
565
|
-
|
566
|
-
|
382
|
+
class Array #:nodoc:
|
383
|
+
def >>(node)
|
384
|
+
raise NoMethodError if empty? or not node.is_a? GraphvizR::Node
|
385
|
+
|
386
|
+
parent = self[0].parent
|
387
|
+
parent.to_digraph
|
388
|
+
GraphvizR::Edge.new self, node, parent
|
567
389
|
end
|
568
|
-
end
|
569
390
|
|
570
|
-
class Hash #:nodoc:
|
571
391
|
def to_dot
|
572
|
-
"
|
392
|
+
"{#{self.map{|e| e.to_s}.join('; ')};}"
|
573
393
|
end
|
574
394
|
end
|
395
|
+
|
data/test/test_graphviz_r.rb
CHANGED
@@ -1,181 +1,156 @@
|
|
1
|
-
# ref. http://homepage3.nifty.com/kaku-chan/graphviz/index.html
|
2
|
-
|
3
1
|
require 'test/unit'
|
4
2
|
require 'graphviz_r'
|
5
3
|
|
6
4
|
class TestGraphvizR < Test::Unit::TestCase
|
7
|
-
def
|
8
|
-
|
5
|
+
def test_access_as_hash
|
6
|
+
gvr = GraphvizR.new 'sample'
|
7
|
+
(gvr['alpha'] >> gvr['beta']) [:label => "label1"]
|
8
|
+
|
9
|
+
assert_equal <<-end_of_string, gvr.to_dot
|
10
|
+
digraph sample {
|
11
|
+
alpha -> beta [label = "label1"];
|
12
|
+
}
|
13
|
+
end_of_string
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_no_node
|
17
|
+
gvr = GraphvizR.new 'sample'
|
18
|
+
|
19
|
+
assert_equal <<-end_of_string, gvr.to_dot
|
20
|
+
digraph sample {
|
21
|
+
}
|
22
|
+
end_of_string
|
9
23
|
end
|
10
24
|
|
11
|
-
def
|
12
|
-
|
25
|
+
def test_just_node
|
26
|
+
gvr = GraphvizR.new 'sample'
|
27
|
+
gvr.alpha
|
28
|
+
|
29
|
+
assert_equal <<-end_of_string, gvr.to_dot
|
30
|
+
digraph sample {
|
31
|
+
alpha;
|
32
|
+
}
|
33
|
+
end_of_string
|
13
34
|
end
|
14
35
|
|
15
|
-
def
|
16
|
-
|
36
|
+
def test_graph_setting
|
37
|
+
gvr = GraphvizR.new 'sample'
|
38
|
+
gvr.graph [:label => 'example', :size => '1.5, 2.5']
|
39
|
+
|
40
|
+
assert_equal <<-end_of_string, gvr.to_dot
|
41
|
+
digraph sample {
|
42
|
+
graph [label = "example", size = "1.5, 2.5"];
|
43
|
+
}
|
44
|
+
end_of_string
|
17
45
|
end
|
18
46
|
|
19
|
-
def
|
20
|
-
gvr = GraphvizR.
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
:beta => {:shape => :box},
|
25
|
-
},
|
26
|
-
:alpha => :beta,
|
27
|
-
{:alpha => :gamma} => {:label => 'label1'},
|
28
|
-
:beta => :delta,
|
29
|
-
:delta => 'size'
|
30
|
-
)
|
31
|
-
|
32
|
-
assert_equal <<-end_of_string, gvr
|
47
|
+
def test_graph_setting_without_blank
|
48
|
+
gvr = GraphvizR.new 'sample'
|
49
|
+
gvr.graph[:label => 'example', :size => '1.5, 2.5']
|
50
|
+
|
51
|
+
assert_equal <<-end_of_string, gvr.to_dot
|
33
52
|
digraph sample {
|
34
53
|
graph [label = "example", size = "1.5, 2.5"];
|
35
|
-
beta [shape = box];
|
36
|
-
alpha -> beta;
|
37
|
-
alpha -> gamma [label = "label1"];
|
38
|
-
beta -> delta;
|
39
|
-
delta -> size;
|
40
54
|
}
|
41
55
|
end_of_string
|
42
56
|
end
|
43
57
|
|
44
|
-
|
45
|
-
#gvr.beta = {:shape => :box}
|
46
|
-
#gvr.graph[:label => 'example', :size => '1.5, 2.5']
|
47
|
-
#gvr.beta[:shape => :box]
|
48
|
-
def test_basic_dynamic
|
58
|
+
def test_edge
|
49
59
|
gvr = GraphvizR.new 'sample'
|
50
|
-
gvr.graph [:label => 'example', :size => '1.5, 2.5']
|
51
|
-
gvr.beta [:shape => :box]
|
52
60
|
gvr.alpha >> gvr.beta
|
53
|
-
(gvr.alpha >> gvr.gamma) [:label => 'label1']
|
54
|
-
(gvr.beta >> gvr.delta) [:label => 'label2']
|
55
|
-
gvr.delta >> gvr[:size]
|
56
61
|
|
57
62
|
assert_equal <<-end_of_string, gvr.to_dot
|
58
63
|
digraph sample {
|
59
|
-
graph [label = "example", size = "1.5, 2.5"];
|
60
|
-
beta [shape = box];
|
61
64
|
alpha -> beta;
|
62
|
-
alpha -> gamma [label = "label1"];
|
63
|
-
beta -> delta [label = "label2"];
|
64
|
-
delta -> size;
|
65
65
|
}
|
66
66
|
end_of_string
|
67
67
|
end
|
68
68
|
|
69
|
-
def
|
70
|
-
gvr = GraphvizR.
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
assert_equal <<-end_of_string, gvr
|
69
|
+
def test_edge_with_attributes
|
70
|
+
gvr = GraphvizR.new 'sample'
|
71
|
+
(gvr.alpha >> gvr.beta) [:label => 'label1']
|
72
|
+
|
73
|
+
assert_equal <<-end_of_string, gvr.to_dot
|
74
|
+
digraph sample {
|
75
|
+
alpha -> beta [label = "label1"];
|
76
|
+
}
|
77
|
+
end_of_string
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_edge_with_attributes_without_blank
|
81
|
+
gvr = GraphvizR.new 'sample'
|
82
|
+
(gvr.alpha >> gvr.beta)[:label => 'label1']
|
83
|
+
|
84
|
+
assert_equal <<-end_of_string, gvr.to_dot
|
85
85
|
digraph sample {
|
86
|
-
|
87
|
-
node [shape = record];
|
88
|
-
edge [fontsize = 24];
|
89
|
-
node1 [label = "<p_left> left|<p_center>center|<p_right> right"];
|
90
|
-
node2 [label = "left|center|right"];
|
91
|
-
node1 -> node2;
|
92
|
-
node1:p_left -> node2;
|
93
|
-
node2 -> node1:p_center;
|
94
|
-
node2 -> node1:p_right [label = "record"];
|
86
|
+
alpha -> beta [label = "label1"];
|
95
87
|
}
|
96
88
|
end_of_string
|
97
89
|
end
|
98
90
|
|
99
|
-
|
100
|
-
#gvr.node = {:shape => :record}
|
101
|
-
#d gvr.node1 = {:label => "<p_left> left|<p_center>center|<p_right> right"}
|
102
|
-
#gvr.node2 = {:label => "left|center|right"}
|
103
|
-
def test_record_dynamic
|
91
|
+
def test_record_edge
|
104
92
|
gvr = GraphvizR.new 'sample'
|
105
|
-
gvr.graph [:size => '1.5, 2.5']
|
106
|
-
gvr.node [:shape => :record]
|
107
|
-
gvr.node1 [:label => "<p_left> left|<p_center>center|<p_right> right"]
|
108
|
-
gvr.node2 [:label => "left|center|right"]
|
109
|
-
gvr.node1 >> gvr.node2
|
110
93
|
gvr.node1(:p_left) >> gvr.node2
|
111
94
|
gvr.node2 >> gvr.node1(:p_center)
|
112
|
-
(gvr.node2 >> gvr.node1(:p_right)) [:label => 'record']
|
113
95
|
|
114
96
|
assert_equal <<-end_of_string, gvr.to_dot
|
115
97
|
digraph sample {
|
116
|
-
graph [size = "1.5, 2.5"];
|
117
|
-
node [shape = record];
|
118
|
-
node1 [label = "<p_left> left|<p_center>center|<p_right> right"];
|
119
|
-
node2 [label = "left|center|right"];
|
120
|
-
node1 -> node2;
|
121
98
|
node1:p_left -> node2;
|
122
99
|
node2 -> node1:p_center;
|
100
|
+
}
|
101
|
+
end_of_string
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_record_edge_with_attributes
|
105
|
+
gvr = GraphvizR.new 'sample'
|
106
|
+
(gvr.node2 >> gvr.node1(:p_right)) [:label => 'record']
|
107
|
+
|
108
|
+
assert_equal <<-end_of_string, gvr.to_dot
|
109
|
+
digraph sample {
|
123
110
|
node2 -> node1:p_right [label = "record"];
|
124
111
|
}
|
125
112
|
end_of_string
|
126
113
|
end
|
127
114
|
|
128
|
-
def
|
129
|
-
gvr = GraphvizR.
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
115
|
+
def test_simple_graph
|
116
|
+
gvr = GraphvizR.new 'sample'
|
117
|
+
gvr.graph [:label => 'example', :size => '1.5, 2.5']
|
118
|
+
gvr.beta [:shape => :box]
|
119
|
+
gvr.alpha >> gvr.beta
|
120
|
+
(gvr.alpha >> gvr.gamma) [:label => 'label1']
|
121
|
+
(gvr.beta >> gvr.delta) [:label => 'label2']
|
122
|
+
gvr.delta >> gvr[:size]
|
123
|
+
|
124
|
+
assert_equal <<-end_of_string, gvr.to_dot
|
125
|
+
digraph sample {
|
126
|
+
graph [label = "example", size = "1.5, 2.5"];
|
127
|
+
beta [shape = box];
|
128
|
+
alpha -> beta;
|
129
|
+
alpha -> gamma [label = "label1"];
|
130
|
+
beta -> delta [label = "label2"];
|
131
|
+
delta -> size;
|
132
|
+
}
|
133
|
+
end_of_string
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_define_subgraph
|
137
|
+
gvr = GraphvizR.new 'sample'
|
138
|
+
gvr.cluster0 do |c0|
|
139
|
+
c0.graph [:color => :blue, :label => 'area 0', :style => :bold]
|
140
|
+
c0.a >> c0.b
|
141
|
+
end
|
142
|
+
|
143
|
+
assert_equal <<-end_of_string, gvr.to_dot
|
153
144
|
digraph sample {
|
154
145
|
subgraph cluster0 {
|
155
146
|
graph [color = blue, label = "area 0", style = bold];
|
156
147
|
a -> b;
|
157
|
-
a -> c;
|
158
|
-
}
|
159
|
-
subgraph cluster1 {
|
160
|
-
graph [fillcolor = "#cc9966", label = "area 1", style = filled];
|
161
|
-
d -> e;
|
162
|
-
d -> f;
|
163
148
|
}
|
164
|
-
a -> f [lhead = cluster1, ltail = cluster0];
|
165
|
-
b -> d;
|
166
|
-
c -> d [ltail = cluster0];
|
167
|
-
c -> f [lhead = cluster1];
|
168
149
|
}
|
169
150
|
end_of_string
|
170
151
|
end
|
171
152
|
|
172
|
-
|
173
|
-
#c0.label = 'area 0'
|
174
|
-
#c0.style = :bold
|
175
|
-
#c1.fillcolor = '#cc9966'
|
176
|
-
#c1.label = 'area 1'
|
177
|
-
#c1.style = :filled
|
178
|
-
def test_subgrpah_dynamic
|
153
|
+
def test_subgraph
|
179
154
|
gvr = GraphvizR.new 'sample'
|
180
155
|
gvr.cluster0 do |c0|
|
181
156
|
c0.graph [:color => :blue, :label => 'area 0', :style => :bold]
|
@@ -214,26 +189,18 @@ digraph sample {
|
|
214
189
|
|
215
190
|
def test_undirected_graph
|
216
191
|
gvr = GraphvizR.new 'sample'
|
217
|
-
gvr.graph [:label => 'example', :size => '1.5, 2.5']
|
218
|
-
gvr.beta [:shape => :box]
|
219
192
|
gvr.alpha - gvr.beta
|
220
|
-
(gvr.
|
221
|
-
(gvr.beta - gvr.delta) [:label => 'label2']
|
222
|
-
gvr.delta - gvr[:size]
|
193
|
+
(gvr.beta - gvr.gamma) [:label => 'label2']
|
223
194
|
|
224
195
|
assert_equal <<-end_of_string, gvr.to_dot
|
225
196
|
graph sample {
|
226
|
-
graph [label = "example", size = "1.5, 2.5"];
|
227
|
-
beta [shape = box];
|
228
197
|
alpha -- beta;
|
229
|
-
|
230
|
-
beta -- delta [label = "label2"];
|
231
|
-
delta -- size;
|
198
|
+
beta -- gamma [label = "label2"];
|
232
199
|
}
|
233
200
|
end_of_string
|
234
201
|
end
|
235
202
|
|
236
|
-
def
|
203
|
+
def test_undirected_subgraph
|
237
204
|
gvr = GraphvizR.new 'sample'
|
238
205
|
gvr.cluster0 do |c0|
|
239
206
|
c0.graph [:color => :blue, :label => 'area 0', :style => :bold]
|
@@ -270,98 +237,133 @@ graph sample {
|
|
270
237
|
end_of_string
|
271
238
|
end
|
272
239
|
|
273
|
-
def
|
240
|
+
def test_consective_edges
|
274
241
|
gvr = GraphvizR.new 'sample'
|
275
|
-
gvr.graph [:label => 'example', :size => '1.5, 2.5']
|
276
|
-
gvr.beta [:shape => :box]
|
277
242
|
gvr.alpha >> gvr.beta
|
278
|
-
|
279
|
-
|
280
|
-
gvr.delta >> gvr[:size]
|
243
|
+
gvr.alpha >> gvr.beta >> gvr.gamma
|
244
|
+
gvr.alpha >> gvr.beta >> gvr.gamma >> gvr.delta
|
281
245
|
|
282
|
-
assert_equal <<-end_of_string, gvr.
|
246
|
+
assert_equal <<-end_of_string, gvr.to_dot
|
283
247
|
digraph sample {
|
284
|
-
graph [label = "example", size = "1.5, 2.5"];
|
285
|
-
beta [shape = box];
|
286
248
|
alpha -> beta;
|
287
|
-
alpha ->
|
288
|
-
beta ->
|
289
|
-
delta -> size;
|
249
|
+
alpha -> beta -> gamma;
|
250
|
+
alpha -> beta -> gamma -> delta;
|
290
251
|
}
|
291
252
|
end_of_string
|
292
253
|
end
|
293
254
|
|
294
|
-
def
|
255
|
+
def test_consective_undirected_edges
|
295
256
|
gvr = GraphvizR.new 'sample'
|
296
|
-
|
257
|
+
gvr.alpha - gvr.beta
|
258
|
+
gvr.alpha - gvr.beta - gvr.gamma
|
259
|
+
gvr.alpha - gvr.beta - gvr.gamma - gvr.delta
|
297
260
|
|
298
|
-
assert_equal <<-end_of_string, gvr.
|
261
|
+
assert_equal <<-end_of_string, gvr.to_dot
|
262
|
+
graph sample {
|
263
|
+
alpha -- beta;
|
264
|
+
alpha -- beta -- gamma;
|
265
|
+
alpha -- beta -- gamma -- delta;
|
266
|
+
}
|
267
|
+
end_of_string
|
268
|
+
end
|
269
|
+
|
270
|
+
def test_node_grouping
|
271
|
+
gvr = GraphvizR.new 'sample'
|
272
|
+
gvr.alpha >> [gvr.beta, gvr.gamma, gvr.delta]
|
273
|
+
|
274
|
+
assert_equal <<-end_of_string, gvr.to_dot
|
299
275
|
digraph sample {
|
300
|
-
|
276
|
+
alpha -> {beta; gamma; delta;};
|
301
277
|
}
|
302
278
|
end_of_string
|
303
279
|
end
|
304
280
|
|
305
|
-
def
|
281
|
+
def test_node_grouping_reverse
|
306
282
|
gvr = GraphvizR.new 'sample'
|
307
|
-
gvr.
|
308
|
-
gvr.alpha >> gvr.beta >> gvr.gamma
|
309
|
-
gvr.alpha >> gvr.beta >> gvr.gamma >> gvr.delta
|
283
|
+
[gvr.beta, gvr.gamma, gvr.delta] >> gvr.alpha
|
310
284
|
|
311
285
|
assert_equal <<-end_of_string, gvr.to_dot
|
312
286
|
digraph sample {
|
313
|
-
|
314
|
-
alpha -> beta -> gamma;
|
315
|
-
alpha -> beta -> gamma -> delta;
|
287
|
+
{beta; gamma; delta;} -> alpha;
|
316
288
|
}
|
317
289
|
end_of_string
|
318
290
|
end
|
319
291
|
|
320
|
-
def
|
292
|
+
def test_consective_node_grouping
|
321
293
|
gvr = GraphvizR.new 'sample'
|
322
|
-
|
323
|
-
# gvr.aa >> gvr.grouping(gvr.bb, gvr.cc, gvr.dd)
|
324
|
-
# a -> {b c d};
|
325
|
-
# aa -> {bb cc dd};
|
326
|
-
gvr.aaa >> [gvr.bbb, gvr.ccc, gvr.ddd]
|
294
|
+
gvr.alpha >> gvr.beta >> [gvr.gamma, gvr.delta]
|
327
295
|
|
328
296
|
assert_equal <<-end_of_string, gvr.to_dot
|
329
297
|
digraph sample {
|
330
|
-
|
298
|
+
alpha -> beta -> {gamma; delta;};
|
299
|
+
}
|
300
|
+
end_of_string
|
301
|
+
end
|
302
|
+
|
303
|
+
def test_intermediate_defaults
|
304
|
+
gvr = GraphvizR.new 'example'
|
305
|
+
gvr.dummy1 [:label => 'dummy1']
|
306
|
+
gvr.graph [:size => "3, 3"]
|
307
|
+
gvr.dummy2 [:label => 'dummy2']
|
308
|
+
gvr.node [:shape => :box]
|
309
|
+
gvr.dummy3 [:label => 'dummy3']
|
310
|
+
gvr.edge [:fontcolor => :red]
|
311
|
+
gvr.dummy4 [:label => 'dummy4']
|
312
|
+
|
313
|
+
assert_equal <<-end_of_string, gvr.to_dot
|
314
|
+
digraph example {
|
315
|
+
dummy1 [label = "dummy1"];
|
316
|
+
graph [size = "3, 3"];
|
317
|
+
dummy2 [label = "dummy2"];
|
318
|
+
node [shape = box];
|
319
|
+
dummy3 [label = "dummy3"];
|
320
|
+
edge [fontcolor = red];
|
321
|
+
dummy4 [label = "dummy4"];
|
331
322
|
}
|
332
323
|
end_of_string
|
333
324
|
end
|
334
325
|
|
335
326
|
def test_rank
|
336
327
|
gvr = GraphvizR.new 'sample'
|
337
|
-
gvr.graph [:size => "3, 3"]
|
338
|
-
gvr.Level_1 >> gvr.Level_2 >> gvr.Level_3
|
339
|
-
gvr.a >> gvr.b
|
340
|
-
gvr.a >> gvr.c
|
341
|
-
gvr.a >> gvr.d
|
342
|
-
gvr.b >> gvr.c
|
343
|
-
gvr.b >> gvr.e
|
344
|
-
gvr.d >> gvr.e
|
345
|
-
gvr.d >> gvr.f
|
346
|
-
#gvr.grouping(:rank => :same) {gvr.Level_1; gvr.a}
|
347
328
|
gvr.rank :same, [gvr.Level_1, gvr.a]
|
348
|
-
gvr.rank :same, [gvr.Level_2, gvr.c, gvr.b, gvr.d]
|
349
|
-
gvr.rank :same, [gvr.Level_3, gvr.e, gvr.f]
|
350
329
|
|
351
330
|
assert_equal <<-end_of_string, gvr.to_dot
|
352
331
|
digraph sample {
|
353
|
-
graph [size = "3, 3"];
|
354
|
-
Level_1 -> Level_2 -> Level_3;
|
355
|
-
a -> b;
|
356
|
-
a -> c;
|
357
|
-
a -> d;
|
358
|
-
b -> c;
|
359
|
-
b -> e;
|
360
|
-
d -> e;
|
361
|
-
d -> f;
|
362
332
|
{rank = same; Level_1; a;};
|
363
|
-
|
364
|
-
|
333
|
+
}
|
334
|
+
end_of_string
|
335
|
+
end
|
336
|
+
|
337
|
+
=begin
|
338
|
+
def test_rank_new
|
339
|
+
gvr = GraphvizR.new 'sample'
|
340
|
+
gvr.group {|gvr| gvr.rank = :same, gvr.Level_1, gvr.a}
|
341
|
+
|
342
|
+
assert_equal <<-end_of_string, gvr.to_dot
|
343
|
+
digraph sample {
|
344
|
+
{rank = same; Level_1; a;};
|
345
|
+
}
|
346
|
+
end_of_string
|
347
|
+
end
|
348
|
+
=end
|
349
|
+
|
350
|
+
def test_data
|
351
|
+
gvr = GraphvizR.new 'sample'
|
352
|
+
gvr.graph [:label => 'example', :size => '1.5, 2.5']
|
353
|
+
gvr.beta [:shape => :box]
|
354
|
+
gvr.alpha >> gvr.beta
|
355
|
+
(gvr.alpha >> gvr.gamma) [:label => 'label1']
|
356
|
+
(gvr.beta >> gvr.delta) [:label => 'label2']
|
357
|
+
gvr.delta >> gvr[:size]
|
358
|
+
|
359
|
+
assert_equal <<-end_of_string, gvr.data(:dot)
|
360
|
+
digraph sample {
|
361
|
+
graph [label = "example", size = "1.5, 2.5"];
|
362
|
+
beta [shape = box];
|
363
|
+
alpha -> beta;
|
364
|
+
alpha -> gamma [label = "label1"];
|
365
|
+
beta -> delta [label = "label2"];
|
366
|
+
delta -> size;
|
365
367
|
}
|
366
368
|
end_of_string
|
367
369
|
end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
|
|
3
3
|
specification_version: 1
|
4
4
|
name: GraphvizR
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2007-
|
6
|
+
version: 0.5.0
|
7
|
+
date: 2007-03-11 00:00:00 +09:00
|
8
8
|
summary: Graphviz wrapper for Ruby and Rails
|
9
9
|
require_paths:
|
10
10
|
- lib
|