rgl 0.6.2 → 0.6.4

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.
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 and Kirill Lashuk for contributing additions, test
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: https://github.com/monora/rgl/contributors
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](https://en.wikipedia.org/wiki/Ruby_License) and terms specified in
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/base' # require base module to get RGL_VERSION
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 #{RGL_VERSION}"
34
- `git commit -am 'Version #{RGL_VERSION}'`
35
- `git tag 'v#{RGL_VERSION}'`
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.merge(vertex_options)
44
- vertex_options.each{|option, val| each_vertex_options[option] = val.call(v) if val.is_a?(Proc)}
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
- each_edge do |u, v|
72
+ edges.each do |edge|
49
73
  default_edge_options = {
50
- 'from' => vertex_id(u),
51
- 'to' => vertex_id(v),
74
+ 'from' => edge.source,
75
+ 'to' => edge.target,
52
76
  'fontsize' => fontsize
53
77
  }
54
- each_edge_options = default_edge_options.merge(edge_options)
55
- edge_options.each{|option, val| each_edge_options[option] = val.call(u, v) if val.is_a?(Proc)}
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
- end
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