GraphvizR 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,10 @@
1
- == 1.0.0 / 2007-02-11
1
+ == 0.1.0 / 2007-02-15
2
+
3
+ * some feature is added
4
+ * undirected graph is available
5
+ * generate more sophisticated dot file
6
+
7
+ == 0.0.1 / 2007-02-11
2
8
 
3
9
  * 1 major enhancement
4
10
  * Birthday!
data/README.txt CHANGED
@@ -1,4 +1,4 @@
1
- GraphvizR
1
+ = GraphvizR
2
2
  by ANDO Yasushi
3
3
  http://blog.technohippy.net
4
4
 
@@ -39,9 +39,13 @@ replies the dot code:
39
39
 
40
40
  To know more detail, please see test/test_graphviz_r.rb
41
41
 
42
- == REQUIREMENTS:
42
+ == DEPENDENCIES:
43
43
 
44
- * Check Graphviz specification
44
+ * Graphviz (http://www.graphviz.org/)
45
+
46
+ == TODO:
47
+
48
+ * rails plugin
45
49
 
46
50
  == INSTALL:
47
51
 
@@ -1,5 +1,6 @@
1
1
  class GraphvizR
2
- VERSION = '0.0.1'
2
+ VERSION = '0.1.0'
3
+ INDENT_UNIT = ' '
3
4
 
4
5
  class Attributes
5
6
  def initialize(name, dot)
@@ -27,8 +28,18 @@ class GraphvizR
27
28
  end
28
29
 
29
30
  def >>(node)
31
+ @dot.directed!
32
+ add_edge_on_dot node
33
+ end
34
+
35
+ def -(node)
36
+ @dot.undirected!
37
+ add_edge_on_dot node
38
+ end
39
+
40
+ def add_edge_on_dot(node)
30
41
  prop = @prop.merge node.prop
31
- edge = Edge.new(self, node, prop)
42
+ edge = Edge.new(self, node, @dot, prop)
32
43
  @dot.add_edge edge
33
44
  edge
34
45
  end
@@ -51,14 +62,14 @@ class GraphvizR
51
62
  name = @port.dup
52
63
  name.unshift @name
53
64
  name.map{|e| e.to_dot}.join(':')
54
- #@name.to_dot
55
65
  end
56
66
  end
57
67
 
58
68
  class Edge
59
- def initialize(from, to, prop={})
69
+ def initialize(from, to, dot, prop={})
60
70
  @from = from
61
71
  @to = to
72
+ @dot = dot
62
73
  @property = prop
63
74
  end
64
75
 
@@ -71,7 +82,7 @@ class GraphvizR
71
82
  end
72
83
 
73
84
  def to_dot
74
- dot = "#{node_to_dot @from} -> #{node_to_dot @to}"
85
+ dot = "#{node_to_dot @from} #{@dot.directed? ? '->' : '--'} #{node_to_dot @to}"
75
86
  dot += " #{@property.to_dot}" unless @property.empty?
76
87
  dot
77
88
  end
@@ -85,7 +96,7 @@ class GraphvizR
85
96
  GraphvizR.new(name, prop).to_dot
86
97
  end
87
98
 
88
- def initialize(name, prop={}, graph_type='digraph')
99
+ def initialize(name, prop={}, parent=nil, indent=0)
89
100
  if name.is_a? Array
90
101
  initialize(*name)
91
102
  else
@@ -95,7 +106,9 @@ class GraphvizR
95
106
  @node_properties = {}
96
107
  @graph_properties = {}
97
108
  @subgraphs = []
98
- @graph_type = graph_type
109
+ @indent = indent + 1
110
+ @parent = parent
111
+ @directed = true
99
112
  interprete prop
100
113
  end
101
114
  end
@@ -128,24 +141,60 @@ class GraphvizR
128
141
  f = from.keys[0]
129
142
  t = from[f]
130
143
  p = to
131
- @edges << Edge.new(f, t, p)
144
+ @edges << Edge.new(f, t, self, p)
132
145
  elsif to.nil?
133
146
  # from is Edge instance
134
147
  @edges << from
135
148
  else
136
- @edges << Edge.new(from, to)
149
+ @edges << Edge.new(from, to, self)
137
150
  end
138
151
  end
139
152
 
140
153
  def add_subgraph(graphs)
141
154
  graphs.to_a.sort.each do |key_prop|
142
- @subgraphs << self.class.new(key_prop[0], key_prop[1], 'subgraph')
155
+ @subgraphs << self.class.new(key_prop[0], key_prop[1], self, @indent)
156
+ end
157
+ end
158
+
159
+ def subgraph?
160
+ not @parent.nil?
161
+ end
162
+
163
+ def directed!
164
+ if subgraph?
165
+ @parent.directed!
166
+ else
167
+ @directed = true
168
+ end
169
+ end
170
+
171
+ def undirected!
172
+ if subgraph?
173
+ @parent.undirected!
174
+ else
175
+ @directed = false
176
+ end
177
+ end
178
+
179
+ def directed?
180
+ if subgraph?
181
+ @parent.directed?
182
+ else
183
+ @directed
184
+ end
185
+ end
186
+
187
+ def undirected?
188
+ if subgraph?
189
+ @parent.undirected?
190
+ else
191
+ !@directed
143
192
  end
144
193
  end
145
194
 
146
195
  def [](key, *args, &block)
147
196
  if block
148
- subgraph = self.class.new(key, {}, 'subgraph')
197
+ subgraph = self.class.new key, {}, self, @indent
149
198
  block.call subgraph
150
199
  @subgraphs << subgraph
151
200
  else
@@ -176,16 +225,28 @@ class GraphvizR
176
225
  end
177
226
 
178
227
  def to_dot
179
- dot = "#{@graph_type} #{@name} {"
180
- dot += "graph #{@graph_properties.to_dot};" unless @graph_properties.empty?
181
- dot += @subgraphs.map{|e| e.to_dot}.join("\n") unless @subgraphs.empty?
228
+ graph_type = if subgraph?
229
+ 'subgraph'
230
+ elsif directed?
231
+ 'digraph'
232
+ else
233
+ 'graph'
234
+ end
235
+ dot = indent_enter("#{graph_type} #{@name} {", true)
236
+ dot += indent_enter("graph #{@graph_properties.to_dot};") unless @graph_properties.empty?
237
+ #dot += indent_enter(@subgraphs.map{|e| e.to_dot}.join("\n")) unless @subgraphs.empty?
238
+ dot += @subgraphs.map{|e| e.to_dot}.join('') unless @subgraphs.empty?
182
239
  dot += properties_to_dot(@default_node_properties) unless @default_node_properties.empty?
183
240
  dot += properties_to_dot(@node_properties) unless @node_properties.empty?
184
- dot += @edges.sort.map{|e| "#{e.to_dot};"}.join("\n")
185
- dot += "}"
241
+ dot += @edges.sort.map{|e| indent_enter("#{e.to_dot};")}.join("")
242
+ dot += indent_enter("}", true)
186
243
  dot
187
244
  end
188
245
 
246
+ def indent_enter(str, is_first=false)
247
+ "#{INDENT_UNIT * (@indent - (is_first ? 1 : 0))}#{str}\n"
248
+ end
249
+
189
250
  def data(format='png')
190
251
  gv = IO.popen "dot -q -T#{format || 'png'}", "w+"
191
252
  gv.puts to_dot
@@ -216,7 +277,7 @@ class GraphvizR
216
277
  protected
217
278
 
218
279
  def properties_to_dot(hash)
219
- hash.to_a.sort.map{|e| "#{e[0]} #{e[1].to_dot};"}.join("\n")
280
+ hash.to_a.sort.map{|e| indent_enter "#{e[0]} #{e[1].to_dot};"}.join()
220
281
  end
221
282
  end
222
283
 
@@ -17,7 +17,7 @@ class TestGraphvizR < Test::Unit::TestCase
17
17
  end
18
18
 
19
19
  def test_basic
20
- dot = GraphvizR.dot(:sample,
20
+ gvr = GraphvizR.dot(:sample,
21
21
  :graph => {:size => "1.5, 2.5"},
22
22
  :label => 'example',
23
23
  :node_properties => {
@@ -28,7 +28,8 @@ class TestGraphvizR < Test::Unit::TestCase
28
28
  :beta => :delta,
29
29
  :delta => 'size'
30
30
  )
31
- assert_equal <<-end_of_string.gsub(/\s/, ''), dot.gsub(/\s/, '')
31
+ #assert_equal <<-end_of_string.gsub(/\s/, ''), gvr.gsub(/\s/, '')
32
+ assert_equal <<-end_of_string, gvr
32
33
  digraph sample {
33
34
  graph [label = "example", size = "1.5, 2.5"];
34
35
  beta [shape = box];
@@ -40,20 +41,20 @@ digraph sample {
40
41
  end_of_string
41
42
  end
42
43
 
43
- #dot.graph = {:label => 'example', :size => '1.5, 2.5'}
44
- #dot.beta = {:shape => :box}
45
- #dot.graph[:label => 'example', :size => '1.5, 2.5']
46
- #dot.beta[:shape => :box]
44
+ #gvr.graph = {:label => 'example', :size => '1.5, 2.5'}
45
+ #gvr.beta = {:shape => :box}
46
+ #gvr.graph[:label => 'example', :size => '1.5, 2.5']
47
+ #gvr.beta[:shape => :box]
47
48
  def test_basic_dynamic
48
- dot = GraphvizR.new 'sample'
49
- dot.graph [:label => 'example', :size => '1.5, 2.5']
50
- dot.beta [:shape => :box]
51
- dot.alpha >> dot.beta
52
- (dot.alpha >> dot.gamma) [:label => 'label1']
53
- (dot.beta >> dot.delta) [:label => 'label2']
54
- dot.delta >> dot[:size]
55
-
56
- assert_equal <<-end_of_string.gsub(/\s/, ''), dot.to_dot.gsub(/\s/, '')
49
+ gvr = GraphvizR.new 'sample'
50
+ gvr.graph [:label => 'example', :size => '1.5, 2.5']
51
+ gvr.beta [:shape => :box]
52
+ gvr.alpha >> gvr.beta
53
+ (gvr.alpha >> gvr.gamma) [:label => 'label1']
54
+ (gvr.beta >> gvr.delta) [:label => 'label2']
55
+ gvr.delta >> gvr[:size]
56
+
57
+ assert_equal <<-end_of_string, gvr.to_dot
57
58
  digraph sample {
58
59
  graph [label = "example", size = "1.5, 2.5"];
59
60
  beta [shape = box];
@@ -66,7 +67,7 @@ digraph sample {
66
67
  end
67
68
 
68
69
  def test_record
69
- dot = GraphvizR.dot(:sample,
70
+ gvr = GraphvizR.dot(:sample,
70
71
  :graph => {:size => "1.5, 2.5"},
71
72
  :node => {:shape => :record},
72
73
  :node_properties => {
@@ -78,7 +79,8 @@ digraph sample {
78
79
  :node2 => [:node1, :p_center],
79
80
  {:node2 => [:node1, :p_right]} => {:label => 'record'}
80
81
  )
81
- assert_equal <<-end_of_string.gsub(/\s/, ''), dot.gsub(/\s/, '')
82
+ #assert_equal <<-end_of_string.gsub(/\s/, ''), gvr.gsub(/\s/, '')
83
+ assert_equal <<-end_of_string, gvr
82
84
  digraph sample {
83
85
  graph [size = "1.5, 2.5"];
84
86
  node [shape = record];
@@ -92,22 +94,22 @@ digraph sample {
92
94
  end_of_string
93
95
  end
94
96
 
95
- #dot.size = '1.5, 2.5'
96
- #dot.node = {:shape => :record}
97
- #d dot.node1 = {:label => "<p_left> left|<p_center>center|<p_right> right"}
98
- #dot.node2 = {:label => "left|center|right"}
97
+ #gvr.size = '1.5, 2.5'
98
+ #gvr.node = {:shape => :record}
99
+ #d gvr.node1 = {:label => "<p_left> left|<p_center>center|<p_right> right"}
100
+ #gvr.node2 = {:label => "left|center|right"}
99
101
  def test_record_dynamic
100
- dot = GraphvizR.new 'sample'
101
- dot.graph [:size => '1.5, 2.5']
102
- dot.node [:shape => :record]
103
- dot.node1 [:label => "<p_left> left|<p_center>center|<p_right> right"]
104
- dot.node2 [:label => "left|center|right"]
105
- dot.node1 >> dot.node2
106
- dot.node1(:p_left) >> dot.node2
107
- dot.node2 >> dot.node1(:p_center)
108
- (dot.node2 >> dot.node1(:p_right)) [:label => 'record']
109
-
110
- assert_equal <<-end_of_string.gsub(/\s/, ''), dot.to_dot.gsub(/\s/, '')
102
+ gvr = GraphvizR.new 'sample'
103
+ gvr.graph [:size => '1.5, 2.5']
104
+ gvr.node [:shape => :record]
105
+ gvr.node1 [:label => "<p_left> left|<p_center>center|<p_right> right"]
106
+ gvr.node2 [:label => "left|center|right"]
107
+ gvr.node1 >> gvr.node2
108
+ gvr.node1(:p_left) >> gvr.node2
109
+ gvr.node2 >> gvr.node1(:p_center)
110
+ (gvr.node2 >> gvr.node1(:p_right)) [:label => 'record']
111
+
112
+ assert_equal <<-end_of_string, gvr.to_dot
111
113
  digraph sample {
112
114
  graph [size = "1.5, 2.5"];
113
115
  node [shape = record];
@@ -122,7 +124,7 @@ digraph sample {
122
124
  end
123
125
 
124
126
  def test_subgraph
125
- dot = GraphvizR.dot(:sample,
127
+ gvr = GraphvizR.dot(:sample,
126
128
  :subgraphs => {
127
129
  :cluster0 => {
128
130
  :color => :blue,
@@ -144,10 +146,11 @@ digraph sample {
144
146
  {:c => :f} => {:lhead => :cluster1},
145
147
  {:a => :f} => {:ltail => :cluster0, :lhead => :cluster1}
146
148
  )
147
- assert_equal <<-end_of_string.gsub(/\s/, ''), dot.gsub(/\s/, '')
149
+ #assert_equal <<-end_of_string.gsub(/\s/, ''), gvr.gsub(/\s/, '')
150
+ assert_equal <<-end_of_string, gvr
148
151
  digraph sample {
149
152
  subgraph cluster0 {
150
- graph [color = blue, label ="area 0", style = bold];
153
+ graph [color = blue, label = "area 0", style = bold];
151
154
  a -> b;
152
155
  a -> c;
153
156
  }
@@ -171,26 +174,26 @@ digraph sample {
171
174
  #c1.label = 'area 1'
172
175
  #c1.style = :filled
173
176
  def test_subgrpah_dynamic
174
- dot = GraphvizR.new 'sample'
175
- dot.cluster0 do |c0|
177
+ gvr = GraphvizR.new 'sample'
178
+ gvr.cluster0 do |c0|
176
179
  c0.graph [:color => :blue, :label => 'area 0', :style => :bold]
177
180
  c0.a >> c0.b
178
181
  c0.a >> c0.c
179
182
  end
180
- dot.cluster1 do |c1|
183
+ gvr.cluster1 do |c1|
181
184
  c1.graph [:fillcolor => '#cc9966', :label => 'area 1', :style => :filled]
182
185
  c1.d >> c1.e
183
186
  c1.d >> c1.f
184
187
  end
185
- (dot.a >> dot.f) [:lhead => :cluster1, :ltail => :cluster0]
186
- dot.b >> dot.d
187
- (dot.c >> dot.d) [:ltail => :cluster0]
188
- (dot.c >> dot.f) [:lhead => :cluster1]
188
+ (gvr.a >> gvr.f) [:lhead => :cluster1, :ltail => :cluster0]
189
+ gvr.b >> gvr.d
190
+ (gvr.c >> gvr.d) [:ltail => :cluster0]
191
+ (gvr.c >> gvr.f) [:lhead => :cluster1]
189
192
 
190
- assert_equal <<-end_of_string.gsub(/\s/, ''), dot.to_dot.gsub(/\s/, '')
193
+ assert_equal <<-end_of_string, gvr.to_dot
191
194
  digraph sample {
192
195
  subgraph cluster0 {
193
- graph [color = blue, label ="area 0", style = bold];
196
+ graph [color = blue, label = "area 0", style = bold];
194
197
  a -> b;
195
198
  a -> c;
196
199
  }
@@ -203,6 +206,66 @@ digraph sample {
203
206
  b -> d;
204
207
  c -> d [ltail = cluster0];
205
208
  c -> f [lhead = cluster1];
209
+ }
210
+ end_of_string
211
+ end
212
+
213
+ def test_undirected_graph
214
+ gvr = GraphvizR.new 'sample'
215
+ gvr.graph [:label => 'example', :size => '1.5, 2.5']
216
+ gvr.beta [:shape => :box]
217
+ gvr.alpha - gvr.beta
218
+ (gvr.alpha - gvr.gamma) [:label => 'label1']
219
+ (gvr.beta - gvr.delta) [:label => 'label2']
220
+ gvr.delta - gvr[:size]
221
+
222
+ #assert_equal <<-end_of_string.gsub(/\s/, ''), gvr.to_dot.gsub(/\s/, '')
223
+ assert_equal <<-end_of_string, gvr.to_dot
224
+ graph sample {
225
+ graph [label = "example", size = "1.5, 2.5"];
226
+ beta [shape = box];
227
+ alpha -- beta;
228
+ alpha -- gamma [label = "label1"];
229
+ beta -- delta [label = "label2"];
230
+ delta -- size;
231
+ }
232
+ end_of_string
233
+ end
234
+
235
+ def test_undirected_subgrpah
236
+ gvr = GraphvizR.new 'sample'
237
+ gvr.cluster0 do |c0|
238
+ c0.graph [:color => :blue, :label => 'area 0', :style => :bold]
239
+ c0.a - c0.b
240
+ c0.a - c0.c
241
+ end
242
+ gvr.cluster1 do |c1|
243
+ c1.graph [:fillcolor => '#cc9966', :label => 'area 1', :style => :filled]
244
+ c1.d - c1.e
245
+ c1.d - c1.f
246
+ end
247
+ (gvr.a - gvr.f) [:lhead => :cluster1, :ltail => :cluster0]
248
+ gvr.b - gvr.d
249
+ (gvr.c - gvr.d) [:ltail => :cluster0]
250
+ (gvr.c - gvr.f) [:lhead => :cluster1]
251
+
252
+ #assert_equal <<-end_of_string.gsub(/\s/, ''), gvr.to_dot.gsub(/\s/, '')
253
+ assert_equal <<-end_of_string, gvr.to_dot
254
+ graph sample {
255
+ subgraph cluster0 {
256
+ graph [color = blue, label = "area 0", style = bold];
257
+ a -- b;
258
+ a -- c;
259
+ }
260
+ subgraph cluster1 {
261
+ graph [fillcolor = "#cc9966", label = "area 1", style = filled];
262
+ d -- e;
263
+ d -- f;
264
+ }
265
+ a -- f [lhead = cluster1, ltail = cluster0];
266
+ b -- d;
267
+ c -- d [ltail = cluster0];
268
+ c -- f [lhead = cluster1];
206
269
  }
207
270
  end_of_string
208
271
  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.0.1
7
- date: 2007-02-14 00:00:00 +09:00
6
+ version: 0.1.0
7
+ date: 2007-02-15 00:00:00 +09:00
8
8
  summary: The author was too lazy to write a summary
9
9
  require_paths:
10
10
  - lib