ruby-graphviz 1.0.1 → 1.0.2
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/.travis.yml +4 -0
- data/AUTHORS +1 -0
- data/README.rdoc +6 -0
- data/Rakefile +7 -1
- data/examples/sample62.rb +1 -1
- data/examples/theory/tests.rb +13 -7
- data/lib/graphviz.rb +34 -11
- data/lib/graphviz/attrs.rb +37 -42
- data/lib/graphviz/constants.rb +3 -3
- data/lib/graphviz/core_ext.rb +7 -0
- data/lib/graphviz/dsl.rb +19 -11
- data/lib/graphviz/edge.rb +164 -184
- data/lib/graphviz/graphml.rb +1 -3
- data/lib/graphviz/node.rb +128 -142
- data/lib/graphviz/theory.rb +283 -249
- data/lib/graphviz/utils/colors.rb +7 -8
- data/lib/graphviz/xml.rb +35 -35
- data/test/test_graph.rb +65 -3
- data/test/test_theory.rb +102 -0
- data/test/test_utils_colors.rb +42 -45
- metadata +7 -4
data/.travis.yml
ADDED
data/AUTHORS
CHANGED
data/README.rdoc
CHANGED
@@ -16,6 +16,12 @@ Interface to the GraphViz graphing tool
|
|
16
16
|
|
17
17
|
== CHANGELOG
|
18
18
|
|
19
|
+
=== 1.0.2 :
|
20
|
+
* Add PageRank algorithm
|
21
|
+
* Major bug corrections
|
22
|
+
* Fix utils/colors.rb's case syntax
|
23
|
+
* Modify deprecated method: Hash#index to Hash#key
|
24
|
+
|
19
25
|
=== 1.0.1 :
|
20
26
|
* Add GraphViz::DSL
|
21
27
|
* Change project to use Bundler gem tools
|
data/Rakefile
CHANGED
@@ -42,7 +42,13 @@ RDoc::Task.new do |rdoc|
|
|
42
42
|
end
|
43
43
|
|
44
44
|
Rake::TestTask.new(:test) do |t|
|
45
|
-
|
45
|
+
require 'graphviz/utils'
|
46
|
+
include GVUtils
|
47
|
+
if find_executable("dot", nil).nil?
|
48
|
+
t.test_files = FileList['test/test_*.rb'].exclude("test/test_examples.rb")
|
49
|
+
else
|
50
|
+
t.test_files = FileList['test/test_*.rb']
|
51
|
+
end
|
46
52
|
end
|
47
53
|
|
48
54
|
Bundler::GemHelper.install_tasks
|
data/examples/sample62.rb
CHANGED
data/examples/theory/tests.rb
CHANGED
@@ -39,15 +39,17 @@ puts "Symmetric ? #{t.symmetric?}"
|
|
39
39
|
|
40
40
|
puts "Incidence matrix :"
|
41
41
|
puts t.incidence_matrix
|
42
|
-
# => [ 1 1 1
|
43
|
-
# [
|
44
|
-
# [ 0 0 0
|
45
|
-
# [ 0
|
46
|
-
# [ 0 0 0 0 0
|
47
|
-
# [ 0 0
|
42
|
+
# => [ 1 1 1 0 0 0 0 0 0]
|
43
|
+
# [ -1 0 0 1 1 1 0 0 0]
|
44
|
+
# [ 0 0 0 -1 0 0 1 1 0]
|
45
|
+
# [ 0 -1 0 0 -1 0 -1 0 1]
|
46
|
+
# [ 0 0 0 0 0 -1 0 0 -1]
|
47
|
+
# [ 0 0 -1 0 0 0 0 -1 0]
|
48
48
|
|
49
49
|
g.each_node do |name, node|
|
50
50
|
puts "Degree of node `#{name}' = #{t.degree(node)}"
|
51
|
+
print "neighbors : "; p t.neighbors(name).map{ |e| e.id } # = node.neighbors.map { |e| e.id }
|
52
|
+
print "incidents : "; p t.incidents(name).map{ |e| e.id } # = node.incidents.map { |e| e.id }
|
51
53
|
end
|
52
54
|
|
53
55
|
puts "Laplacian matrix :"
|
@@ -78,4 +80,8 @@ puts "Your graph contains circuits" if rr.include?(nil)
|
|
78
80
|
puts "Critical path : "
|
79
81
|
rrr = t.critical_path
|
80
82
|
print "\tPath "; p rrr[:path]
|
81
|
-
puts "\tDistance : #{rrr[:distance]}"
|
83
|
+
puts "\tDistance : #{rrr[:distance]}"
|
84
|
+
|
85
|
+
t.pagerank.each { |node, rank|
|
86
|
+
puts "Pagerank for node #{node.id} = #{rank}"
|
87
|
+
}
|
data/lib/graphviz.rb
CHANGED
@@ -93,31 +93,33 @@ class GraphViz
|
|
93
93
|
# Return the GraphViz::Node object created
|
94
94
|
#
|
95
95
|
def add_node( xNodeName, hOpts = {} )
|
96
|
-
|
96
|
+
node = @hoNodes[xNodeName]
|
97
|
+
|
98
|
+
if node.nil?
|
97
99
|
@hoNodes[xNodeName] = GraphViz::Node::new( xNodeName, self )
|
98
100
|
@hoNodes[xNodeName].index = @elements_order.size_of( "node" )
|
99
101
|
|
100
102
|
unless hOpts.keys.include?(:label) or hOpts.keys.include?("label")
|
101
103
|
hOpts[:label] = xNodeName
|
102
104
|
end
|
103
|
-
|
104
|
-
hOpts.each do |xKey, xValue|
|
105
|
-
@hoNodes[xNodeName][xKey.to_s] = xValue
|
106
|
-
end
|
107
105
|
|
108
106
|
@elements_order.push( {
|
109
107
|
"type" => "node",
|
110
108
|
"name" => xNodeName,
|
111
109
|
"value" => @hoNodes[xNodeName]
|
112
110
|
} )
|
113
|
-
|
114
|
-
|
115
|
-
|
111
|
+
|
112
|
+
node = @hoNodes[xNodeName]
|
113
|
+
end
|
114
|
+
|
115
|
+
hOpts.each do |xKey, xValue|
|
116
|
+
@hoNodes[xNodeName][xKey.to_s] = xValue
|
117
|
+
end
|
118
|
+
|
119
|
+
return node
|
116
120
|
end
|
117
121
|
|
118
|
-
#
|
119
|
-
# Return the node object for the given name (or nil)
|
120
|
-
#
|
122
|
+
# Return the node object for the given name (or nil) in the current graph
|
121
123
|
def get_node( xNodeName, &block )
|
122
124
|
node = @hoNodes[xNodeName] || nil
|
123
125
|
|
@@ -125,6 +127,23 @@ class GraphViz
|
|
125
127
|
|
126
128
|
return node
|
127
129
|
end
|
130
|
+
|
131
|
+
# Returns the first node found in the entire graph, starting from the root graph
|
132
|
+
def find_node(name)
|
133
|
+
root = root_graph
|
134
|
+
return root.search_node(name)
|
135
|
+
end
|
136
|
+
|
137
|
+
# Return the first node found in the current graph, and it subgraphs
|
138
|
+
def search_node(name)
|
139
|
+
n = get_node(name)
|
140
|
+
return n unless n.nil?
|
141
|
+
each_graph { |_, g|
|
142
|
+
n = g.search_node(name)
|
143
|
+
return n unless n.nil?
|
144
|
+
}
|
145
|
+
return nil
|
146
|
+
end
|
128
147
|
|
129
148
|
#
|
130
149
|
# Return the node object for the given index
|
@@ -764,6 +783,10 @@ class GraphViz
|
|
764
783
|
complete
|
765
784
|
end
|
766
785
|
|
786
|
+
# Return true if the graph is directed.
|
787
|
+
def directed?
|
788
|
+
not (/digraph/ =~ "bla digraph bla").nil?
|
789
|
+
end
|
767
790
|
## ----------------------------------------------------------------------------
|
768
791
|
|
769
792
|
private
|
data/lib/graphviz/attrs.rb
CHANGED
@@ -15,54 +15,49 @@
|
|
15
15
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
16
16
|
|
17
17
|
class GraphViz
|
18
|
-
|
19
|
-
|
20
|
-
@name
|
21
|
-
@attributs
|
22
|
-
@graphviz
|
23
|
-
|
24
|
-
attr_accessor :data
|
18
|
+
class Attrs
|
19
|
+
attr_accessor :data
|
25
20
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
21
|
+
def initialize( gviz, name, attributs )
|
22
|
+
@name = name
|
23
|
+
@attributs = attributs
|
24
|
+
@data = Hash::new( )
|
25
|
+
@graphviz = gviz
|
26
|
+
end
|
32
27
|
|
33
|
-
|
34
|
-
|
35
|
-
|
28
|
+
def each
|
29
|
+
@data.each do |k, v|
|
30
|
+
yield(k, v)
|
31
|
+
end
|
36
32
|
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def to_h
|
40
|
-
@data.clone
|
41
|
-
end
|
42
33
|
|
43
|
-
|
44
|
-
|
45
|
-
xKey.each do |k, v|
|
46
|
-
self[k] = v
|
47
|
-
end
|
48
|
-
else
|
49
|
-
if @data.key?( xKey.to_s ) == false
|
50
|
-
nil
|
51
|
-
end
|
52
|
-
@data[xKey.to_s]
|
34
|
+
def to_h
|
35
|
+
@data.clone
|
53
36
|
end
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
37
|
+
|
38
|
+
def []( key )
|
39
|
+
if key.class == Hash
|
40
|
+
key.each do |k, v|
|
41
|
+
self[k] = v
|
42
|
+
end
|
43
|
+
else
|
44
|
+
if @data.key?( key.to_s ) == false
|
45
|
+
nil
|
46
|
+
end
|
47
|
+
@data[key.to_s]
|
48
|
+
end
|
59
49
|
end
|
60
|
-
|
61
|
-
@data[xKey.to_s] = GraphViz::Types.const_get(@attributs[xKey.to_s]).new( xValue )
|
62
50
|
|
63
|
-
|
64
|
-
|
51
|
+
def []=( key, value )
|
52
|
+
unless @attributs.keys.include?( key.to_s )
|
53
|
+
raise ArgumentError, "#{@name} attribut '#{key.to_s}' invalid"
|
54
|
+
end
|
55
|
+
|
56
|
+
@data[key.to_s] = GraphViz::Types.const_get(@attributs[key.to_s]).new( value )
|
57
|
+
|
58
|
+
if @graphviz.nil? == false
|
59
|
+
@graphviz.set_position( @name, key.to_s, @data[key.to_s] )
|
60
|
+
end
|
65
61
|
end
|
66
|
-
|
67
|
-
end
|
62
|
+
end
|
68
63
|
end
|
data/lib/graphviz/constants.rb
CHANGED
@@ -40,7 +40,7 @@
|
|
40
40
|
# C => cluster
|
41
41
|
#
|
42
42
|
module Constants
|
43
|
-
RGV_VERSION = "1.0.
|
43
|
+
RGV_VERSION = "1.0.2"
|
44
44
|
|
45
45
|
## Const: Output formats
|
46
46
|
FORMATS = [
|
@@ -103,8 +103,8 @@ module Constants
|
|
103
103
|
## Const: graphs type
|
104
104
|
GRAPHTYPE = [
|
105
105
|
"digraph",
|
106
|
-
|
107
|
-
|
106
|
+
"graph",
|
107
|
+
"strict digraph"
|
108
108
|
]
|
109
109
|
|
110
110
|
def self.getAttrsFor( x )
|
data/lib/graphviz/core_ext.rb
CHANGED
@@ -63,4 +63,11 @@ class Hash
|
|
63
63
|
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))
|
64
64
|
end
|
65
65
|
end
|
66
|
+
|
67
|
+
unless self.method_defined? :key
|
68
|
+
# Add Hash#key to Ruby < 1.9
|
69
|
+
def key(v)
|
70
|
+
index(v)
|
71
|
+
end
|
72
|
+
end
|
66
73
|
end
|
data/lib/graphviz/dsl.rb
CHANGED
@@ -3,12 +3,13 @@ require 'graphviz'
|
|
3
3
|
class GraphViz::DSL
|
4
4
|
attr_accessor :graph
|
5
5
|
|
6
|
-
|
7
|
-
|
6
|
+
# Create a new graph
|
7
|
+
def initialize(name, options = {}, &block)
|
8
|
+
@graph = GraphViz.new(name, options)
|
8
9
|
instance_eval(&block) if block
|
9
10
|
end
|
10
11
|
|
11
|
-
def method_missing(sym, *args, &block)
|
12
|
+
def method_missing(sym, *args, &block) #:nodoc:
|
12
13
|
return @graph.get_graph(sym.to_s) unless @graph.get_graph(sym.to_s).nil?
|
13
14
|
return @graph.get_node(sym.to_s) unless @graph.get_node(sym.to_s).nil?
|
14
15
|
if(@graph.respond_to?(sym, true))
|
@@ -20,11 +21,13 @@ class GraphViz::DSL
|
|
20
21
|
end
|
21
22
|
end
|
22
23
|
|
24
|
+
# Add a new node
|
23
25
|
def n(name)
|
24
26
|
return @graph.get_node(name) unless @graph.get_node(name.to_s).nil?
|
25
27
|
@graph.add_node(name)
|
26
28
|
end
|
27
29
|
|
30
|
+
# Create edges
|
28
31
|
def e(*args)
|
29
32
|
e = nil
|
30
33
|
last = args.shift
|
@@ -35,25 +38,30 @@ class GraphViz::DSL
|
|
35
38
|
return e
|
36
39
|
end
|
37
40
|
|
41
|
+
# Add a subgraph
|
38
42
|
def subgraph(name, &block)
|
39
43
|
@graph.add_graph(GraphViz::DSL.new(name, { :parent => @graph, :type => @graph.type }, &block).graph)
|
40
44
|
end
|
41
45
|
alias :cluster :subgraph
|
42
46
|
|
43
|
-
|
44
|
-
|
47
|
+
# Generate output
|
48
|
+
def output(options = {})
|
49
|
+
@graph.output(options)
|
45
50
|
end
|
46
51
|
end
|
47
52
|
|
48
|
-
|
49
|
-
|
53
|
+
# Create a new undirected graph
|
54
|
+
def graph(name, options = {}, &block)
|
55
|
+
GraphViz::DSL.new(name, options.merge( { :type => "graph" } ), &block).graph
|
50
56
|
end
|
51
57
|
|
52
|
-
|
53
|
-
|
58
|
+
# Create a new directed graph
|
59
|
+
def digraph(name, options = {}, &block)
|
60
|
+
GraphViz::DSL.new(name, options.merge( { :type => "digraph" } ), &block).graph
|
54
61
|
end
|
55
62
|
|
56
|
-
|
57
|
-
|
63
|
+
# Create a new strict directed graph
|
64
|
+
def strict(name, options = {}, &block)
|
65
|
+
GraphViz::DSL.new(name, options.merge( { :type => "strict digraph" } ), &block).graph
|
58
66
|
end
|
59
67
|
|
data/lib/graphviz/edge.rb
CHANGED
@@ -18,196 +18,176 @@ require 'graphviz/attrs'
|
|
18
18
|
require 'graphviz/constants'
|
19
19
|
|
20
20
|
class GraphViz
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
21
|
+
class Edge
|
22
|
+
include Constants
|
23
|
+
|
24
|
+
# Create a new edge
|
25
|
+
#
|
26
|
+
# In:
|
27
|
+
# * vNodeOne : First node (can be a GraphViz::Node or a node ID)
|
28
|
+
# * vNodeTwo : Second node (can be a GraphViz::Node or a node ID)
|
29
|
+
# * parent_graph : Graph
|
30
|
+
def initialize( vNodeOne, vNodeTwo, parent_graph )
|
31
|
+
@node_one_id, @node_one_port = getNodeNameAndPort( vNodeOne )
|
32
|
+
@node_two_id, @node_two_port = getNodeNameAndPort( vNodeTwo )
|
33
|
+
|
34
|
+
@parent_graph = parent_graph
|
35
|
+
@edge_attributs = GraphViz::Attrs::new( nil, "edge", EDGESATTRS )
|
36
|
+
@index = nil
|
37
|
+
|
38
|
+
unless @parent_graph.directed?
|
39
|
+
(@parent_graph.find_node(@node_one_id) || @parent_graph.add_node(@node_one_id)).incidents << (@parent_graph.find_node(@node_two_id) || @parent_graph.add_node(@node_two_id))
|
40
|
+
(@parent_graph.find_node(@node_two_id) || @parent_graph.add_node(@node_two_id)).neighbors << (@parent_graph.find_node(@node_one_id) || @parent_graph.add_node(@node_one_id))
|
41
|
+
end
|
42
|
+
(@parent_graph.find_node(@node_one_id) || @parent_graph.add_node(@node_one_id)).neighbors << (@parent_graph.find_node(@node_two_id) || @parent_graph.add_node(@node_two_id))
|
43
|
+
(@parent_graph.find_node(@node_two_id) || @parent_graph.add_node(@node_two_id)).incidents << (@parent_graph.find_node(@node_one_id) || @parent_graph.add_node(@node_one_id))
|
44
|
+
end
|
45
|
+
|
46
|
+
# Return the node one as string (so with port if any)
|
47
|
+
def node_one( with_port = true )
|
48
|
+
if @node_one_port.nil? or with_port == false
|
49
|
+
GraphViz.escape(@node_one_id)
|
50
|
+
else
|
51
|
+
GraphViz.escape(@node_one_id, :force => true) + ":#{@node_one_port}"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
alias :tail_node :node_one
|
55
|
+
|
56
|
+
# Return the node two as string (so with port if any)
|
57
|
+
def node_two( with_port = true )
|
58
|
+
if @node_two_port.nil? or with_port == false
|
59
|
+
GraphViz.escape(@node_two_id)
|
60
|
+
else
|
61
|
+
GraphViz.escape(@node_two_id, :force => true) + ":#{@node_two_port}"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
alias :head_node :node_two
|
65
|
+
|
66
|
+
# Return the index of the edge
|
67
|
+
def index
|
68
|
+
@index
|
69
|
+
end
|
70
|
+
def index=(i) #:nodoc:
|
71
|
+
@index = i if @index == nil
|
72
|
+
end
|
73
|
+
|
74
|
+
# Set value +attribut_value+ to the edge attribut +attribut_name+
|
75
|
+
def []=( attribut_name, attribut_value )
|
76
|
+
attribut_value = attribut_value.to_s if attribut_value.class == Symbol
|
77
|
+
@edge_attributs[attribut_name.to_s] = attribut_value
|
78
|
+
end
|
79
|
+
|
80
|
+
# Set values for edge attributs or
|
81
|
+
# get the value of the given edge attribut +attribut_name+
|
82
|
+
def []( attribut_name )
|
83
|
+
# Modification by axgle (http://github.com/axgle)
|
84
|
+
if Hash === attribut_name
|
85
|
+
attribut_name.each do |key, value|
|
86
|
+
self[key] = value
|
87
|
+
end
|
88
|
+
else
|
89
|
+
if @edge_attributs[attribut_name.to_s]
|
90
|
+
@edge_attributs[attribut_name.to_s].clone
|
91
|
+
else
|
92
|
+
nil
|
93
|
+
end
|
94
|
+
end
|
65
95
|
end
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
96
|
+
|
97
|
+
#
|
98
|
+
# Calls block once for each attribut of the edge, passing the name and value to the
|
99
|
+
# block as a two-element array.
|
100
|
+
#
|
101
|
+
# If global is set to false, the block does not receive the attributs set globally
|
102
|
+
#
|
103
|
+
def each_attribut(global = true, &b)
|
104
|
+
attrs = @edge_attributs.to_h
|
105
|
+
if global
|
106
|
+
attrs = pg.edge.to_h.merge attrs
|
107
|
+
end
|
108
|
+
attrs.each do |k,v|
|
109
|
+
yield(k,v)
|
110
|
+
end
|
75
111
|
end
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
def index
|
82
|
-
@index
|
83
|
-
end
|
84
|
-
def index=(i) #:nodoc:
|
85
|
-
@index = i if @index == nil
|
86
|
-
end
|
87
|
-
|
88
|
-
#
|
89
|
-
# Set value +xAttrValue+ to the edge attribut +xAttrName+
|
90
|
-
#
|
91
|
-
def []=( xAttrName, xAttrValue )
|
92
|
-
xAttrValue = xAttrValue.to_s if xAttrValue.class == Symbol
|
93
|
-
@oAttrEdge[xAttrName.to_s] = xAttrValue
|
94
|
-
end
|
95
|
-
|
96
|
-
#
|
97
|
-
# Set values for edge attributs or
|
98
|
-
# get the value of the given edge attribut +xAttrName+
|
99
|
-
#
|
100
|
-
def []( xAttrName )
|
101
|
-
# Modification by axgle (http://github.com/axgle)
|
102
|
-
if Hash === xAttrName
|
103
|
-
xAttrName.each do |key, value|
|
104
|
-
self[key] = value
|
105
|
-
end
|
106
|
-
else
|
107
|
-
if @oAttrEdge[xAttrName.to_s]
|
108
|
-
@oAttrEdge[xAttrName.to_s].clone
|
109
|
-
else
|
110
|
-
nil
|
111
|
-
end
|
112
|
+
|
113
|
+
def <<( node ) #:nodoc:
|
114
|
+
n = @parent_graph.get_node(@node_two_id)
|
115
|
+
|
116
|
+
GraphViz::commonGraph( node, n ).add_edge( n, node )
|
112
117
|
end
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
attrs = @oAttrEdge.to_h
|
123
|
-
if global
|
124
|
-
attrs = pg.edge.to_h.merge attrs
|
118
|
+
alias :> :<< #:nodoc:
|
119
|
+
alias :- :<< #:nodoc:
|
120
|
+
alias :>> :<< #:nodoc:
|
121
|
+
|
122
|
+
#
|
123
|
+
# Return the root graph
|
124
|
+
#
|
125
|
+
def root_graph
|
126
|
+
return( (self.pg.nil?) ? nil : self.pg.root_graph )
|
125
127
|
end
|
126
|
-
|
127
|
-
|
128
|
+
|
129
|
+
def pg #:nodoc:
|
130
|
+
@parent_graph
|
131
|
+
end
|
132
|
+
|
133
|
+
# Set edge attributs
|
134
|
+
#
|
135
|
+
# Example :
|
136
|
+
# e = graph.add_edge( ... )
|
137
|
+
# ...
|
138
|
+
# e.set { |_e|
|
139
|
+
# _e.color = "blue"
|
140
|
+
# _e.fontcolor = "red"
|
141
|
+
# }
|
142
|
+
def set( &b )
|
143
|
+
yield( self )
|
128
144
|
end
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
alias :- :<< #:nodoc:
|
138
|
-
alias :>> :<< #:nodoc:
|
139
|
-
|
140
|
-
#
|
141
|
-
# Return the root graph
|
142
|
-
#
|
143
|
-
def root_graph
|
144
|
-
return( (self.pg.nil?) ? nil : self.pg.root_graph )
|
145
|
-
end
|
146
|
-
|
147
|
-
def pg #:nodoc:
|
148
|
-
@oGParrent
|
149
|
-
end
|
150
|
-
|
151
|
-
#
|
152
|
-
# Set edge attributs
|
153
|
-
#
|
154
|
-
# Example :
|
155
|
-
# e = graph.add_edge( ... )
|
156
|
-
# ...
|
157
|
-
# e.set { |_e|
|
158
|
-
# _e.color = "blue"
|
159
|
-
# _e.fontcolor = "red"
|
160
|
-
# }
|
161
|
-
#
|
162
|
-
def set( &b )
|
163
|
-
yield( self )
|
164
|
-
end
|
165
|
-
|
166
|
-
# Add edge options
|
167
|
-
# use edge.<option>=<value> or edge.<option>( <value> )
|
168
|
-
def method_missing( idName, *args, &block ) #:nodoc:
|
169
|
-
return if idName == :to_ary # ruby 1.9.2 fix
|
170
|
-
xName = idName.id2name
|
171
|
-
|
172
|
-
self[xName.gsub( /=$/, "" )]=args[0]
|
173
|
-
end
|
174
|
-
|
175
|
-
def output( oGraphType ) #:nodoc:
|
176
|
-
xLink = " -> "
|
177
|
-
if oGraphType == "graph"
|
178
|
-
xLink = " -- "
|
179
|
-
end
|
180
|
-
|
181
|
-
xOut = self.node_one + xLink + self.node_two
|
182
|
-
xAttr = ""
|
183
|
-
xSeparator = ""
|
184
|
-
@oAttrEdge.data.each do |k, v|
|
185
|
-
xAttr << xSeparator + k + " = " + v.to_gv
|
186
|
-
xSeparator = ", "
|
145
|
+
|
146
|
+
# Add edge options
|
147
|
+
# use edge.<option>=<value> or edge.<option>( <value> )
|
148
|
+
def method_missing( idName, *args, &block ) #:nodoc:
|
149
|
+
return if idName == :to_ary # ruby 1.9.2 fix
|
150
|
+
xName = idName.id2name
|
151
|
+
|
152
|
+
self[xName.gsub( /=$/, "" )]=args[0]
|
187
153
|
end
|
188
|
-
|
189
|
-
|
154
|
+
|
155
|
+
def output( oGraphType ) #:nodoc:
|
156
|
+
xLink = " -> "
|
157
|
+
if oGraphType == "graph"
|
158
|
+
xLink = " -- "
|
159
|
+
end
|
160
|
+
|
161
|
+
xOut = self.node_one + xLink + self.node_two
|
162
|
+
xAttr = ""
|
163
|
+
xSeparator = ""
|
164
|
+
@edge_attributs.data.each do |k, v|
|
165
|
+
xAttr << xSeparator + k + " = " + v.to_gv
|
166
|
+
xSeparator = ", "
|
167
|
+
end
|
168
|
+
if xAttr.length > 0
|
169
|
+
xOut << " [" + xAttr + "]"
|
170
|
+
end
|
171
|
+
xOut + ";"
|
172
|
+
|
173
|
+
return( xOut )
|
190
174
|
end
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
name = node.id
|
175
|
+
|
176
|
+
private
|
177
|
+
def getNodeNameAndPort( node )
|
178
|
+
name, port = nil, nil
|
179
|
+
if node.class == Hash
|
180
|
+
node.each do |k, v|
|
181
|
+
name, port = getNodeNameAndPort(k)
|
182
|
+
port = v
|
183
|
+
end
|
184
|
+
elsif node.class == String
|
185
|
+
name = node
|
186
|
+
else
|
187
|
+
name = node.id
|
188
|
+
end
|
189
|
+
|
190
|
+
return name, port
|
208
191
|
end
|
209
|
-
|
210
|
-
return name, port
|
211
|
-
end
|
212
|
-
end
|
192
|
+
end
|
213
193
|
end
|