ruby-graphviz_c 1.1.0
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 +7 -0
- data/.gemrc +0 -0
- data/.gitignore +9 -0
- data/.travis.yml +7 -0
- data/AUTHORS.rdoc +33 -0
- data/CHANGELOG.rdoc +287 -0
- data/COPYING.rdoc +133 -0
- data/Gemfile +4 -0
- data/README.rdoc +206 -0
- data/Rakefile +71 -0
- data/bin/dot2ruby +91 -0
- data/bin/gem2gv +165 -0
- data/bin/git2gv +167 -0
- data/bin/ruby2gv +234 -0
- data/bin/xml2gv +96 -0
- data/examples/dot/JSP.dot +52 -0
- data/examples/dot/balanced.dot +36 -0
- data/examples/dot/cluster.dot +30 -0
- data/examples/dot/dotgraph.dot +28 -0
- data/examples/dot/fsm.dot +20 -0
- data/examples/dot/genetic.dot +118 -0
- data/examples/dot/hello.dot +1 -0
- data/examples/dot/hello_test.rb +33 -0
- data/examples/dot/lion_share.dot +103 -0
- data/examples/dot/prof.dot +150 -0
- data/examples/dot/psg.dot +28 -0
- data/examples/dot/rank.dot +6 -0
- data/examples/dot/sdh.dot +284 -0
- data/examples/dot/siblings.dot +492 -0
- data/examples/dot/so-sample001.gv +30 -0
- data/examples/dot/so-sample002.gv +33 -0
- data/examples/dot/so-sample003.gv +45 -0
- data/examples/dot/test.dot +17 -0
- data/examples/dot/test_parse.rb +13 -0
- data/examples/dot/this_crach_with_dot_2.20.dot +24 -0
- data/examples/dot/unix.dot +104 -0
- data/examples/graphml/attributes.ext.graphml +12 -0
- data/examples/graphml/attributes.graphml +40 -0
- data/examples/graphml/cluster.graphml +75 -0
- data/examples/graphml/failed_graph.graphml +461 -0
- data/examples/graphml/hyper.graphml +29 -0
- data/examples/graphml/nested.graphml +54 -0
- data/examples/graphml/port.graphml +32 -0
- data/examples/graphml/simple.graphml +30 -0
- data/examples/hello.png +0 -0
- data/examples/rgv/rgv.ps +125 -0
- data/examples/rgv/test_rgv.rb +12 -0
- data/examples/sample01.rb +32 -0
- data/examples/sample02.rb +42 -0
- data/examples/sample03.rb +31 -0
- data/examples/sample04.rb +22 -0
- data/examples/sample05.rb +32 -0
- data/examples/sample06.rb +46 -0
- data/examples/sample07.rb +23 -0
- data/examples/sample08.rb +34 -0
- data/examples/sample09.rb +50 -0
- data/examples/sample10.rb +50 -0
- data/examples/sample11.rb +42 -0
- data/examples/sample12.rb +55 -0
- data/examples/sample13.rb +48 -0
- data/examples/sample14.rb +44 -0
- data/examples/sample15.rb +25 -0
- data/examples/sample16.rb +8 -0
- data/examples/sample17.rb +92 -0
- data/examples/sample18.rb +24 -0
- data/examples/sample19.rb +59 -0
- data/examples/sample20.rb +47 -0
- data/examples/sample21.rb +12 -0
- data/examples/sample22.rb +10 -0
- data/examples/sample23.rb +11 -0
- data/examples/sample24.rb +11 -0
- data/examples/sample25.rb +11 -0
- data/examples/sample26.rb +8 -0
- data/examples/sample27.rb +8 -0
- data/examples/sample28.rb +12 -0
- data/examples/sample29.rb +8 -0
- data/examples/sample30.rb +12 -0
- data/examples/sample31.rb +10 -0
- data/examples/sample32.rb +14 -0
- data/examples/sample33.rb +43 -0
- data/examples/sample34.rb +29 -0
- data/examples/sample35.rb +43 -0
- data/examples/sample36.rb +35 -0
- data/examples/sample37.rb +87 -0
- data/examples/sample38.rb +12 -0
- data/examples/sample39.rb +11 -0
- data/examples/sample40.rb +17 -0
- data/examples/sample41.rb +8 -0
- data/examples/sample42.rb +35 -0
- data/examples/sample43.rb +26 -0
- data/examples/sample44.rb +97 -0
- data/examples/sample45.rb +24 -0
- data/examples/sample46.rb +43 -0
- data/examples/sample47.rb +7 -0
- data/examples/sample48.rb +62 -0
- data/examples/sample49.rb +10 -0
- data/examples/sample50.rb +215 -0
- data/examples/sample51.rb +37 -0
- data/examples/sample52.rb +62 -0
- data/examples/sample53.rb +26 -0
- data/examples/sample54.rb +26 -0
- data/examples/sample55.rb +9 -0
- data/examples/sample56.rb +10 -0
- data/examples/sample57.rb +8 -0
- data/examples/sample58.rb +33 -0
- data/examples/sample59.rb +14 -0
- data/examples/sample60.rb +12 -0
- data/examples/sample61.rb +12 -0
- data/examples/sample62.rb +24 -0
- data/examples/sample63.rb +32 -0
- data/examples/sample64.rb +31 -0
- data/examples/sample65.rb +9 -0
- data/examples/sample66.rb +4 -0
- data/examples/sample67.rb +10 -0
- data/examples/sample68.rb +27 -0
- data/examples/sample69.rb +23 -0
- data/examples/sample70.rb +9 -0
- data/examples/sample99.rb +70 -0
- data/examples/sdlshapes/README +2 -0
- data/examples/sdlshapes/sdl.ps +655 -0
- data/examples/sdlshapes/sdlshapes.dot +78 -0
- data/examples/test.xml +26 -0
- data/examples/theory/pert.rb +47 -0
- data/examples/theory/tests.rb +87 -0
- data/lib/ext/gvpr/dot2ruby.g +185 -0
- data/lib/graphviz/attrs.rb +73 -0
- data/lib/graphviz/constants.rb +294 -0
- data/lib/graphviz/core_ext.rb +64 -0
- data/lib/graphviz/dot2ruby.rb +59 -0
- data/lib/graphviz/dot_script.rb +109 -0
- data/lib/graphviz/dsl.rb +67 -0
- data/lib/graphviz/edge.rb +197 -0
- data/lib/graphviz/elements.rb +39 -0
- data/lib/graphviz/ext.rb +17 -0
- data/lib/graphviz/family_tree/couple.rb +63 -0
- data/lib/graphviz/family_tree/generation.rb +39 -0
- data/lib/graphviz/family_tree/person.rb +120 -0
- data/lib/graphviz/family_tree/sibling.rb +13 -0
- data/lib/graphviz/family_tree.rb +118 -0
- data/lib/graphviz/graphml.rb +268 -0
- data/lib/graphviz/math/matrix.rb +221 -0
- data/lib/graphviz/node.rb +160 -0
- data/lib/graphviz/nothugly/nothugly.xsl +321 -0
- data/lib/graphviz/nothugly.rb +63 -0
- data/lib/graphviz/theory.rb +321 -0
- data/lib/graphviz/types/arrow_type.rb +32 -0
- data/lib/graphviz/types/color.rb +58 -0
- data/lib/graphviz/types/color_list.rb +24 -0
- data/lib/graphviz/types/esc_string.rb +20 -0
- data/lib/graphviz/types/gv_bool.rb +49 -0
- data/lib/graphviz/types/gv_double.rb +32 -0
- data/lib/graphviz/types/html_string.rb +18 -0
- data/lib/graphviz/types/lbl_string.rb +22 -0
- data/lib/graphviz/types/rect.rb +35 -0
- data/lib/graphviz/types/spline_type.rb +77 -0
- data/lib/graphviz/types.rb +22 -0
- data/lib/graphviz/utils/colors.rb +1018 -0
- data/lib/graphviz/utils.rb +70 -0
- data/lib/graphviz/xml.rb +119 -0
- data/lib/graphviz.rb +967 -0
- data/lib/ruby-graphviz.rb +1 -0
- data/man/dot2ruby.1 +66 -0
- data/man/dot2ruby.1.ronn +55 -0
- data/man/gem2gv.1 +60 -0
- data/man/gem2gv.1.ronn +47 -0
- data/man/git2gv.1 +48 -0
- data/man/git2gv.1.ronn +40 -0
- data/man/ruby2gv.1 +60 -0
- data/man/ruby2gv.1.ronn +47 -0
- data/man/xml2gv.1 +48 -0
- data/man/xml2gv.1.ronn +39 -0
- data/ruby-graphviz.gemspec +47 -0
- data/setup.rb +1585 -0
- data/test/helper.rb +13 -0
- data/test/support.rb +95 -0
- data/test/test_dot_script.rb +47 -0
- data/test/test_examples.rb +151 -0
- data/test/test_graph.rb +115 -0
- data/test/test_search.rb +29 -0
- data/test/test_subgraph.rb +27 -0
- data/test/test_theory.rb +98 -0
- data/test/test_types.rb +65 -0
- data/test/test_utils_colors.rb +52 -0
- metadata +301 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# This file use notugly.xsl: An XSL transform to pretty up the SVG output from Graphviz
|
|
2
|
+
#
|
|
3
|
+
# See: http://www.hokstad.com/making-graphviz-output-pretty-with-xsl.html
|
|
4
|
+
# And: http://www.hokstad.com/making-graphviz-output-pretty-with-xsl-updated.html
|
|
5
|
+
#
|
|
6
|
+
# By Vidar Hokstad and Ryan Shea; Contributions by Jonas Tingborn,
|
|
7
|
+
# Earl Cummings, Michael Kennedy (Graphviz 2.20.2 compatibility, bug fixes,
|
|
8
|
+
# testing, lots of gradients)
|
|
9
|
+
|
|
10
|
+
require 'rubygems'
|
|
11
|
+
begin
|
|
12
|
+
require 'xml/xslt'
|
|
13
|
+
XSLT_METHOD = :xml_xslt_transform
|
|
14
|
+
rescue LoadError => e
|
|
15
|
+
require 'libxml'
|
|
16
|
+
require 'libxslt'
|
|
17
|
+
XSLT_METHOD = :libxslt_transform
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
class GraphViz
|
|
21
|
+
# Transform to pretty up the SVG output
|
|
22
|
+
#
|
|
23
|
+
# For more information, see http://www.hokstad.com/making-graphviz-output-pretty-with-xsl.html
|
|
24
|
+
# and http://www.hokstad.com/making-graphviz-output-pretty-with-xsl-updated.html
|
|
25
|
+
#
|
|
26
|
+
# You can use the :nothugly option to GraphViz#output :
|
|
27
|
+
#
|
|
28
|
+
# graph.output( :svg => "myGraph.svg", :nothugly => true )
|
|
29
|
+
#
|
|
30
|
+
# Or directly on an SVG output graph :
|
|
31
|
+
#
|
|
32
|
+
# GraphViz.nothugly( "myGraph.svg" )
|
|
33
|
+
def self.nothugly( file, save = true )
|
|
34
|
+
xsl = File.join( File.dirname(File.expand_path(__FILE__)), "nothugly", "nothugly.xsl" )
|
|
35
|
+
out = self.send(XSLT_METHOD, file, xsl)
|
|
36
|
+
|
|
37
|
+
if save
|
|
38
|
+
fname = File.join( File.dirname(File.expand_path(file)), File.basename(file))
|
|
39
|
+
File.open( fname, "w" ) { |io|
|
|
40
|
+
io.print out
|
|
41
|
+
}
|
|
42
|
+
else
|
|
43
|
+
return out
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def self.xml_xslt_transform(xml, xsl)
|
|
48
|
+
xslt = XML::XSLT.new()
|
|
49
|
+
xslt.xml = xml
|
|
50
|
+
xslt.xsl = xsl
|
|
51
|
+
xslt.serve()
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def self.libxslt_transform(xml, xsl)
|
|
55
|
+
LibXML::XML.default_load_external_dtd = false
|
|
56
|
+
LibXML::XML.default_substitute_entities = false
|
|
57
|
+
|
|
58
|
+
stylesheet_doc = LibXML::XML::Document.file(xsl)
|
|
59
|
+
stylesheet = LibXSLT::XSLT::Stylesheet.new(stylesheet_doc)
|
|
60
|
+
xml_doc = LibXML::XML::Document.file(xml)
|
|
61
|
+
stylesheet.apply(xml_doc).to_s
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
require 'graphviz/math/matrix'
|
|
2
|
+
|
|
3
|
+
class GraphViz
|
|
4
|
+
class Theory
|
|
5
|
+
def initialize( graph )
|
|
6
|
+
@graph = graph
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# Return the adjancy matrix of the graph
|
|
10
|
+
def adjancy_matrix
|
|
11
|
+
matrix = GraphViz::Math::Matrix.new( @graph.node_count, @graph.node_count )
|
|
12
|
+
|
|
13
|
+
@graph.each_edge { |e|
|
|
14
|
+
x = @graph.get_node(e.node_one( false )).index
|
|
15
|
+
y = @graph.get_node(e.node_two( false )).index
|
|
16
|
+
matrix[x+1, y+1] = 1
|
|
17
|
+
matrix[y+1, x+1] = 1 if @graph.type == "graph"
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return matrix
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Return the incidence matrix of the graph
|
|
24
|
+
def incidence_matrix
|
|
25
|
+
tail = (@graph.type == "digraph") ? -1 : 1
|
|
26
|
+
matrix = GraphViz::Math::Matrix.new( @graph.node_count, @graph.edge_count )
|
|
27
|
+
|
|
28
|
+
@graph.each_edge { |e|
|
|
29
|
+
x = e.index
|
|
30
|
+
|
|
31
|
+
nstart = @graph.get_node(e.node_one( false )).index
|
|
32
|
+
nend = @graph.get_node(e.node_two( false )).index
|
|
33
|
+
|
|
34
|
+
matrix[nstart+1, x+1] = 1
|
|
35
|
+
matrix[nend+1, x+1] = tail
|
|
36
|
+
matrix[nend+1, x+1] = 2 if nstart == nend
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return matrix
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Return the degree of the given node
|
|
43
|
+
def degree( node )
|
|
44
|
+
degree = 0
|
|
45
|
+
name = node
|
|
46
|
+
if node.kind_of?(GraphViz::Node)
|
|
47
|
+
name = node.id
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
@graph.each_edge do |e|
|
|
51
|
+
degree += 1 if e.node_one(false) == name or e.node_two(false) == name
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
return degree
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Return the laplacian matrix of the graph
|
|
58
|
+
def laplacian_matrix
|
|
59
|
+
return degree_matrix - adjancy_matrix
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Return <tt>true</tt> if the graph if symmetric, <tt>false</tt> otherwise
|
|
63
|
+
def symmetric?
|
|
64
|
+
adjancy_matrix == adjancy_matrix.transpose
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# moore_dijkstra(source, destination)
|
|
68
|
+
def moore_dijkstra( dep, arv )
|
|
69
|
+
dep = @graph.get_node(dep) unless dep.kind_of?(GraphViz::Node)
|
|
70
|
+
arv = @graph.get_node(arv) unless arv.kind_of?(GraphViz::Node)
|
|
71
|
+
|
|
72
|
+
m = distance_matrix
|
|
73
|
+
n = @graph.node_count
|
|
74
|
+
# Table des sommets à choisir
|
|
75
|
+
c = [dep.index]
|
|
76
|
+
# Table des distances
|
|
77
|
+
d = []
|
|
78
|
+
d[dep.index] = 0
|
|
79
|
+
|
|
80
|
+
# Table des predecesseurs
|
|
81
|
+
pred = []
|
|
82
|
+
|
|
83
|
+
@graph.each_node do |name, k|
|
|
84
|
+
if k != dep
|
|
85
|
+
d[k.index] = m[dep.index+1,k.index+1]
|
|
86
|
+
pred[k.index] = dep
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
while c.size < n
|
|
91
|
+
# trouver y tel que d[y] = min{d[k]; k sommet tel que k n'appartient pas à c}
|
|
92
|
+
mini = 1.0/0.0
|
|
93
|
+
y = nil
|
|
94
|
+
@graph.each_node do |name, k|
|
|
95
|
+
next if c.include?(k.index)
|
|
96
|
+
if d[k.index] < mini
|
|
97
|
+
mini = d[k.index]
|
|
98
|
+
y = k
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# si ce minimum est ∞ alors sortir de la boucle fin si
|
|
103
|
+
break unless mini.to_f.infinite?.nil?
|
|
104
|
+
|
|
105
|
+
c << y.index
|
|
106
|
+
@graph.each_node do |name, k|
|
|
107
|
+
next if c.include?(k.index)
|
|
108
|
+
if d[k.index] > d[y.index] + m[y.index+1,k.index+1]
|
|
109
|
+
d[k.index] = d[y.index] + m[y.index+1,k.index+1]
|
|
110
|
+
pred[k.index] = y
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Construction du chemin le plus court
|
|
116
|
+
ch = []
|
|
117
|
+
k = arv
|
|
118
|
+
while k.index != dep.index
|
|
119
|
+
ch.unshift(k)
|
|
120
|
+
k = pred[k.index]
|
|
121
|
+
end
|
|
122
|
+
ch.unshift(dep)
|
|
123
|
+
|
|
124
|
+
if d[arv.index].to_f.infinite?
|
|
125
|
+
return nil
|
|
126
|
+
else
|
|
127
|
+
return( {
|
|
128
|
+
:path => ch,
|
|
129
|
+
:distance => d[arv.index]
|
|
130
|
+
} )
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# Return a liste of range
|
|
135
|
+
#
|
|
136
|
+
# If the returned array include nil values, there is one or more circuits in the graph
|
|
137
|
+
def range
|
|
138
|
+
matrix = adjancy_matrix
|
|
139
|
+
unseen = (1..matrix.columns).to_a
|
|
140
|
+
result = Array.new(matrix.columns)
|
|
141
|
+
r = 0
|
|
142
|
+
|
|
143
|
+
range_recursion( matrix, unseen, result, r )
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# Return the critical path for a PERT network
|
|
147
|
+
#
|
|
148
|
+
# If the given graph is not a PERT network, return nul
|
|
149
|
+
def critical_path
|
|
150
|
+
return nil if range.include?(nil) or @graph.type != "digraph"
|
|
151
|
+
r = [ [0, [1]] ]
|
|
152
|
+
|
|
153
|
+
critical_path_recursion( distance_matrix, adjancy_matrix, r, [], 0 ).inject( {:distance => 0, :path => []} ) { |_r, item|
|
|
154
|
+
(_r[:distance] < item[0]) ? { :distance => item[0], :path => item[1] } : _r
|
|
155
|
+
}
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# Return the PageRank in an directed graph.
|
|
159
|
+
#
|
|
160
|
+
# * damping_factor: PageRank dumping factor.
|
|
161
|
+
# * max_iterations: Maximum number of iterations.
|
|
162
|
+
# * min_delta: Smallest variation required to have a new iteration.
|
|
163
|
+
def pagerank(damping_factor = 0.85, max_iterations = 100, min_delta = 0.00001)
|
|
164
|
+
return nil unless @graph.directed?
|
|
165
|
+
|
|
166
|
+
min_value = (1.0-damping_factor)/@graph.node_count
|
|
167
|
+
|
|
168
|
+
pagerank = {}
|
|
169
|
+
@graph.each_node { |_, node|
|
|
170
|
+
pagerank[node] = 1.0/@graph.node_count
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
max_iterations.times { |_|
|
|
174
|
+
diff = 0
|
|
175
|
+
@graph.each_node { |_, node|
|
|
176
|
+
rank = min_value
|
|
177
|
+
incidents(node).each { |referent|
|
|
178
|
+
rank += damping_factor * pagerank[referent] / neighbors(referent).size
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
diff += (pagerank[node] - rank).abs
|
|
182
|
+
pagerank[node] = rank
|
|
183
|
+
}
|
|
184
|
+
break if diff < min_delta
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return pagerank
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# Return the list of nodes that are directly accessible from given node
|
|
191
|
+
def neighbors(node)
|
|
192
|
+
if node.class == String
|
|
193
|
+
@graph.get_node(node).neighbors
|
|
194
|
+
else
|
|
195
|
+
node.neighbors
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# Return the list of nodes that are incident to the given node (in a directed graph neighbors == incidents)
|
|
200
|
+
def incidents(node)
|
|
201
|
+
if node.class == String
|
|
202
|
+
@graph.get_node(node).incidents
|
|
203
|
+
else
|
|
204
|
+
node.incidents
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
# Breadth First Search
|
|
209
|
+
def bfs(node, &b)
|
|
210
|
+
queue = []
|
|
211
|
+
visited_nodes = []
|
|
212
|
+
node = @graph.get_node(node) if node.kind_of? String
|
|
213
|
+
queue << node
|
|
214
|
+
visited_nodes << node
|
|
215
|
+
|
|
216
|
+
while not queue.empty?
|
|
217
|
+
node = queue.shift
|
|
218
|
+
b.call(node)
|
|
219
|
+
neighbors(node).each do |n|
|
|
220
|
+
unless visited_nodes.include?(n)
|
|
221
|
+
visited_nodes << n
|
|
222
|
+
queue << n
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
# Depth First Search
|
|
229
|
+
def dfs(node, &b)
|
|
230
|
+
visited_nodes = []
|
|
231
|
+
recursive_dfs(node, visited_nodes, &b)
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
private
|
|
235
|
+
def recursive_dfs(node, visited_nodes, &b)
|
|
236
|
+
node = @graph.get_node(node) if node.kind_of? String
|
|
237
|
+
b.call(node)
|
|
238
|
+
visited_nodes << node
|
|
239
|
+
neighbors(node).each do |n|
|
|
240
|
+
recursive_dfs(n, visited_nodes, &b) unless visited_nodes.include?(n)
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def distance_matrix
|
|
245
|
+
type = @graph.type
|
|
246
|
+
matrix = GraphViz::Math::Matrix.new( @graph.node_count, @graph.node_count, (1.0/0.0) )
|
|
247
|
+
|
|
248
|
+
@graph.each_edge { |e|
|
|
249
|
+
x = @graph.get_node(e.node_one( false )).index
|
|
250
|
+
y = @graph.get_node(e.node_two( false )).index
|
|
251
|
+
unless x == y
|
|
252
|
+
weight = ((e[:weight].nil?) ? 1 : e[:weight].to_f)
|
|
253
|
+
matrix[x+1, y+1] = weight
|
|
254
|
+
matrix[y+1, x+1] = weight if type == "graph"
|
|
255
|
+
end
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
return matrix
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
def degree_matrix
|
|
262
|
+
matrix = GraphViz::Math::Matrix.new( @graph.node_count, @graph.node_count )
|
|
263
|
+
@graph.each_node do |name, node|
|
|
264
|
+
i = node.index
|
|
265
|
+
matrix[i+1, i+1] = degree(node)
|
|
266
|
+
end
|
|
267
|
+
return matrix
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
def range_recursion(matrix, unseen, result, r)
|
|
271
|
+
remove = []
|
|
272
|
+
matrix.columns.times do |c|
|
|
273
|
+
if matrix.sum_of_column(c+1) == 0
|
|
274
|
+
result[unseen[c]-1] = r
|
|
275
|
+
remove.unshift( c + 1 )
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
remove.each do |rem|
|
|
280
|
+
matrix = matrix.remove_line(rem).remove_column(rem)
|
|
281
|
+
unseen.delete_at(rem-1)
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
if matrix.columns == 1 and matrix.lines == 1
|
|
285
|
+
if matrix.sum_of_column(1) == 0
|
|
286
|
+
result[unseen[0]-1] = r+1
|
|
287
|
+
end
|
|
288
|
+
elsif remove.size > 0
|
|
289
|
+
range_recursion( matrix, unseen, result, r+1 )
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
return result
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
def index_of_item( array, item )
|
|
296
|
+
array.inject( [0,[]] ){|a,i|
|
|
297
|
+
a[1] << a[0] if i == item
|
|
298
|
+
a[0] += 1
|
|
299
|
+
a
|
|
300
|
+
}[1]
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
def critical_path_recursion( d, a, r, result, level )
|
|
304
|
+
r.each do |p|
|
|
305
|
+
node = p[1][-1]
|
|
306
|
+
index_of_item( a.line(node), 1 ).each do |c|
|
|
307
|
+
succ = c+1
|
|
308
|
+
|
|
309
|
+
cpath = [ (p[0] + d[node,succ]), (p[1].clone << succ) ]
|
|
310
|
+
|
|
311
|
+
if index_of_item( a.line(succ), 1 ).size > 0
|
|
312
|
+
critical_path_recursion( d, a, [cpath], result, level+1 )
|
|
313
|
+
else
|
|
314
|
+
result << cpath
|
|
315
|
+
end
|
|
316
|
+
end
|
|
317
|
+
end
|
|
318
|
+
return result
|
|
319
|
+
end
|
|
320
|
+
end
|
|
321
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# >> x = "hello\n\t\\l\"world\""
|
|
2
|
+
# => "hello\n\t\\l\"world\""
|
|
3
|
+
# >> puts x.inspect.gsub( "\\\\", "\\" )
|
|
4
|
+
# "hello\n\t\l\"world\""
|
|
5
|
+
#
|
|
6
|
+
# OR
|
|
7
|
+
#
|
|
8
|
+
# >> x = 'hello\n\t\l"world"'
|
|
9
|
+
# => "hello\\n\\t\\l\"world\""
|
|
10
|
+
# >> puts x.inspect.gsub( "\\\\", "\\" )
|
|
11
|
+
# "hello\n\t\l\"world\""
|
|
12
|
+
|
|
13
|
+
class GraphViz
|
|
14
|
+
class Types
|
|
15
|
+
class ArrowType < Common
|
|
16
|
+
def check(data)
|
|
17
|
+
return data
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def output
|
|
21
|
+
return @data.to_s.inspect.gsub( "\\\\", "\\" )
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
alias :to_gv :output
|
|
25
|
+
alias :to_s :output
|
|
26
|
+
|
|
27
|
+
def to_ruby
|
|
28
|
+
@data
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require 'graphviz/utils/colors'
|
|
2
|
+
|
|
3
|
+
class ColorException < RuntimeError
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
class GraphViz
|
|
7
|
+
class Types
|
|
8
|
+
class Color < Common
|
|
9
|
+
HEX_FOR_COLOR = /[0-9a-fA-F]{2}/
|
|
10
|
+
RGBA = /^#(#{HEX_FOR_COLOR})(#{HEX_FOR_COLOR})(#{HEX_FOR_COLOR})(#{HEX_FOR_COLOR})?$/
|
|
11
|
+
|
|
12
|
+
def check(data)
|
|
13
|
+
data = data.to_s if data.is_a?(Symbol)
|
|
14
|
+
return nil if data.empty?
|
|
15
|
+
|
|
16
|
+
if data[0].chr == "#"
|
|
17
|
+
m = RGBA.match(data)
|
|
18
|
+
if m.nil?
|
|
19
|
+
raise ColorException, "Wrong color definition RGBA #{data}"
|
|
20
|
+
end
|
|
21
|
+
@to_ruby = GraphViz::Utils::Colors.rgb(m[1], m[2], m[3], m[4])
|
|
22
|
+
return data
|
|
23
|
+
elsif data.include?(",") or data.include?(" ")
|
|
24
|
+
m = data.split(/(?:\s*,\s*|\s+)/).map { |x| x.to_f }
|
|
25
|
+
if m.size != 3
|
|
26
|
+
raise ColorException, "Wrong color definition HSV #{data}"
|
|
27
|
+
end
|
|
28
|
+
@to_ruby = GraphViz::Utils::Colors.hsv(m[0], m[1], m[2])
|
|
29
|
+
return data
|
|
30
|
+
elsif data.is_a?(Array)
|
|
31
|
+
if data.all? { |x| x.is_a?(String) and x =~ /^#{HEX_FOR_COLOR}$/ } and [3,4].include?(data.size)
|
|
32
|
+
@to_ruby = GraphViz::Utils::Colors.rgb(data[0], data[1], data[2], data[3])
|
|
33
|
+
return data
|
|
34
|
+
elsif data.all? { |x| x.kind_of?(Numeric) } and data.size == 3
|
|
35
|
+
@to_ruby = GraphViz::Utils::Colors.hsv(data[0], data[1], data[2])
|
|
36
|
+
return data
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
raise ColorException, "Wrong color definition Array #{data}"
|
|
40
|
+
else
|
|
41
|
+
@to_ruby = GraphViz::Utils::Colors.name(data)
|
|
42
|
+
return data
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def output
|
|
47
|
+
return @data.to_s.inspect.gsub( "\\\\", "\\" )
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
alias :to_gv :output
|
|
51
|
+
alias :to_s :output
|
|
52
|
+
|
|
53
|
+
def to_ruby
|
|
54
|
+
@to_ruby
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|