ruby-graphviz 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|