GraphvizR 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +7 -1
- data/README.txt +7 -3
- data/lib/graphviz_r.rb +78 -17
- data/test/test_graphviz_r.rb +107 -44
- metadata +2 -2
data/History.txt
CHANGED
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
|
-
==
|
42
|
+
== DEPENDENCIES:
|
43
43
|
|
44
|
-
*
|
44
|
+
* Graphviz (http://www.graphviz.org/)
|
45
|
+
|
46
|
+
== TODO:
|
47
|
+
|
48
|
+
* rails plugin
|
45
49
|
|
46
50
|
== INSTALL:
|
47
51
|
|
data/lib/graphviz_r.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
class GraphvizR
|
2
|
-
VERSION = '0.0
|
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={},
|
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
|
-
@
|
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],
|
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
|
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
|
-
|
180
|
-
|
181
|
-
|
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("
|
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(
|
280
|
+
hash.to_a.sort.map{|e| indent_enter "#{e[0]} #{e[1].to_dot};"}.join()
|
220
281
|
end
|
221
282
|
end
|
222
283
|
|
data/test/test_graphviz_r.rb
CHANGED
@@ -17,7 +17,7 @@ class TestGraphvizR < Test::Unit::TestCase
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def test_basic
|
20
|
-
|
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/, ''),
|
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
|
-
#
|
44
|
-
#
|
45
|
-
#
|
46
|
-
#
|
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
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
(
|
53
|
-
(
|
54
|
-
|
55
|
-
|
56
|
-
assert_equal <<-end_of_string
|
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
|
-
|
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/, ''),
|
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
|
-
#
|
96
|
-
#
|
97
|
-
#d
|
98
|
-
#
|
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
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
(
|
109
|
-
|
110
|
-
assert_equal <<-end_of_string
|
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
|
-
|
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/, ''),
|
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
|
-
|
175
|
-
|
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
|
-
|
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
|
-
(
|
186
|
-
|
187
|
-
(
|
188
|
-
(
|
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
|
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
|
7
|
-
date: 2007-02-
|
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
|