ruby-graphviz 1.0.9 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -59,7 +59,7 @@ class GraphViz
59
59
  end
60
60
 
61
61
  begin
62
- value = GraphViz::Types.const_get(@attributes[key.to_s]).new( value )
62
+ value = GraphViz::Types.const_get(@attributes[key.to_s]).new(value)
63
63
  rescue => e
64
64
  raise AttributeException, "Invalid value `#{value}` for attribute `#{key}` : #{e}"
65
65
  end
@@ -41,7 +41,7 @@
41
41
  #
42
42
  class GraphViz
43
43
  module Constants
44
- RGV_VERSION = "1.0.9"
44
+ RGV_VERSION = "1.1.0"
45
45
 
46
46
  ## Const: Output formats
47
47
  FORMATS = [
@@ -24,13 +24,16 @@ class Dot2Ruby #:nodoc:
24
24
  def initialize( xGVPath, xOutFile, xOutFormat = nil ) #:nodoc:
25
25
  paths = (xGVPath.nil?) ? [] : [xGVPath]
26
26
  @xGvprPath = find_executable( 'gvpr', paths )
27
+ if (@xGvprPath.blank?)
28
+ raise Exception, "GraphViz is not installed. Please be sure that 'gvpr' is on the search path'"
29
+ end
27
30
  @xOutFile = xOutFile
28
31
  @xOutFormat = xOutFormat || "_"
29
32
  @gvprScript = GraphViz::Ext.find( "dot2ruby.g" )
30
33
  end
31
34
 
32
35
  def run( xFile ) #:nodoc:
33
- xCmd = "#{@xGvprPath} -f #{@gvprScript} -a #{@xOutFormat} #{xFile}"
36
+ xCmd = [@xGvprPath, '-f', @gvprScript, '-a', @xOutFormat, xFile]
34
37
  xOutput = output_from_command( xCmd )
35
38
  if @xOutFile.nil?
36
39
  puts xOutput
@@ -42,7 +45,7 @@ class Dot2Ruby #:nodoc:
42
45
  end
43
46
 
44
47
  def eval( xFile ) #:nodoc:
45
- xCmd = "#{@xGvprPath} -f #{@gvprScript} -a \"-\" #{xFile}"
48
+ xCmd = [@xGvprPath, '-f', @gvprScript, '-a', '-', xFile]
46
49
  xOutput = output_from_command( xCmd )
47
50
  instance_eval(xOutput)
48
51
  return @_graph_eval
@@ -18,180 +18,185 @@ require 'graphviz/attrs'
18
18
  require 'graphviz/constants'
19
19
 
20
20
  class GraphViz
21
- class Edge
22
- include GraphViz::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_attributes = 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_nodes(@node_one_id)).incidents << (@parent_graph.find_node(@node_two_id) || @parent_graph.add_nodes(@node_two_id))
40
- (@parent_graph.find_node(@node_two_id) || @parent_graph.add_nodes(@node_two_id)).neighbors << (@parent_graph.find_node(@node_one_id) || @parent_graph.add_nodes(@node_one_id))
41
- end
42
- (@parent_graph.find_node(@node_one_id) || @parent_graph.add_nodes(@node_one_id)).neighbors << (@parent_graph.find_node(@node_two_id) || @parent_graph.add_nodes(@node_two_id))
43
- (@parent_graph.find_node(@node_two_id) || @parent_graph.add_nodes(@node_two_id)).incidents << (@parent_graph.find_node(@node_one_id) || @parent_graph.add_nodes(@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 not(@node_one_port and with_port)
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 not(@node_two_port and with_port)
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 +attribute_value+ to the edge attribute +attribute_name+
75
- def []=( attribute_name, attribute_value )
76
- attribute_value = attribute_value.to_s if attribute_value.class == Symbol
77
- @edge_attributes[attribute_name.to_s] = attribute_value
78
- end
79
-
80
- # Set values for edge attributes or
81
- # get the value of the given edge attribute +attribute_name+
82
- def []( attribute_name )
83
- # Modification by axgle (http://github.com/axgle)
84
- if Hash === attribute_name
85
- attribute_name.each do |key, value|
86
- self[key] = value
87
- end
88
- else
89
- if @edge_attributes[attribute_name.to_s]
90
- @edge_attributes[attribute_name.to_s].clone
91
- else
92
- nil
93
- end
94
- end
95
- end
96
-
97
- #
98
- # Calls block once for each attribute 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 attributes set globally
102
- #
103
- def each_attribute(global = true, &b)
104
- attrs = @edge_attributes.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
111
- end
112
- def each_attribut(global = true, &b)
113
- warn "`GraphViz::Edge#each_attribut` is deprecated, please use `GraphViz::Edge#each_attribute`"
114
- each_attribute(global, &b)
115
- end
116
-
117
- def <<( node ) #:nodoc:
118
- n = @parent_graph.get_node(@node_two_id)
119
-
120
- GraphViz::commonGraph( node, n ).add_edges( n, node )
121
- end
122
- alias :> :<< #:nodoc:
123
- alias :- :<< #:nodoc:
124
- alias :>> :<< #:nodoc:
125
-
126
- #
127
- # Return the root graph
128
- #
129
- def root_graph
130
- return( (self.pg.nil?) ? nil : self.pg.root_graph )
131
- end
132
-
133
- def pg #:nodoc:
134
- @parent_graph
135
- end
136
-
137
- # Set edge attributes
138
- #
139
- # Example :
140
- # e = graph.add_edges( ... )
141
- # ...
142
- # e.set { |_e|
143
- # _e.color = "blue"
144
- # _e.fontcolor = "red"
145
- # }
146
- def set( &b )
147
- yield( self )
148
- end
149
-
150
- # Add edge options
151
- # use edge.<option>=<value> or edge.<option>( <value> )
152
- def method_missing( idName, *args, &block ) #:nodoc:
153
- return if idName == :to_ary # ruby 1.9.2 fix
154
- xName = idName.id2name
155
-
156
- self[xName.gsub( /=$/, "" )]=args[0]
157
- end
158
-
159
- def output( oGraphType ) #:nodoc:
160
- xLink = " -> "
161
- if oGraphType == "graph"
162
- xLink = " -- "
163
- end
164
-
165
- xOut = self.node_one + xLink + self.node_two
166
- xAttr = ""
167
- xSeparator = ""
168
- @edge_attributes.data.each do |k, v|
169
- xAttr << xSeparator + k + " = " + v.to_gv
170
- xSeparator = ", "
171
- end
172
- if xAttr.length > 0
173
- xOut << " [" + xAttr + "]"
174
- end
175
- xOut << ";"
176
-
177
- return( xOut )
178
- end
179
-
180
- private
181
- def getNodeNameAndPort( node )
182
- name, port = nil, nil
183
- if node.class == Hash
184
- node.each do |k, v|
185
- name, port = getNodeNameAndPort(k)
186
- port = v
187
- end
188
- elsif node.class == String
189
- name = node
190
- else
191
- name = node.id
192
- end
193
-
194
- return name, port
195
- end
196
- end
21
+ class Edge
22
+ include GraphViz::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_attributes = 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_nodes(@node_one_id)).incidents << (@parent_graph.find_node(@node_two_id) || @parent_graph.add_nodes(@node_two_id))
40
+ (@parent_graph.find_node(@node_two_id) || @parent_graph.add_nodes(@node_two_id)).neighbors << (@parent_graph.find_node(@node_one_id) || @parent_graph.add_nodes(@node_one_id))
41
+ end
42
+ (@parent_graph.find_node(@node_one_id) || @parent_graph.add_nodes(@node_one_id)).neighbors << (@parent_graph.find_node(@node_two_id) || @parent_graph.add_nodes(@node_two_id))
43
+ (@parent_graph.find_node(@node_two_id) || @parent_graph.add_nodes(@node_two_id)).incidents << (@parent_graph.find_node(@node_one_id) || @parent_graph.add_nodes(@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, escaped = true)
48
+ if not(@node_one_port and with_port)
49
+ escaped ? GraphViz.escape(@node_one_id) : @node_one_id
50
+ else
51
+ escaped ? GraphViz.escape(@node_one_id, :force => true) + ":#{@node_one_port}" : "#{@node_one_id}:#{@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, escaped = true)
58
+ if not(@node_two_port and with_port)
59
+ escaped ? GraphViz.escape(@node_two_id) : @node_two_id
60
+ else
61
+ escaped ? GraphViz.escape(@node_two_id, :force => true) + ":#{@node_two_port}" : "#{@node_two_id}:#{@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 +attribute_value+ to the edge attribute +attribute_name+
75
+ def []=( attribute_name, attribute_value )
76
+ attribute_value = attribute_value.to_s if attribute_value.class == Symbol
77
+ @edge_attributes[attribute_name.to_s] = attribute_value
78
+ end
79
+
80
+ # Set values for edge attributes or
81
+ # get the value of the given edge attribute +attribute_name+
82
+ def []( attribute_name )
83
+ # Modification by axgle (http://github.com/axgle)
84
+ if Hash === attribute_name
85
+ attribute_name.each do |key, value|
86
+ self[key] = value
87
+ end
88
+ else
89
+ if @edge_attributes[attribute_name.to_s]
90
+ @edge_attributes[attribute_name.to_s].clone
91
+ else
92
+ nil
93
+ end
94
+ end
95
+ end
96
+
97
+ #
98
+ # Calls block once for each attribute 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 attributes set globally
102
+ #
103
+ def each_attribute(global = true, &b)
104
+ attrs = @edge_attributes.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
111
+ end
112
+ def each_attribut(global = true, &b)
113
+ warn "`GraphViz::Edge#each_attribut` is deprecated, please use `GraphViz::Edge#each_attribute`"
114
+ each_attribute(global, &b)
115
+ end
116
+
117
+ def <<( node ) #:nodoc:
118
+ n = @parent_graph.get_node(@node_two_id)
119
+
120
+ GraphViz::commonGraph( node, n ).add_edges( n, node )
121
+ end
122
+ alias :> :<< #:nodoc:
123
+ alias :- :<< #:nodoc:
124
+ alias :>> :<< #:nodoc:
125
+
126
+ #
127
+ # Return the root graph
128
+ #
129
+ def root_graph
130
+ return( (self.pg.nil?) ? nil : self.pg.root_graph )
131
+ end
132
+
133
+ def pg #:nodoc:
134
+ @parent_graph
135
+ end
136
+
137
+ # Set edge attributes
138
+ #
139
+ # Example :
140
+ # e = graph.add_edges( ... )
141
+ # ...
142
+ # e.set { |_e|
143
+ # _e.color = "blue"
144
+ # _e.fontcolor = "red"
145
+ # }
146
+ def set( &b )
147
+ yield( self )
148
+ end
149
+
150
+ # Add edge options
151
+ # use edge.<option>=<value> or edge.<option>( <value> )
152
+ def method_missing( idName, *args, &block ) #:nodoc:
153
+ return if idName == :to_ary # ruby 1.9.2 fix
154
+ xName = idName.id2name
155
+
156
+ self[xName.gsub( /=$/, "" )]=args[0]
157
+ end
158
+
159
+ def output( oGraphType ) #:nodoc:
160
+ xLink = " -> "
161
+ if oGraphType == "graph"
162
+ xLink = " -- "
163
+ end
164
+
165
+ # reserved words, they aren't accepted in dot as node name
166
+ reserved_names = ["node", "edge","graph", "digraph", "subgraph", "strict"]
167
+
168
+ xOut = reserved_names.include?(self.node_one) ? "" << "_" + self.node_one : "" << self.node_one
169
+ xOut = xOut << xLink
170
+ xOut = reserved_names.include?(self.node_two) ? xOut << "_" + self.node_two : xOut << self.node_two
171
+ xAttr = ""
172
+ xSeparator = ""
173
+ @edge_attributes.data.each do |k, v|
174
+ xAttr << xSeparator + k + " = " + v.to_gv
175
+ xSeparator = ", "
176
+ end
177
+ if xAttr.length > 0
178
+ xOut << " [" + xAttr + "]"
179
+ end
180
+ xOut << ";"
181
+
182
+ return( xOut )
183
+ end
184
+
185
+ private
186
+ def getNodeNameAndPort( node )
187
+ name, port = nil, nil
188
+ if node.class == Hash
189
+ node.each do |k, v|
190
+ name, port = getNodeNameAndPort(k)
191
+ port = v
192
+ end
193
+ elsif node.class == String
194
+ name = node
195
+ else
196
+ name = node.id
197
+ end
198
+
199
+ return name, port
200
+ end
201
+ end
197
202
  end
@@ -134,11 +134,16 @@ class GraphViz
134
134
  end
135
135
 
136
136
  def output #:nodoc:
137
+ # reserved words, they aren't accepted in dot as node name
138
+ reserved_names = ["node", "edge","graph", "digraph", "subgraph", "strict"]
137
139
  #node_id = @node_id.clone
138
140
  #node_id = '"' << node_id << '"' if node_id.match( /^[a-zA-Z_]+[a-zA-Z0-9_\.]*$/ ).nil?
139
141
  node_id = GraphViz.escape(@node_id)
140
142
 
141
- xOut = "" << node_id
143
+ # add a check to see if the node names are valid
144
+ # if they aren't is added an _ before
145
+ # and the print staies the same, because of the label
146
+ xOut = reserved_names.include?(node_id) ? "" << "_" + node_id : "" << node_id
142
147
  xAttr = ""
143
148
  xSeparator = ""
144
149
 
@@ -11,8 +11,8 @@ class GraphViz
11
11
  matrix = GraphViz::Math::Matrix.new( @graph.node_count, @graph.node_count )
12
12
 
13
13
  @graph.each_edge { |e|
14
- x = @graph.get_node(e.node_one( false )).index
15
- y = @graph.get_node(e.node_two( false )).index
14
+ x = @graph.get_node(e.node_one(false, false)).index
15
+ y = @graph.get_node(e.node_two(false, false)).index
16
16
  matrix[x+1, y+1] = 1
17
17
  matrix[y+1, x+1] = 1 if @graph.type == "graph"
18
18
  }
@@ -28,8 +28,8 @@ class GraphViz
28
28
  @graph.each_edge { |e|
29
29
  x = e.index
30
30
 
31
- nstart = @graph.get_node(e.node_one( false )).index
32
- nend = @graph.get_node(e.node_two( false )).index
31
+ nstart = @graph.get_node(e.node_one(false, false)).index
32
+ nend = @graph.get_node(e.node_two(false, false)).index
33
33
 
34
34
  matrix[nstart+1, x+1] = 1
35
35
  matrix[nend+1, x+1] = tail
@@ -48,7 +48,7 @@ class GraphViz
48
48
  end
49
49
 
50
50
  @graph.each_edge do |e|
51
- degree += 1 if e.node_one(false) == name or e.node_two(false) == name
51
+ degree += 1 if e.node_one(false, false) == name or e.node_two(false, false) == name
52
52
  end
53
53
 
54
54
  return degree
@@ -246,8 +246,8 @@ class GraphViz
246
246
  matrix = GraphViz::Math::Matrix.new( @graph.node_count, @graph.node_count, (1.0/0.0) )
247
247
 
248
248
  @graph.each_edge { |e|
249
- x = @graph.get_node(e.node_one( false )).index
250
- y = @graph.get_node(e.node_two( false )).index
249
+ x = @graph.get_node(e.node_one(false, false)).index
250
+ y = @graph.get_node(e.node_two(false, false)).index
251
251
  unless x == y
252
252
  weight = ((e[:weight].nil?) ? 1 : e[:weight].to_f)
253
253
  matrix[x+1, y+1] = weight