rgl 0.6.2 → 0.6.4

Sign up to get free protection for your applications and to get access to all the features.
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