ruby-graphviz 0.9.10 → 0.9.11

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.
Files changed (57) hide show
  1. data/AUTHORS +1 -0
  2. data/README.rdoc +5 -0
  3. data/examples/maketest.bat +6 -0
  4. data/examples/maketest.sh +6 -0
  5. data/examples/sample30.rb.ps +923 -0
  6. data/examples/sample37.rb +87 -0
  7. data/examples/sample37.rb.dot +50 -0
  8. data/examples/sample37.rb.png +0 -0
  9. data/examples/sample38.rb +11 -0
  10. data/lib/graphviz.rb +34 -17
  11. data/lib/graphviz/constants.rb +1 -1
  12. data/lib/graphviz/core_ext.rb +23 -0
  13. data/lib/graphviz/family_tree.rb +23 -4
  14. data/lib/graphviz/family_tree/couple.rb +3 -2
  15. data/lib/graphviz/family_tree/generation.rb +4 -4
  16. data/lib/graphviz/family_tree/person.rb +27 -3
  17. data/test/output/sample01.rb.png +0 -0
  18. data/test/output/sample02.rb.png +0 -0
  19. data/test/output/sample03.rb.png +0 -0
  20. data/test/output/sample04.rb.png +0 -0
  21. data/test/output/sample05.rb.png +0 -0
  22. data/test/output/sample06.rb.png +0 -0
  23. data/test/output/sample07.rb.png +0 -0
  24. data/test/output/sample08.rb.png +0 -0
  25. data/test/output/sample09.rb.png +0 -0
  26. data/test/output/sample10.rb.png +0 -0
  27. data/test/output/sample11.rb.png +0 -0
  28. data/test/output/sample12.rb.png +0 -0
  29. data/test/output/sample13.rb.png +0 -0
  30. data/test/output/sample14.rb.png +0 -0
  31. data/test/output/sample15.rb.png +0 -0
  32. data/test/output/sample16.rb.png +0 -0
  33. data/test/output/sample17.rb.png +0 -0
  34. data/test/output/sample18.rb.png +0 -0
  35. data/test/output/sample19.rb.png +0 -0
  36. data/test/output/sample20.rb.png +0 -0
  37. data/test/output/sample21.rb.html +3 -0
  38. data/test/output/sample21.rb.png +0 -0
  39. data/test/output/sample22.rb.html +5 -0
  40. data/test/output/sample22.rb.png +0 -0
  41. data/test/output/sample23.rb.png +0 -0
  42. data/test/output/sample24.rb.png +0 -0
  43. data/test/output/sample25.rb.png +0 -0
  44. data/test/output/sample26.rb.png +0 -0
  45. data/test/output/sample28.rb.png +0 -0
  46. data/test/output/sample29.rb.svg +21 -0
  47. data/test/output/sample30.rb.ps +268 -0
  48. data/test/output/sample31.rb.png +0 -0
  49. data/test/output/sample32.rb.png +0 -0
  50. data/test/output/sample37.rb.dot +50 -0
  51. data/test/output/sample37.rb.png +0 -0
  52. data/test/output/sample38.rb.png +0 -0
  53. data/test/output/sample40.rb.png +0 -0
  54. data/test/support.rb +100 -0
  55. data/test/test_examples.rb +130 -0
  56. metadata +47 -5
  57. data/examples/sample13b.rb +0 -48
@@ -0,0 +1,87 @@
1
+ $:.unshift( "../lib" )
2
+ require "graphviz"
3
+
4
+ # The goal is to set each planet to its own orbit + set some (earth+moon) to the same orbit
5
+
6
+ g = GraphViz::new( "Solarsys",
7
+ :type => "digraph",
8
+ :use => "twopi"
9
+ )
10
+
11
+ # the star
12
+ sun = g.add_node(
13
+ 'Sun',
14
+ :shape => "circle",
15
+ :penwidth => 2,
16
+ :fontsize => 12,
17
+ :style => :filled,
18
+ :fillcolor => "orange",
19
+ :label => "Sun\n"
20
+ )
21
+
22
+ planets = Hash.new
23
+
24
+ # The Earth and the Moon - in the same subgraph\rank
25
+ g.subgraph { |c|
26
+ c[:rank => 'same']
27
+ planets['Moon'] = c.add_node(
28
+ 'Moon',
29
+ :shape => "circle",
30
+ :penwidth => 2,
31
+ :fontsize => 12,
32
+ :style => :filled,
33
+ :fillcolor => "red",
34
+ :label => "Moon\n"
35
+ )
36
+ planets['Earth'] = c.add_node(
37
+ 'Earth',
38
+ :shape => "circle",
39
+ :penwidth => 2,
40
+ :fontsize => 12,
41
+ :style => :filled,
42
+ :fillcolor => "blue",
43
+ :label => "Earth\n"
44
+ )
45
+ c.add_edge( planets['Moon'], planets['Earth'],
46
+ :penwidth => 2,
47
+ :labeltooltip => "distance",
48
+ :color => "black"
49
+ )
50
+
51
+
52
+ }
53
+
54
+ g.add_edge( sun, planets['Earth'],
55
+ :penwidth => 2,
56
+ :labeltooltip => "distance",
57
+ :color => "black"
58
+ )
59
+
60
+ i = 0
61
+ # some more planets - each supposed having its own orbit - im trying to do it with rank
62
+ ['Mercury','Venus','Mars','Jupiter','Saturn','Uranus','Neptune','Pluto'].each { |p|
63
+ i = i + 1
64
+ # set each to its own orbit
65
+ # that doesnt seem to work ...
66
+ g.subgraph { |c|
67
+ c[:rank => "same"]
68
+ planets[p] = c.add_node(
69
+ p,
70
+ :shape => "circle",
71
+ :penwidth => 2,
72
+ :fontsize => 12,
73
+ :fillcolor => "green",
74
+ :style => :filled,
75
+ :label => "#{p}\n"
76
+ )
77
+ c.add_edge( sun, planets[p],
78
+ :penwidth => 2,
79
+ :label => "distance",
80
+ :color => "black"
81
+ )
82
+ }
83
+
84
+ }
85
+
86
+ g.output( :png => "#{$0}.png" )
87
+ g.output( :none => "#{$0}.dot" )
@@ -0,0 +1,50 @@
1
+ digraph Solarsys {
2
+ Sun [label = "Sun\n", penwidth = "2", fillcolor = "orange", shape = "circle", fontsize = "12", style = "filled"];
3
+ subgraph {
4
+ rank = "same";
5
+ Moon [label = "Moon\n", penwidth = "2", fillcolor = "red", shape = "circle", fontsize = "12", style = "filled"];
6
+ Earth [label = "Earth\n", penwidth = "2", fillcolor = "blue", shape = "circle", fontsize = "12", style = "filled"];
7
+ Moon -> Earth [penwidth = "2", color = "black", labeltooltip = "distance"]
8
+ }
9
+ Sun -> Earth [penwidth = "2", color = "black", labeltooltip = "distance"]
10
+ subgraph {
11
+ rank = "same";
12
+ Mercury [label = "Mercury\n", penwidth = "2", fillcolor = "green", shape = "circle", fontsize = "12", style = "filled"];
13
+ Sun -> Mercury [label = "distance", penwidth = "2", color = "black"]
14
+ }
15
+ subgraph {
16
+ rank = "same";
17
+ Venus [label = "Venus\n", penwidth = "2", fillcolor = "green", shape = "circle", fontsize = "12", style = "filled"];
18
+ Sun -> Venus [label = "distance", penwidth = "2", color = "black"]
19
+ }
20
+ subgraph {
21
+ rank = "same";
22
+ Mars [label = "Mars\n", penwidth = "2", fillcolor = "green", shape = "circle", fontsize = "12", style = "filled"];
23
+ Sun -> Mars [label = "distance", penwidth = "2", color = "black"]
24
+ }
25
+ subgraph {
26
+ rank = "same";
27
+ Jupiter [label = "Jupiter\n", penwidth = "2", fillcolor = "green", shape = "circle", fontsize = "12", style = "filled"];
28
+ Sun -> Jupiter [label = "distance", penwidth = "2", color = "black"]
29
+ }
30
+ subgraph {
31
+ rank = "same";
32
+ Saturn [label = "Saturn\n", penwidth = "2", fillcolor = "green", shape = "circle", fontsize = "12", style = "filled"];
33
+ Sun -> Saturn [label = "distance", penwidth = "2", color = "black"]
34
+ }
35
+ subgraph {
36
+ rank = "same";
37
+ Uranus [label = "Uranus\n", penwidth = "2", fillcolor = "green", shape = "circle", fontsize = "12", style = "filled"];
38
+ Sun -> Uranus [label = "distance", penwidth = "2", color = "black"]
39
+ }
40
+ subgraph {
41
+ rank = "same";
42
+ Neptune [label = "Neptune\n", penwidth = "2", fillcolor = "green", shape = "circle", fontsize = "12", style = "filled"];
43
+ Sun -> Neptune [label = "distance", penwidth = "2", color = "black"]
44
+ }
45
+ subgraph {
46
+ rank = "same";
47
+ Pluto [label = "Pluto\n", penwidth = "2", fillcolor = "green", shape = "circle", fontsize = "12", style = "filled"];
48
+ Sun -> Pluto [label = "distance", penwidth = "2", color = "black"]
49
+ }
50
+ }
Binary file
@@ -0,0 +1,11 @@
1
+ $:.unshift( "../lib" )
2
+ require "graphviz"
3
+
4
+ g = GraphViz::new( :G ) { |g|
5
+ g.a[:label => "ε"]
6
+ g.add_node( "b", :label => "ε" )
7
+ g.c[:label => 'ε']
8
+ g.add_node( "d", :label => 'ε' )
9
+ }
10
+
11
+ puts g.output( :none => String, :png => "#{$0}.png", :path => "/usr/local/bin" )
data/lib/graphviz.rb CHANGED
@@ -15,12 +15,8 @@
15
15
  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
16
 
17
17
 
18
- begin
19
- include Java
20
- IS_JRUBY = true
21
- rescue
22
- IS_JRUBY= false
23
- end
18
+ IS_JRUBY = (defined?( JRUBY_VERSION ) != nil)
19
+ IS_CYGWIN = ((RUBY_PLATFORM =~ /cygwin/) != nil)
24
20
 
25
21
  require 'tempfile'
26
22
 
@@ -393,6 +389,8 @@ class GraphViz
393
389
 
394
390
  return( xDOTScript )
395
391
  else
392
+ hOutput = {}
393
+
396
394
  hOpts.each do |xKey, xValue|
397
395
  xValue = xValue.to_s unless xValue.nil? or [Class, TrueClass, FalseClass].include?(xValue.class)
398
396
  case xKey.to_s
@@ -420,19 +418,30 @@ class GraphViz
420
418
  if FORMATS.index( xKey.to_s ).nil? == true
421
419
  raise ArgumentError, "output format '#{xValue}' invalid"
422
420
  end
423
- @output[xKey.to_s] = xValue
421
+ hOutput[xKey.to_s] = xValue
424
422
  end
425
423
  end
424
+
425
+ @output = hOutput if hOutput.size > 0
426
426
 
427
427
  xDOTScript = "#{@oGraphType} #{@name} {\n" << xDOTScript
428
428
 
429
429
  xOutputString = (@filename == String ||
430
430
  @output.any? {|format, file| file == String })
431
431
 
432
- xOutput =
433
- if @format.to_s == "none" || @output.any? {|fmt, fn| fmt.to_s == "none" }
434
- xDOTScript
435
- else
432
+ xOutput = ""
433
+ if @format.to_s == "none" or @output.any? {|fmt, fn| fmt.to_s == "none"}
434
+ if xOutputString
435
+ xOutput << xDOTScript
436
+ else
437
+ xFileName = @output["none"] || @filename
438
+ open( xFileName, "w" ) do |h|
439
+ h.puts xDOTScript
440
+ end
441
+ end
442
+ end
443
+
444
+ if (@format.to_s != "none" and not @format.nil?) or (@output.any? {|format, file| format != "none" } and @output.size > 0)
436
445
  ## Act: Save script and send it to dot
437
446
  t = Tempfile::open( File.basename($0) )
438
447
  t.print( xDOTScript )
@@ -447,15 +456,15 @@ class GraphViz
447
456
 
448
457
  xOutputWithFile = ""
449
458
  xOutputWithoutFile = ""
450
- unless @format.nil?
451
- if @filename.nil? || @filename == String
459
+ unless @format.nil? or @format == "none"
460
+ if @filename.nil? or @filename == String
452
461
  xOutputWithoutFile = "-T#{@format} "
453
462
  else
454
463
  xOutputWithFile = "-T#{@format} -o#{@filename} "
455
464
  end
456
465
  end
457
- @output.each do |format, file|
458
- if file.nil? || file == String
466
+ @output.each_except( :key => ["none"] ) do |format, file|
467
+ if file.nil? or file == String
459
468
  xOutputWithoutFile << "-T#{format} "
460
469
  else
461
470
  xOutputWithFile << "-T#{format} -o#{file} "
@@ -469,11 +478,19 @@ class GraphViz
469
478
 
470
479
  if IS_JRUBY
471
480
  xCmd = "#{cmd} -q#{@errors} #{xExternalLibraries} #{xOutputWithFile} #{xOutputWithoutFile} #{t.path}"
481
+ elsif IS_CYGWIN
482
+ tmpPath = t.path
483
+ begin
484
+ tmpPath = "'" + `cygpath -w #{t.path}`.chomp + "'"
485
+ rescue
486
+ warn "cygpath is not installed!"
487
+ end
488
+ xCmd = "\"#{cmd}\" -q#{@errors} #{xExternalLibraries} #{xOutputWithFile} #{xOutputWithoutFile} #{tmpPath}"
472
489
  else
473
490
  xCmd = "\"#{cmd}\" -q#{@errors} #{xExternalLibraries} #{xOutputWithFile} #{xOutputWithoutFile} #{t.path}"
474
491
  end
475
492
 
476
- output_from_command( xCmd )
493
+ xOutput << output_from_command( xCmd )
477
494
  end
478
495
 
479
496
  if xOutputString
@@ -743,7 +760,7 @@ class GraphViz
743
760
 
744
761
  paths.each do |path|
745
762
  file = (path.nil?)?bin:File.join(path,bin)
746
- if File.executable?(file) then
763
+ if File.executable?(file) and not File.directory?(file) then
747
764
  return file
748
765
  elsif RUBY_PLATFORM =~ /mswin|mingw/
749
766
  found_ext = (ENV['PATHEXT'] || '.exe;.bat;.com').split(";").find {|ext| File.executable?(file + ext) }
@@ -40,7 +40,7 @@
40
40
  # C => cluster
41
41
  #
42
42
  module Constants
43
- RGV_VERSION = "0.9.10"
43
+ RGV_VERSION = "0.9.11"
44
44
 
45
45
  ## Const: Output formats
46
46
  FORMATS = [
@@ -17,4 +17,27 @@ class Hash
17
17
  options
18
18
  end
19
19
  end
20
+
21
+ # x = {
22
+ # :none => String,
23
+ # :png => "file.png",
24
+ # :svg => "file.svg"
25
+ # }
26
+ #
27
+ # x.each_except( :key => [:none], :value => [/\.png$/] ) do |k, v|
28
+ # puts "#{k} -> #{v}"
29
+ # end
30
+ #
31
+ # => svg -> file.svg
32
+ def each_except( e, &b )
33
+ key_table = (e[:key]||[]).clone.delete_if {|i| i.kind_of? Regexp }
34
+ key_regexp = (e[:key]||[]).clone.delete_if {|i| key_table.include? i }.map {|i| i.to_s }.join("|")
35
+
36
+ value_table = (e[:value]||[]).clone.delete_if {|i| i.kind_of? Regexp }
37
+ value_regexp = (e[:value]||[]).clone.delete_if {|i| value_table.include? i }.map {|i| i.to_s }.join("|")
38
+
39
+ self.each do |k, v|
40
+ yield( k, v ) unless (key_table.size > 0 and key_table.include?(k)) or (key_regexp.size > 0 and k.to_s.match(key_regexp)) or (value_table.size > 0 and value_table.include?(v)) or (value_regexp.size > 0 and v.to_s.match(value_regexp))
41
+ end
42
+ end
20
43
  end
@@ -6,6 +6,12 @@ require 'graphviz/family_tree/couple'
6
6
 
7
7
  class GraphViz
8
8
  class FamilyTree
9
+ # Create a new family tree
10
+ #
11
+ # require 'graphviz/family_tree'
12
+ # t = GraphViz::FamilyTree.new do
13
+ # ...
14
+ # end
9
15
  def initialize( &block )
10
16
  @persons = {}
11
17
  @graph = GraphViz.new( "FamilyTree" )
@@ -15,30 +21,43 @@ class GraphViz
15
21
  instance_eval(&block) if block
16
22
  end
17
23
 
24
+ # Add a new generation in the tree
25
+ #
26
+ # require 'graphviz/family_tree'
27
+ # t = GraphViz::FamilyTree.new do
28
+ # generation do
29
+ # ...
30
+ # end
31
+ # generation do
32
+ # ...
33
+ # end
34
+ # end
18
35
  def generation( &b )
19
36
  GraphViz::FamilyTree::Generation.new( @graph, @persons, self, @generation ).make( &b )
20
37
  @generation += 1
21
38
  end
22
39
 
23
- def persons
40
+ def persons #:nodoc:
24
41
  @persons ||= {}
25
42
  end
26
43
 
27
- def add_couple( x, y, node )
44
+ def add_couple( x, y, node ) #:nodoc:
28
45
  @couples[x] = {} if @couples[x].nil?
29
46
  @couples[x][y] = GraphViz::FamilyTree::Couple.new( @graph, node )
30
47
  @couples[y] = {} if @couples[y].nil?
31
48
  @couples[y][x] = @couples[x][y]
32
49
  end
33
50
 
34
- def couple( x, y )
51
+ # Get a couple (GraphViz::FamilyTree::Couple)
52
+ def couple( x, y )
35
53
  @couples[x][y]
36
54
  end
37
55
 
38
- def method_missing(sym, *args, &block)
56
+ def method_missing(sym, *args, &block) #:nodoc:
39
57
  persons[sym.to_s]
40
58
  end
41
59
 
60
+ # Get the graph
42
61
  def graph
43
62
  @graph
44
63
  end
@@ -1,15 +1,16 @@
1
1
  class GraphViz
2
2
  class FamilyTree
3
3
  class Couple
4
- def initialize( g, n )
4
+ def initialize( g, n ) #:nodoc:
5
5
  @graph = g
6
6
  @node = n
7
7
  end
8
8
 
9
- def node
9
+ def node #:nodoc:
10
10
  @node
11
11
  end
12
12
 
13
+ # Add kids to a couple
13
14
  def kids( *z )
14
15
  if z.size == 1
15
16
  @graph.add_edge( @node, z[0].node, "dir" => "none" )
@@ -1,7 +1,7 @@
1
1
  class GraphViz
2
2
  class FamilyTree
3
3
  class Generation
4
- def initialize( graph, persons, tree, gen_number )
4
+ def initialize( graph, persons, tree, gen_number ) #:nodoc:
5
5
  @graph = graph
6
6
  @persons = persons
7
7
  @cluster = @graph.add_graph( "Generation#{gen_number}" )
@@ -9,15 +9,15 @@ class GraphViz
9
9
  @tree = tree
10
10
  end
11
11
 
12
- def persons
12
+ def persons #:nodoc:
13
13
  @persons
14
14
  end
15
15
 
16
- def make( &block )
16
+ def make( &block ) #:nodoc:
17
17
  instance_eval(&block) if block
18
18
  end
19
19
 
20
- def method_missing(sym, *args, &block)
20
+ def method_missing(sym, *args, &block) #:nodoc:
21
21
  persons[sym.to_s] ||= GraphViz::FamilyTree::Person.new( @graph, @cluster, @tree, sym.to_s )
22
22
  end
23
23
  end
@@ -4,7 +4,7 @@ require 'graphviz'
4
4
  class GraphViz
5
5
  class FamilyTree
6
6
  class Person
7
- def initialize( graph, cluster, tree, name )
7
+ def initialize( graph, cluster, tree, name ) #:nodoc:
8
8
  @graph = graph
9
9
  @cluster = cluster
10
10
  @node = @cluster.add_node( name )
@@ -12,30 +12,45 @@ class GraphViz
12
12
  @tree = tree
13
13
  end
14
14
 
15
- def couples
15
+ def couples #:nodoc:
16
16
  @couples
17
17
  end
18
18
 
19
- def node
19
+ def node #:nodoc:
20
20
  @node
21
21
  end
22
22
 
23
+ # Define the current person as a man
24
+ #
25
+ # greg.is_a_man( "Greg" )
23
26
  def is_a_man( name )
24
27
  @node["label"] = name
25
28
  @node["color"] = "blue"
26
29
  end
30
+ # Define the current person as a boy
31
+ #
32
+ # greg.is_a_boy( "Greg" )
27
33
  def is_a_boy( name )
28
34
  is_a_man( name )
29
35
  end
30
36
 
37
+ # Define the current perdon as a woman
38
+ #
39
+ # mu.is_a_woman( "Muriel" )
31
40
  def is_a_woman( name )
32
41
  @node["label"] = name
33
42
  @node["color"] = "pink"
34
43
  end
44
+ # Define the current perdon as a girl
45
+ #
46
+ # maia.is_a_girl( "Maia" )
35
47
  def is_a_girl( name )
36
48
  is_a_woman( name )
37
49
  end
38
50
 
51
+ # Define that's two persons are maried
52
+ #
53
+ # mu.is_maried_with greg
39
54
  def is_maried_with( x )
40
55
  node = @cluster.add_node( "#{@node.name}And#{x.node.name}" )
41
56
  node["shape"] = "point"
@@ -44,6 +59,9 @@ class GraphViz
44
59
  @tree.add_couple( self, x, node )
45
60
  end
46
61
 
62
+ # Define that's two persons are divorced
63
+ #
64
+ # sophie.is_divorced_with john
47
65
  def is_divorced_with( x )
48
66
  node = @cluster.add_node( "#{@node.name}And#{x.node.name}" )
49
67
  node["shape"] = "point"
@@ -53,6 +71,9 @@ class GraphViz
53
71
  @tree.add_couple( self, x, node )
54
72
  end
55
73
 
74
+ # Define that's a person is widower of another
75
+ #
76
+ # simon.is_widower_of elisa
56
77
  def is_widower_of( x ) #veuf
57
78
  node = @cluster.add_node( "#{@node.name}And#{x.node.name}" )
58
79
  node["shape"] = "point"
@@ -62,6 +83,9 @@ class GraphViz
62
83
  @tree.add_couple( self, x, node )
63
84
  end
64
85
 
86
+ # Define the kids of a single person
87
+ #
88
+ # alice.kids( john, jack, julie )
65
89
  def kids( *z )
66
90
  GraphViz::FamilyTree::Couple.new( @graph, @node ).kids( *z )
67
91
  end