rgl 0.6.2 → 0.6.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/{ChangeLog → CHANGELOG.md} +200 -181
- data/README.md +53 -4
- data/Rakefile +11 -35
- data/lib/rgl/base.rb +0 -3
- data/lib/rgl/dot.rb +46 -14
- data/lib/rgl/rdot.rb +185 -134
- data/lib/rgl/traversal.rb +3 -1
- data/lib/rgl/version.rb +3 -0
- data/test/dot_test.rb +23 -29
- data/test/traversal_bfs_require.rb +29 -0
- metadata +25 -24
- data/examples/graph.dot +0 -971
data/README.md
CHANGED
@@ -227,6 +227,41 @@ This graph shows all loaded RGL modules:
|
|
227
227
|
Look for more in
|
228
228
|
[examples](https://github.com/monora/rgl/tree/master/examples) directory.
|
229
229
|
|
230
|
+
## (Optional) Configuring Graphviz DOT output options
|
231
|
+
|
232
|
+
The default graph will use standard DOT output visuals.
|
233
|
+
|
234
|
+
If you wish to configure the styling of the diagram, module {RGL::DOT} adds the methods {RGL::Graph#set_edge_options} and {RGL::Graph#set_vertex_options} for this purpose. You can use any options from the {RGL::DOT::NODE_OPTS} and {RGL::DOT::EDGE_OPTS} constants in {RGL::DOT}. Use the exact option name as an argument in your method call.
|
235
|
+
|
236
|
+
You can also configure the overall appearance of the graph by passing a hash of options from {RGL::DOT::GRAPH_OPTS} to the output method. The example below shows styling of vertices, edges and setting some basic graph options.
|
237
|
+
|
238
|
+
The available options are described in the [GraphViz DOT Spec](https://www.graphviz.org/pdf/dotguide.pdf)
|
239
|
+
|
240
|
+
![colored diagram](images/styled_graph.png "Colored DOT graph")
|
241
|
+
|
242
|
+
```ruby
|
243
|
+
require 'rgl/adjacency'
|
244
|
+
require 'rgl/dot'
|
245
|
+
|
246
|
+
graph = RGL::DirectedAdjacencyGraph['a','b', 'c','d', 'a','c']
|
247
|
+
|
248
|
+
graph.set_vertex_options('a', label: 'This is A', shape: 'box3d', fontcolor: 'green', fontsize: 16)
|
249
|
+
graph.set_vertex_options('b', label: 'This is B', shape: 'tab', fontcolor: 'red', fontsize: 14)
|
250
|
+
graph.set_vertex_options('c', shape: 'tab', fontcolor: 'blue')
|
251
|
+
|
252
|
+
graph.set_edge_options('a', 'b', label: 'NotCapitalEdge', style: 'dotted', dir: 'back', color: 'magenta')
|
253
|
+
graph.set_edge_options('a', 'c', weight: 5, color: 'blue')
|
254
|
+
|
255
|
+
graph_options = {
|
256
|
+
"rankdir" => "LR",
|
257
|
+
"labelloc" => "t",
|
258
|
+
"label" => "Graph\n (generated #{Time.now.utc})"
|
259
|
+
}
|
260
|
+
|
261
|
+
graph.write_to_graphic_file('png', 'graph', graph_options)
|
262
|
+
|
263
|
+
```
|
264
|
+
|
230
265
|
## Credits
|
231
266
|
|
232
267
|
Many thanks to Robert Feldt which also worked on a graph library
|
@@ -249,14 +284,28 @@ the module {RGL::DOT} which is used instead of Roberts module to visualize
|
|
249
284
|
graphs.
|
250
285
|
|
251
286
|
Jeremy Bopp, John Carter, Sascha Doerdelmann, Shawn Garbett, Andreas
|
252
|
-
Schörk, Dan Čermák
|
287
|
+
Schörk, Dan Čermák, Kirill Lashuk and Markus Napp for contributing additions, test
|
253
288
|
cases and bugfixes.
|
254
289
|
|
255
|
-
See also
|
290
|
+
See also the [list of contributers][5]
|
291
|
+
|
292
|
+
## Links
|
293
|
+
|
294
|
+
- See [CHANGELOG.md][1] for major/breaking updates, and [releases][2] for a
|
295
|
+
detailed version history.
|
296
|
+
- To **contribute**, please read [CONTRIBUTING.md][4] first.
|
297
|
+
- Please [open an issue][3] if anything is missing or unclear in this
|
298
|
+
documentation.
|
256
299
|
|
257
300
|
## Copying
|
258
301
|
|
259
|
-
RGL is Copyright (c) 2002,2004,2005,2008,2013,2015,2019,2020,2022 by Horst
|
302
|
+
RGL is Copyright (c) 2002,2004,2005,2008,2013,2015,2019,2020,2022,2023 by Horst
|
260
303
|
Duchene. It is free software, and may be redistributed under the [Ruby
|
261
|
-
license](
|
304
|
+
license](.LICENSE) and terms specified in
|
262
305
|
the LICENSE file.
|
306
|
+
|
307
|
+
[1] ./CHANGELOG.md
|
308
|
+
[2] https://github.com/monora/rgl/releases
|
309
|
+
[3] https://github.com/monora/rgl/issues/new
|
310
|
+
[4] ./.github/CONTRIBUTING.md
|
311
|
+
[5] https://github.com/monora/rgl/contributors
|
data/Rakefile
CHANGED
@@ -1,16 +1,12 @@
|
|
1
1
|
# -*- ruby -*-
|
2
2
|
|
3
|
-
require 'rubygems'
|
4
3
|
require 'bundler/setup'
|
5
|
-
|
6
|
-
require 'rubygems/package_task'
|
7
|
-
|
8
4
|
require 'rake/testtask'
|
9
5
|
require 'rake/clean'
|
10
6
|
require 'yard'
|
11
7
|
|
12
8
|
$:.unshift File.join(File.dirname(__FILE__), 'lib')
|
13
|
-
require 'rgl/
|
9
|
+
require 'rgl/version' # defines RGL::VERSION
|
14
10
|
|
15
11
|
SOURCES = FileList['lib/**/*.rb']
|
16
12
|
|
@@ -26,13 +22,20 @@ Rake::TestTask.new do |t|
|
|
26
22
|
t.verbose = true
|
27
23
|
end
|
28
24
|
|
25
|
+
# Test bfs_search_tree_from in isolation, to ensure that adjacency is not loaded by other tests.
|
26
|
+
Rake::TestTask.new do |t|
|
27
|
+
t.libs << 'test'
|
28
|
+
t.pattern = 'test/traversal_bfs_require.rb'
|
29
|
+
t.verbose = true
|
30
|
+
end
|
31
|
+
|
29
32
|
# Git tagging
|
30
33
|
|
31
34
|
desc 'Commit all changes as a new version commit. Tag the commit with v<version> tag'
|
32
35
|
task :tag do
|
33
|
-
puts "Committing and tagging version #{
|
34
|
-
`git commit -am 'Version #{
|
35
|
-
`git tag 'v#{
|
36
|
+
puts "Committing and tagging version #{RGL::VERSION}"
|
37
|
+
`git commit -am 'Version #{RGL::VERSION}'`
|
38
|
+
`git tag 'v#{RGL::VERSION}'`
|
36
39
|
end
|
37
40
|
|
38
41
|
YARD::Rake::YardocTask.new
|
@@ -86,30 +89,3 @@ task :lines do
|
|
86
89
|
end
|
87
90
|
show_line('TOTAL', total_lines, total_code)
|
88
91
|
end
|
89
|
-
|
90
|
-
# simple rake task to output a changelog between two commits, tags ...
|
91
|
-
# output is formatted simply, commits are grouped under each author name
|
92
|
-
#
|
93
|
-
desc 'generate changelog with nice clean output'
|
94
|
-
task :changelog, :since_c, :until_c do |t, args|
|
95
|
-
since_c = args[:since_c] || `git tag | tail -1`.chomp
|
96
|
-
until_c = args[:until_c]
|
97
|
-
cmd = `git log --pretty='format:%ci::%an <%ae>::%s::%H' #{since_c}..#{until_c}`
|
98
|
-
|
99
|
-
entries = Hash.new
|
100
|
-
changelog_content = String.new
|
101
|
-
|
102
|
-
cmd.split("\n").each do |entry|
|
103
|
-
_, author, subject, hash = entry.chomp.split('::')
|
104
|
-
entries[author] = Array.new unless entries[author]
|
105
|
-
entries[author] << "#{subject} (#{hash[0..5]})" unless subject =~ /Merge/
|
106
|
-
end
|
107
|
-
|
108
|
-
# generate clean output
|
109
|
-
entries.keys.each do |author|
|
110
|
-
changelog_content += author + "\n"
|
111
|
-
entries[author].reverse.each { |entry| changelog_content += " * #{entry}\n" }
|
112
|
-
end
|
113
|
-
|
114
|
-
puts changelog_content
|
115
|
-
end
|
data/lib/rgl/base.rb
CHANGED
@@ -1,8 +1,5 @@
|
|
1
1
|
# base.rb
|
2
2
|
|
3
|
-
# version information
|
4
|
-
RGL_VERSION = "0.6.2"
|
5
|
-
|
6
3
|
# Module {RGL} defines the namespace for all modules and classes of the graph
|
7
4
|
# library. The main module is {Graph} which defines the abstract behavior of
|
8
5
|
# all graphs in the library. Other important modules or classes are:
|
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
|
|