rgl 0.6.2 → 0.6.3
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.
- checksums.yaml +4 -4
- data/README.md +37 -2
- data/examples/graph.dot +18 -934
- data/lib/rgl/base.rb +1 -1
- data/lib/rgl/dot.rb +46 -14
- data/lib/rgl/rdot.rb +185 -134
- data/test/dot_test.rb +23 -29
- metadata +2 -2
data/lib/rgl/base.rb
CHANGED
data/lib/rgl/dot.rb
CHANGED
@@ -10,9 +10,7 @@
|
|
10
10
|
require 'rgl/rdot'
|
11
11
|
|
12
12
|
module RGL
|
13
|
-
|
14
13
|
module Graph
|
15
|
-
|
16
14
|
# Returns a label for vertex v. Default is v.to_s
|
17
15
|
def vertex_label(v)
|
18
16
|
v.to_s
|
@@ -22,6 +20,27 @@ module RGL
|
|
22
20
|
v
|
23
21
|
end
|
24
22
|
|
23
|
+
# Set the configuration values for the given vertex
|
24
|
+
def set_vertex_options(vertex, **options)
|
25
|
+
@vertex_options ||= {}
|
26
|
+
@vertex_options[vertex] ||= {}
|
27
|
+
|
28
|
+
RGL::DOT::NODE_OPTS.each do |opt|
|
29
|
+
@vertex_options[vertex][:"#{opt}"] = options[:"#{opt}"] if options.key?(:"#{opt}")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Set the configuration values for the given edge
|
34
|
+
def set_edge_options(u, v, **options)
|
35
|
+
edge = edge_class.new(u, v)
|
36
|
+
@edge_options ||= {}
|
37
|
+
@edge_options[edge] ||= {}
|
38
|
+
|
39
|
+
RGL::DOT::EDGE_OPTS.each do |opt|
|
40
|
+
@edge_options[edge][:"#{opt}"] = options[:"#{opt}"] if options.key?(:"#{opt}")
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
25
44
|
# Return a {DOT::Digraph} for directed graphs or a {DOT::Graph} for an
|
26
45
|
# undirected {Graph}. _params_ can contain any graph property specified in
|
27
46
|
# rdot.rb.
|
@@ -31,30 +50,43 @@ module RGL
|
|
31
50
|
fontsize = params['fontsize'] ? params['fontsize'] : '8'
|
32
51
|
graph = (directed? ? DOT::Digraph : DOT::Graph).new(params)
|
33
52
|
edge_class = directed? ? DOT::DirectedEdge : DOT::Edge
|
34
|
-
vertex_options = params['vertex'] || {}
|
35
|
-
edge_options = params['edge'] || {}
|
36
53
|
|
37
54
|
each_vertex do |v|
|
38
|
-
default_vertex_options =
|
55
|
+
default_vertex_options = {
|
39
56
|
'name' => vertex_id(v),
|
40
57
|
'fontsize' => fontsize,
|
41
58
|
'label' => vertex_label(v)
|
42
59
|
}
|
43
|
-
each_vertex_options = default_vertex_options
|
44
|
-
|
60
|
+
each_vertex_options = default_vertex_options
|
61
|
+
|
62
|
+
if @vertex_options && @vertex_options[v]
|
63
|
+
RGL::DOT::NODE_OPTS.each do |opt|
|
64
|
+
if @vertex_options[v].key?(:"#{opt}")
|
65
|
+
each_vertex_options["#{opt}"] = @vertex_options[v].fetch(:"#{opt}")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
45
69
|
graph << DOT::Node.new(each_vertex_options)
|
46
70
|
end
|
47
71
|
|
48
|
-
|
72
|
+
edges.each do |edge|
|
49
73
|
default_edge_options = {
|
50
|
-
'from' =>
|
51
|
-
'to' =>
|
74
|
+
'from' => edge.source,
|
75
|
+
'to' => edge.target,
|
52
76
|
'fontsize' => fontsize
|
53
77
|
}
|
54
|
-
|
55
|
-
|
78
|
+
|
79
|
+
each_edge_options = default_edge_options
|
80
|
+
|
81
|
+
if @edge_options && @edge_options[edge]
|
82
|
+
RGL::DOT::EDGE_OPTS.each do |opt|
|
83
|
+
if @edge_options[edge].key?(:"#{opt}")
|
84
|
+
each_edge_options["#{opt}"] = @edge_options[edge].fetch(:"#{opt}")
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
56
88
|
graph << edge_class.new(each_edge_options)
|
57
|
-
|
89
|
+
end
|
58
90
|
|
59
91
|
graph
|
60
92
|
end
|
@@ -81,7 +113,7 @@ module RGL
|
|
81
113
|
# Use dot[https://www.graphviz.org] to create a graphical representation of
|
82
114
|
# the graph. Returns the filename of the graphics file.
|
83
115
|
#
|
84
|
-
def write_to_graphic_file(fmt='png', dotfile="graph", options={})
|
116
|
+
def write_to_graphic_file(fmt = 'png', dotfile = "graph", options = {})
|
85
117
|
src = dotfile + ".dot"
|
86
118
|
dot = dotfile + "." + fmt
|
87
119
|
|
data/lib/rgl/rdot.rb
CHANGED
@@ -7,131 +7,185 @@ module RGL
|
|
7
7
|
# It also supports undirected edges.
|
8
8
|
module DOT
|
9
9
|
|
10
|
-
#
|
10
|
+
# attributes due to
|
11
|
+
# https://www.graphviz.org/pdf/dotguide.pdf
|
12
|
+
# January 5, 2015
|
11
13
|
|
14
|
+
# options for node declaration
|
12
15
|
NODE_OPTS = [
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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
|
-
|
16
|
+
'color', # default: black; node shape color
|
17
|
+
'colorscheme', # default: X11; scheme for interpreting color names
|
18
|
+
'comment', # any string (format-dependent)
|
19
|
+
'distortion', # default: 0.0; node distortion for shape=polygon
|
20
|
+
'fillcolor', # default: lightgrey/black; node fill color
|
21
|
+
'fixedsize', # default: false; label text has no affect on node size
|
22
|
+
'fontcolor', # default: black; type face color
|
23
|
+
'fontname', # default: Times-Roman; font family
|
24
|
+
'fontsize', # default: 14; point size of label
|
25
|
+
'group', # name of node's group
|
26
|
+
'height', # default: .5; height in inches
|
27
|
+
'id', # any string (user-defined output object tags)
|
28
|
+
'label', # default: node name; any string
|
29
|
+
'labelloc', # default: c; node label vertical alignment
|
30
|
+
'layer', # default: overlay range; all, id or id:id
|
31
|
+
'margin', # default: 0.11,0.55; space around label
|
32
|
+
'nojustify', # default: false; if true, justify to label, not node
|
33
|
+
'orientation', # default: 0.0; node rotation angle
|
34
|
+
'penwidth', # default: 1.0; width of pen for drawing boundaries, in points
|
35
|
+
'peripheries', # shape-dependent number of node boundaries
|
36
|
+
'regular', # default: false; force polygon to be regular
|
37
|
+
'samplepoints', # default 8 or 20; number vertices to convert circle or ellipse
|
38
|
+
'shape', # default: ellipse; node shape; see Section 2.1 and Appendix E
|
39
|
+
'shapefile', # external EPSF or SVG custom shape file
|
40
|
+
'sides', # default: 4; number of sides for shape=polygon
|
41
|
+
'skew', # default: 0.0; skewing of node for shape=polygon
|
42
|
+
'style', # graphics options, e.g. bold, dotted, filled; cf. Section 2.3
|
43
|
+
'target', # if URL is set, determines browser window for URL
|
44
|
+
'tooltip', # default: label, tooltip annotation for node
|
45
|
+
'URL', # URL associated with node (format-dependent)
|
46
|
+
'width', # default: .75; width in inches
|
47
|
+
].freeze
|
48
|
+
|
49
|
+
# maintained for backward compatibility or rdot internal
|
50
|
+
NODE_OPTS_LGCY = [
|
51
|
+
'bottomlabel', # auxiliary label for nodes of shape M*
|
52
|
+
'bgcolor',
|
53
|
+
'rank',
|
54
|
+
'toplabel' # auxiliary label for nodes of shape M*
|
55
|
+
].freeze
|
46
56
|
|
47
57
|
# options for edge declaration
|
48
|
-
|
49
58
|
EDGE_OPTS = [
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
59
|
+
'arrowhead', # default: normal; style of arrowhead at head end
|
60
|
+
'arrowsize', # default: 1.0; scaling factor for arrowheads
|
61
|
+
'arrowtail', # default: normal; style of arrowhead at tail end
|
62
|
+
'color', # default: black; edge stroke color
|
63
|
+
'colorscheme', # default: X11; scheme for interpreting color names
|
64
|
+
'comment', # any string (format-dependent)
|
65
|
+
'constraint', # default: true use edge to affect node ranking
|
66
|
+
'decorate', # if set, draws a line connecting labels with their edges
|
67
|
+
'dir', # default: forward; forward, back, both, or none
|
68
|
+
'edgeURL', # URL attached to non-label part of edge
|
69
|
+
'edgehref', # synonym for edgeURL
|
70
|
+
'edgetarget', # if URL is set, determines browser window for URL
|
71
|
+
'edgetooltip', # default: label; tooltip annotation for non-label part of edge
|
72
|
+
'fontcolor', # default: black type face color
|
73
|
+
'fontname', # default: Times-Roman; font family
|
74
|
+
'fontsize', # default: 14; point size of label
|
75
|
+
'headclip', # default: true; if false, edge is not clipped to head node boundary
|
76
|
+
'headhref', # synonym for headURL
|
77
|
+
'headlabel', # default: label; placed near head of edge
|
78
|
+
'headport', # n,ne,e,se,s,sw,w,nw
|
79
|
+
'headtarget', # if headURL is set, determines browser window for URL
|
80
|
+
'headtooltip', # default: label; tooltip annotation near head of edge
|
81
|
+
'headURL', # URL attached to head label if output format is ismap
|
82
|
+
'href', # alias for URL
|
83
|
+
'id', # any string (user-defined output object tags)
|
84
|
+
'label', # edge label
|
85
|
+
'labelangle', # default: -25.0; angle in degrees which head or tail label is rotated off edge
|
86
|
+
'labeldistance', # default: 1.0; scaling factor for distance of head or tail label from node
|
87
|
+
'labelfloat', # default: false; lessen constraints on edge label placement
|
88
|
+
'labelfontcolor', # default: black; type face color for head and tail labels
|
89
|
+
'labelfontname', # default: Times-Roman; font family for head and tail labels
|
90
|
+
'labelfontsize', # default: 14 point size for head and tail labels
|
91
|
+
'labelhref', # synonym for labelURL
|
92
|
+
'labelURL', # URL for label, overrides edge URL
|
93
|
+
'labeltarget', # if URL or labelURL is set, determines browser window for URL
|
94
|
+
'labeltooltip', # default: label; tooltip annotation near label
|
95
|
+
'layer', # default: overlay range; all, id or id:id
|
96
|
+
'lhead', # name of cluster to use as head of edge
|
97
|
+
'ltail', # name of cluster to use as tail of edge
|
98
|
+
'minlen', # default: 1 minimum rank distance between head and tail
|
99
|
+
'penwidth', # default: 1.0; width of pen for drawing boundaries, in points
|
100
|
+
'samehead', # tag for head node; edge heads with the same tag are merged onto the same port
|
101
|
+
'sametail', # tag for tail node; edge tails with the same tag are merged onto the same port
|
102
|
+
'style', # graphics options, e.g. bold, dotted, filled; cf. Section 2.3
|
103
|
+
'weight', # default: 1; integer cost of stretching an edge
|
104
|
+
'tailclip', # default: true; if false, edge is not clipped to tail node boundary
|
105
|
+
'tailhref', # synonym for tailURL
|
106
|
+
'taillabel', # label placed near tail of edge
|
107
|
+
'tailport', # n,ne,e,se,s,sw,w,nw
|
108
|
+
'tailtarget', # if tailURL is set, determines browser window for URL
|
109
|
+
'tailtooltip', # default: label; tooltip annotation near tail of edge
|
110
|
+
'tailURL', # URL attached to tail label if output format is ismap
|
111
|
+
'target', # if URL is set, determines browser window for URL
|
112
|
+
'tooltip' # default: label; tooltip annotation for edge
|
113
|
+
].freeze
|
114
|
+
|
115
|
+
# maintained for backward compatibility or rdot internal
|
116
|
+
EDGE_OPTS_LGCY = [].freeze
|
86
117
|
|
87
118
|
# options for graph declaration
|
88
|
-
|
89
119
|
GRAPH_OPTS = [
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
120
|
+
'aspect', # controls aspect ratio adjustment
|
121
|
+
'bgcolor', # background color for drawing, plus initial fill color
|
122
|
+
'center', # default: false; center draing on page
|
123
|
+
'clusterrank', # default: local; may be "global" or "none"
|
124
|
+
'color', # default: black; for clusters, outline color, and fill color if
|
125
|
+
# fillcolor not defined
|
126
|
+
'colorscheme', # default: X11; scheme for interpreting color names
|
127
|
+
'comment', # any string (format-dependent)
|
128
|
+
'compound', # default: false; allow edges between clusters
|
129
|
+
'concentrate', # default: false; enables edge concentrators
|
130
|
+
'dpi', # default: 96; dots per inch for image output
|
131
|
+
'fillcolor', # default: black; cluster fill color
|
132
|
+
'fontcolor', # default: black; type face color
|
133
|
+
'fontname', # default: Times-Roman; font family
|
134
|
+
'fontnames', # svg, ps, gd (SVG only)
|
135
|
+
'fontpath', # list of directories to search for fonts
|
136
|
+
'fontsize', # default: 14; point size of label
|
137
|
+
'id', # any string (user-defined output object tags)
|
138
|
+
'label', # any string
|
139
|
+
'labeljust', # default: centered; "l" and "r" for left- and right-justified
|
140
|
+
# cluster labels, respectively
|
141
|
+
'labelloc', # default: top; "t" and "b" for top- and bottom-justified
|
142
|
+
# cluster labels, respectively
|
143
|
+
'landscape', # if true, means orientation=landscape
|
144
|
+
'layers', # id:id:id...
|
145
|
+
'layersep', # default: : ; specifies separator character to split layers'
|
146
|
+
'margin', # default: .5; margin included in page, inches
|
147
|
+
'mclimit', # default: 1.0; scale factor for mincross iterations
|
148
|
+
'nodesep', # default: .25; separation between nodes, in inches.
|
149
|
+
'nojustify', # default: false; if true, justify to label, not graph
|
150
|
+
'nslimit', # if set to "f", bounds network simplex iterations by
|
151
|
+
# (f)(number of nodes) when setting x-coordinates
|
152
|
+
'nslimit1', # if set to "f", bounds network simplex iterations by
|
153
|
+
# (f)(number of nodes) when ranking nodes
|
154
|
+
'ordering', # if "out" out edge order is preserved
|
155
|
+
'orientation', # default: portrait; if "rotate" is not used and the value is
|
156
|
+
# "landscape", use landscape orientation
|
157
|
+
'outputorder', # default: breadthfirst; or nodesfirst, edgesfirst
|
158
|
+
'page', # unit of pagination, e.g. "8.5,11"
|
159
|
+
'pagedir', # default: BL; traversal order of pages
|
160
|
+
'pencolor', # default: black; color for drawing cluster boundaries
|
161
|
+
'penwidth', # default: 1.0; width of pen for drawing boundaries, in points
|
162
|
+
'peripheries', # default: 1; shape-dependent number of node boundaries
|
163
|
+
'rank', # "same", "min", "max", "source", or "sink"
|
164
|
+
'rankdir', # default: TB; "LR" (left to right) or "TB" (top to bottom)
|
165
|
+
'ranksep', # default: .75; separation between ranks, in inches.
|
166
|
+
'ratio', # approximate aspect ratio desired, "fill" or "auto"
|
167
|
+
'remincross', # default: true; whether to run edge crossing minimization
|
168
|
+
# a second time when there are multiple clusters
|
169
|
+
'rotate', # If 90, set orientation to landscape
|
170
|
+
'samplepoints', # default: 8; number of points used to represent ellipses
|
171
|
+
# and circles on output
|
172
|
+
'searchsize', # default: 30; maximum edges with negative cut values to check
|
173
|
+
# when looking for a minimum one during network simplex
|
174
|
+
'size', # maximum drawing size, in inches
|
175
|
+
'splines', # draw edges as splines, polylines, lines
|
176
|
+
'style', # graphics options, e.g. "filled" for clusters
|
177
|
+
'stylesheet', # pathname or URL to XML style sheet for SVG
|
178
|
+
'target', # if URL is set, determines browser window for URL
|
179
|
+
'tooltip', # default: label; tooltip annotation for cluster
|
180
|
+
'truecolor', # if set, force 24 bit or indexed color in image output
|
181
|
+
'viewport', # clipping window on output
|
182
|
+
'URL', # URL associated with graph (format-dependent)
|
183
|
+
].freeze
|
184
|
+
|
185
|
+
# maintained for backward compatibility or rdot internal
|
186
|
+
GRAPH_OPTS_LGCY = [
|
187
|
+
'layerseq'
|
188
|
+
].freeze
|
135
189
|
|
136
190
|
# Ancestor of Edge, Node, and Graph.
|
137
191
|
#
|
@@ -179,16 +233,15 @@ module RGL
|
|
179
233
|
# Return a quoted version of the label otherwise.
|
180
234
|
'"' + label.split(/(\\n|\\r|\\l)/).collect do |part|
|
181
235
|
case part
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
236
|
+
when "\\n", "\\r", "\\l"
|
237
|
+
part
|
238
|
+
else
|
239
|
+
part.gsub('\\', '\\\\\\\\').gsub('"', '\\\\"').gsub("\n", '\\n')
|
186
240
|
end
|
187
241
|
end.join + '"'
|
188
242
|
end
|
189
243
|
end
|
190
244
|
|
191
|
-
|
192
245
|
# Ports are used when a Node instance has its `shape' option set to
|
193
246
|
# _record_ or _Mrecord_. Ports can be nested.
|
194
247
|
#
|
@@ -244,7 +297,7 @@ module RGL
|
|
244
297
|
# option which, if specified, must be an Enumerable containing a list of
|
245
298
|
# ports.
|
246
299
|
#
|
247
|
-
def initialize(params = {}, option_list = NODE_OPTS)
|
300
|
+
def initialize(params = {}, option_list = NODE_OPTS+NODE_OPTS_LGCY)
|
248
301
|
super(params, option_list)
|
249
302
|
@ports = params['ports'] ? params['ports'] : []
|
250
303
|
end
|
@@ -287,11 +340,10 @@ module RGL
|
|
287
340
|
leader + quote_ID(@name) unless @name.nil?
|
288
341
|
else
|
289
342
|
leader + (@name.nil? ? '' : quote_ID(@name) + " ") + "[\n" +
|
290
|
-
|
291
|
-
|
343
|
+
stringified_options + "\n" +
|
344
|
+
leader + "]"
|
292
345
|
end
|
293
346
|
end
|
294
|
-
|
295
347
|
end # class Node
|
296
348
|
|
297
349
|
# A graph representation. Whether or not it is rendered as directed or
|
@@ -306,7 +358,7 @@ module RGL
|
|
306
358
|
# option which, if specified, must be an Enumerable containing a list of
|
307
359
|
# nodes, edges, and/or subgraphs.
|
308
360
|
#
|
309
|
-
def initialize(params = {}, option_list = GRAPH_OPTS)
|
361
|
+
def initialize(params = {}, option_list = GRAPH_OPTS+GRAPH_OPTS_LGCY)
|
310
362
|
super(params, option_list)
|
311
363
|
@elements = params['elements'] ? params['elements'] : []
|
312
364
|
@dot_string = 'graph'
|
@@ -368,9 +420,8 @@ module RGL
|
|
368
420
|
end.join("\n\n")
|
369
421
|
|
370
422
|
hdr + (options.empty? ? '' : options + "\n\n") +
|
371
|
-
|
423
|
+
(elements.empty? ? '' : elements + "\n") + leader + "}"
|
372
424
|
end
|
373
|
-
|
374
425
|
end # class Graph
|
375
426
|
|
376
427
|
# A digraph is a directed graph representation which is the same as a Graph
|
@@ -385,7 +436,7 @@ module RGL
|
|
385
436
|
# option which, if specified, must be an Enumerable containing a list of
|
386
437
|
# nodes, edges, and/or subgraphs.
|
387
438
|
#
|
388
|
-
def initialize(params = {}, option_list = GRAPH_OPTS)
|
439
|
+
def initialize(params = {}, option_list = GRAPH_OPTS+GRAPH_OPTS_LGCY)
|
389
440
|
super(params, option_list)
|
390
441
|
@dot_string = 'digraph'
|
391
442
|
end
|
@@ -404,7 +455,7 @@ module RGL
|
|
404
455
|
# option which, if specified, must be an Enumerable containing a list of
|
405
456
|
# nodes, edges, and/or subgraphs.
|
406
457
|
#
|
407
|
-
def initialize(params = {}, option_list = GRAPH_OPTS)
|
458
|
+
def initialize(params = {}, option_list = GRAPH_OPTS+GRAPH_OPTS_LGCY)
|
408
459
|
super(params, option_list)
|
409
460
|
@dot_string = 'subgraph'
|
410
461
|
end
|
@@ -427,7 +478,7 @@ module RGL
|
|
427
478
|
# edge options. The _option_list_ parameter restricts those options to the
|
428
479
|
# list of valid names it contains.
|
429
480
|
#
|
430
|
-
def initialize(params = {}, option_list = EDGE_OPTS)
|
481
|
+
def initialize(params = {}, option_list = EDGE_OPTS+EDGE_OPTS_LGCY)
|
431
482
|
super(params, option_list)
|
432
483
|
@from = params['from'] ? params['from'] : nil
|
433
484
|
@to = params['to'] ? params['to'] : nil
|
@@ -452,8 +503,8 @@ module RGL
|
|
452
503
|
leader + quote_ID(f_s) + ' ' + edge_link + ' ' + quote_ID(t_s)
|
453
504
|
else
|
454
505
|
leader + quote_ID(f_s) + ' ' + edge_link + ' ' + quote_ID(t_s) + " [\n" +
|
455
|
-
|
456
|
-
|
506
|
+
stringified_options + "\n" +
|
507
|
+
leader + "]"
|
457
508
|
end
|
458
509
|
end
|
459
510
|
|
data/test/dot_test.rb
CHANGED
@@ -13,7 +13,7 @@ class TestDot < Test::Unit::TestCase
|
|
13
13
|
graph = RGL::DirectedAdjacencyGraph["a", "b"]
|
14
14
|
|
15
15
|
begin
|
16
|
-
dot
|
16
|
+
dot = graph.to_dot_graph.to_s
|
17
17
|
|
18
18
|
first_vertex_id = "a"
|
19
19
|
second_vertex_id = "b"
|
@@ -29,31 +29,29 @@ class TestDot < Test::Unit::TestCase
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
def
|
33
|
-
|
32
|
+
def test_dot_digraph_with_complicated_options
|
33
|
+
graph = RGL::DirectedAdjacencyGraph['a','b', 'c','d', 'a','c']
|
34
34
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
key = "#{b}-#{e}"
|
39
|
-
edge_labels[key] = "#{b} to #{e}"
|
40
|
-
end
|
41
|
-
|
42
|
-
vertex_fontcolors = {'a' => 'green', 'b' => 'blue'}
|
43
|
-
vertex_fontcolor_setting = Proc.new{|v| vertex_fontcolors[v]}
|
44
|
-
vertex_settings = {'fontcolor' => vertex_fontcolor_setting, 'fontsize' => 12}
|
45
|
-
|
46
|
-
edge_label_setting = Proc.new{|b, e| edge_labels["#{b}-#{e}"]}
|
47
|
-
edge_settings = {'color' => 'red', 'label' => edge_label_setting}
|
48
|
-
dot_options = {'edge' => edge_settings,'vertex' => vertex_settings}
|
49
|
-
dot = graph.to_dot_graph(dot_options).to_s
|
35
|
+
graph.set_vertex_options('a', label: 'This is A', shape: 'box3d', fontcolor: 'green', fontsize: 16)
|
36
|
+
graph.set_vertex_options('b', label: 'This is B', shape: 'tab', fontcolor: 'red', fontsize: 14)
|
37
|
+
graph.set_vertex_options('c', shape: 'tab', fontcolor: 'blue')
|
50
38
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
39
|
+
graph.set_edge_options('a', 'b', label: 'NotCapitalEdge', style: 'dotted', dir: 'back', color: 'magenta')
|
40
|
+
graph.set_edge_options('a', 'c', weight: 5, color: 'blue')
|
41
|
+
|
42
|
+
graph_options = {
|
43
|
+
"rankdir" => "LR",
|
44
|
+
"labelloc" => "t",
|
45
|
+
"label" => "Graph\n (generated #{Time.now.utc})"
|
46
|
+
}
|
47
|
+
|
48
|
+
dot = graph.to_dot_graph(graph_options).to_s
|
49
|
+
|
50
|
+
assert_match(dot, /labelloc = t\n\s*/)
|
51
|
+
assert_match(dot, /rankdir = LR\n\s*/)
|
52
|
+
assert_match(dot, /a \[\n\s*fontcolor = green,\n\s*fontsize = 16,\n\s*shape = box3d,\n\s*label = "This is A"\n\s*/)
|
53
|
+
assert_match(dot, /b \[\n\s*fontcolor = red,\n\s*fontsize = 14,\n\s*shape = tab,\n\s*label = "This is B"\n\s*/)
|
54
|
+
assert_match(dot, /a -> b \[\n\s*color = magenta,\n\s*dir = back,\n\s*fontsize = 8,\n\s*label = NotCapitalEdge,\n\s*style = dotted\n\s*/)
|
57
55
|
end
|
58
56
|
|
59
57
|
def test_to_dot_graph
|
@@ -65,10 +63,6 @@ class TestDot < Test::Unit::TestCase
|
|
65
63
|
def graph.vertex_id(v)
|
66
64
|
"id-"+v.to_s
|
67
65
|
end
|
68
|
-
|
69
|
-
graph.write_to_graphic_file
|
70
|
-
rescue
|
71
|
-
puts "Graphviz not installed?"
|
72
|
-
end
|
66
|
+
graph.write_to_graphic_file
|
73
67
|
end
|
74
68
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rgl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Horst Duchene
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire: rgl/base
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2023-
|
12
|
+
date: 2023-05-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: stream
|