ruby-graphviz_c 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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,118 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'graphviz'
|
5
|
+
require 'graphviz/family_tree/generation'
|
6
|
+
require 'graphviz/family_tree/person'
|
7
|
+
require 'graphviz/family_tree/couple'
|
8
|
+
require 'graphviz/family_tree/sibling'
|
9
|
+
|
10
|
+
class GraphViz
|
11
|
+
class FamilyTree
|
12
|
+
# Create a new family tree
|
13
|
+
#
|
14
|
+
# require 'graphviz/family_tree'
|
15
|
+
# t = GraphViz::FamilyTree.new do
|
16
|
+
# ...
|
17
|
+
# end
|
18
|
+
def initialize( &block )
|
19
|
+
@persons = {}
|
20
|
+
@graph = GraphViz.new( "FamilyTree", :use => :neato )
|
21
|
+
@generation_number = 0
|
22
|
+
@generations = []
|
23
|
+
@couples = {}
|
24
|
+
|
25
|
+
instance_eval(&block) if block
|
26
|
+
end
|
27
|
+
|
28
|
+
# Add a new generation in the tree
|
29
|
+
#
|
30
|
+
# require 'graphviz/family_tree'
|
31
|
+
# t = GraphViz::FamilyTree.new do
|
32
|
+
# generation do
|
33
|
+
# ...
|
34
|
+
# end
|
35
|
+
# generation do
|
36
|
+
# ...
|
37
|
+
# end
|
38
|
+
# end
|
39
|
+
def generation( &b )
|
40
|
+
gen = GraphViz::FamilyTree::Generation.new( @graph, @persons, self, @generation_number )
|
41
|
+
gen.make( &b )
|
42
|
+
@generations << gen
|
43
|
+
@generation_number += 1
|
44
|
+
end
|
45
|
+
|
46
|
+
def persons #:nodoc:
|
47
|
+
@persons ||= {}
|
48
|
+
end
|
49
|
+
|
50
|
+
def add_couple( x, y, node ) #:nodoc:
|
51
|
+
@couples[x] = {} if @couples[x].nil?
|
52
|
+
@couples[x][y] = GraphViz::FamilyTree::Couple.new( @graph, node, [x, y] )
|
53
|
+
@couples[y] = {} if @couples[y].nil?
|
54
|
+
@couples[y][x] = @couples[x][y]
|
55
|
+
end
|
56
|
+
|
57
|
+
# Get a couple (GraphViz::FamilyTree::Couple)
|
58
|
+
def couple( x, y )
|
59
|
+
@couples[x][y]
|
60
|
+
end
|
61
|
+
|
62
|
+
def method_missing(sym, *args, &block) #:nodoc:
|
63
|
+
persons[sym.to_s]
|
64
|
+
end
|
65
|
+
|
66
|
+
# Family size
|
67
|
+
def size
|
68
|
+
@persons.size
|
69
|
+
end
|
70
|
+
|
71
|
+
# Get the graph
|
72
|
+
def graph
|
73
|
+
maxY = @generations.size
|
74
|
+
biggestGen, maxX = biggestGenerationNumberAndSize
|
75
|
+
|
76
|
+
puts "#{maxY} generations"
|
77
|
+
puts "Plus grosse generation : ##{biggestGen} avec #{maxX} personnes"
|
78
|
+
|
79
|
+
puts "traitement des générations..."
|
80
|
+
|
81
|
+
puts " #{biggestGen}:"
|
82
|
+
@generations[biggestGen].persons.each do |id, person|
|
83
|
+
puts " - #{id} : #{person.class}"
|
84
|
+
end
|
85
|
+
|
86
|
+
puts " Up..."
|
87
|
+
(0...biggestGen).reverse_each do |genNumber|
|
88
|
+
puts " #{genNumber}:"
|
89
|
+
@generations[genNumber].persons.each do |id, person|
|
90
|
+
puts " - #{id} : #{person.class}"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
puts " Down..."
|
95
|
+
((biggestGen+1)...maxY).each do |genNumber|
|
96
|
+
puts " #{genNumber}:"
|
97
|
+
@generations[genNumber].persons.each do |id, person|
|
98
|
+
puts " - #{id} : #{person.class}"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
@graph
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
def biggestGenerationNumberAndSize
|
107
|
+
size = 0
|
108
|
+
number = 0
|
109
|
+
@generations.each do |gen|
|
110
|
+
if gen.size > size
|
111
|
+
size = gen.size
|
112
|
+
number = gen.number
|
113
|
+
end
|
114
|
+
end
|
115
|
+
return number, size
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,268 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Copyright (C) 2010 Gregoire Lejeune <gregoire.lejeune@free.fr>
|
3
|
+
#
|
4
|
+
# This program is free software; you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
6
|
+
# the Free Software Foundation; either version 2 of the License, or
|
7
|
+
# (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program; if not, write to the Free Software
|
16
|
+
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
17
|
+
|
18
|
+
require 'graphviz'
|
19
|
+
require 'rexml/document'
|
20
|
+
|
21
|
+
class GraphViz
|
22
|
+
class GraphMLError < RuntimeError
|
23
|
+
end
|
24
|
+
|
25
|
+
class GraphML
|
26
|
+
attr_reader :attributes
|
27
|
+
def attributs
|
28
|
+
warn "`GraphViz::GraphML#attributs` is deprecated, please, use `GraphViz::GraphML#attributes`"
|
29
|
+
return @attributes
|
30
|
+
end
|
31
|
+
|
32
|
+
# The GraphViz object
|
33
|
+
attr_accessor :graph
|
34
|
+
|
35
|
+
DEST = {
|
36
|
+
'node' => [:nodes],
|
37
|
+
'edge' => [:edges],
|
38
|
+
'graph' => [:graphs],
|
39
|
+
'graphml' => [:graphml],
|
40
|
+
'hyperedge' => [:hyperedge],
|
41
|
+
'port' => [:port],
|
42
|
+
'endpoint' => [:endpoint],
|
43
|
+
'all' => [:nodes, :edges, :graphs, :graphml, :hyperedge, :port, :endpoint]
|
44
|
+
}
|
45
|
+
|
46
|
+
GTYPE = {
|
47
|
+
'directed' => :digraph,
|
48
|
+
'undirected' => :graph
|
49
|
+
}
|
50
|
+
|
51
|
+
# Create a new GraphViz object from a GraphML file of string
|
52
|
+
def initialize( file_or_str )
|
53
|
+
data = ((File.file?( file_or_str )) ? File::new(file_or_str) : file_or_str)
|
54
|
+
@xmlDoc = REXML::Document::new( data )
|
55
|
+
@attributes = {
|
56
|
+
:nodes => {},
|
57
|
+
:edges => {},
|
58
|
+
:graphs => {},
|
59
|
+
:graphml => {},
|
60
|
+
:endpoint => {},
|
61
|
+
:port => {},
|
62
|
+
:hyperedge => {}
|
63
|
+
}
|
64
|
+
@ignored_keys = []
|
65
|
+
@graph = nil
|
66
|
+
@current_attr = nil
|
67
|
+
@current_node = nil
|
68
|
+
@current_edge = nil
|
69
|
+
@current_graph = nil
|
70
|
+
|
71
|
+
parse( @xmlDoc.root )
|
72
|
+
end
|
73
|
+
|
74
|
+
def parse( node ) #:nodoc:
|
75
|
+
send( node.name.to_sym, node )
|
76
|
+
end
|
77
|
+
|
78
|
+
def graphml( node ) #:nodoc:
|
79
|
+
node.each_element( ) do |child|
|
80
|
+
begin
|
81
|
+
send( "graphml_#{child.name}".to_sym, child )
|
82
|
+
rescue NoMethodError => e
|
83
|
+
raise GraphMLError, "node #{child.name} can be child of graphml"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def graphml_data(node)
|
89
|
+
warn "graphml/data not supported!"
|
90
|
+
end
|
91
|
+
|
92
|
+
def graphml_key( node ) #:nodoc:
|
93
|
+
id = node.attributes['id']
|
94
|
+
@current_attr = {
|
95
|
+
:name => node.attributes['attr.name'],
|
96
|
+
:type => node.attributes['attr.type']
|
97
|
+
}
|
98
|
+
if @current_attr[:name].nil?
|
99
|
+
@ignored_keys << id
|
100
|
+
else
|
101
|
+
DEST[node.attributes['for']].each do |d|
|
102
|
+
@attributes[d][id] = @current_attr
|
103
|
+
end
|
104
|
+
|
105
|
+
node.each_element( ) do |child|
|
106
|
+
begin
|
107
|
+
send( "graphml_key_#{child.name}".to_sym, child )
|
108
|
+
rescue NoMethodError => e
|
109
|
+
raise GraphMLError, "node #{child.name} can be child of key"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
@current_attr = nil
|
115
|
+
end
|
116
|
+
|
117
|
+
def graphml_key_default( node ) #:nodoc:
|
118
|
+
@current_attr[:default] = node.texts().join('\n')
|
119
|
+
end
|
120
|
+
|
121
|
+
def graphml_graph( node ) #:nodoc:
|
122
|
+
@current_node = nil
|
123
|
+
|
124
|
+
if @current_graph.nil?
|
125
|
+
@graph = GraphViz.new( node.attributes['id'], :type => GTYPE[node.attributes['edgedefault']] )
|
126
|
+
@current_graph = @graph
|
127
|
+
previous_graph = @graph
|
128
|
+
else
|
129
|
+
previous_graph = @current_graph
|
130
|
+
@current_graph = previous_graph.add_graph( node.attributes['id'] )
|
131
|
+
end
|
132
|
+
|
133
|
+
@attributes[:graphs].each do |id, data|
|
134
|
+
begin
|
135
|
+
@current_graph.graph[data[:name]] = data[:default] if data.has_key?(:default)
|
136
|
+
rescue ArgumentError => e
|
137
|
+
warn e
|
138
|
+
end
|
139
|
+
end
|
140
|
+
@attributes[:nodes].each do |id, data|
|
141
|
+
begin
|
142
|
+
@current_graph.node[data[:name]] = data[:default] if data.has_key?(:default)
|
143
|
+
rescue ArgumentError => e
|
144
|
+
warn e
|
145
|
+
end
|
146
|
+
end
|
147
|
+
@attributes[:edges].each do |id, data|
|
148
|
+
begin
|
149
|
+
@current_graph.edge[data[:name]] = data[:default] if data.has_key?(:default)
|
150
|
+
rescue ArgumentError => e
|
151
|
+
warn e
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
node.each_element( ) do |child|
|
156
|
+
send( "graphml_graph_#{child.name}".to_sym, child )
|
157
|
+
end
|
158
|
+
|
159
|
+
@current_graph = previous_graph
|
160
|
+
end
|
161
|
+
|
162
|
+
def graphml_graph_data( node ) #:nodoc:
|
163
|
+
begin
|
164
|
+
@current_graph[@attributes[:graphs][node.attributes['key']][:name]] = node.texts().join('\n')
|
165
|
+
rescue ArgumentError => e
|
166
|
+
warn e
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def graphml_graph_node( node ) #:nodoc:
|
171
|
+
@current_node = {}
|
172
|
+
|
173
|
+
node.each_element( ) do |child|
|
174
|
+
case child.name
|
175
|
+
when "graph"
|
176
|
+
graphml_graph( child )
|
177
|
+
else
|
178
|
+
begin
|
179
|
+
send( "graphml_graph_node_#{child.name}".to_sym, child )
|
180
|
+
rescue NoMethodError => e
|
181
|
+
raise GraphMLError, "node #{child.name} can be child of node"
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
unless @current_node.nil?
|
187
|
+
node = @current_graph.add_nodes( node.attributes['id'] )
|
188
|
+
@current_node.each do |k, v|
|
189
|
+
begin
|
190
|
+
node[k] = v
|
191
|
+
rescue ArgumentError => e
|
192
|
+
warn e
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
@current_node = nil
|
198
|
+
end
|
199
|
+
|
200
|
+
def graphml_graph_node_data( node ) #:nodoc:
|
201
|
+
return if @ignored_keys.include?(node.attributes['key'])
|
202
|
+
begin
|
203
|
+
@current_node[@attributes[:nodes][node.attributes['key']][:name]] = node.texts().join('\n')
|
204
|
+
rescue ArgumentError => e
|
205
|
+
warn e
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
def graphml_graph_node_port( node ) #:nodoc:
|
210
|
+
@current_node[:shape] = :record
|
211
|
+
port = node.attributes['name']
|
212
|
+
if @current_node[:label]
|
213
|
+
label = @current_node[:label].gsub( "{", "" ).gsub( "}", "" )
|
214
|
+
@current_node[:label] = "#{label}|<#{port}> #{port}"
|
215
|
+
else
|
216
|
+
@current_node[:label] = "<#{port}> #{port}"
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
def graphml_graph_edge( node ) #:nodoc:
|
221
|
+
source = node.attributes['source']
|
222
|
+
source = {source => node.attributes['sourceport']} if node.attributes['sourceport']
|
223
|
+
target = node.attributes['target']
|
224
|
+
target = {target => node.attributes['targetport']} if node.attributes['targetport']
|
225
|
+
|
226
|
+
@current_edge = @current_graph.add_edges( source, target )
|
227
|
+
|
228
|
+
node.each_element( ) do |child|
|
229
|
+
begin
|
230
|
+
send( "graphml_graph_edge_#{child.name}".to_sym, child )
|
231
|
+
rescue NoMethodError => e
|
232
|
+
raise GraphMLError, "node #{child.name} can be child of edge"
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
@current_edge = nil
|
237
|
+
end
|
238
|
+
|
239
|
+
def graphml_graph_edge_data( node ) #:nodoc:
|
240
|
+
return if @ignored_keys.include?(node.attributes['key'])
|
241
|
+
begin
|
242
|
+
@current_edge[@attributes[:edges][node.attributes['key']][:name]] = node.texts().join('\n')
|
243
|
+
rescue ArgumentError => e
|
244
|
+
warn e
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
def graphml_graph_hyperedge( node ) #:nodoc:
|
249
|
+
list = []
|
250
|
+
|
251
|
+
node.each_element( ) do |child|
|
252
|
+
if child.name == "endpoint"
|
253
|
+
if child.attributes['port']
|
254
|
+
list << { child.attributes['node'] => child.attributes['port'] }
|
255
|
+
else
|
256
|
+
list << child.attributes['node']
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
list.each { |s|
|
262
|
+
list.each { |t|
|
263
|
+
@current_graph.add_edges( s, t ) unless s == t
|
264
|
+
}
|
265
|
+
}
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
@@ -0,0 +1,221 @@
|
|
1
|
+
class GraphViz
|
2
|
+
class Math
|
3
|
+
def self.Matrix( line, column = 0, val = 0 )
|
4
|
+
GraphViz::Math::Matrix.new(line, column, val)
|
5
|
+
end
|
6
|
+
|
7
|
+
class CoordinateError < RuntimeError
|
8
|
+
end
|
9
|
+
class ValueError < RuntimeError
|
10
|
+
end
|
11
|
+
|
12
|
+
class Matrix
|
13
|
+
def initialize( line_or_array, column = 0, val = 0 )
|
14
|
+
if line_or_array.kind_of?(Array)
|
15
|
+
line = line_or_array.size
|
16
|
+
column = nil
|
17
|
+
line_or_array.size.times do |l|
|
18
|
+
unless line_or_array[l].kind_of?(Array)
|
19
|
+
raise ArgumentError, "Wrong matrix definition"
|
20
|
+
end
|
21
|
+
column = line_or_array[l].size if column.nil?
|
22
|
+
unless line_or_array[l].size == column
|
23
|
+
raise ArgumentError, "Wrong matrix definition"
|
24
|
+
end
|
25
|
+
line_or_array[l].size.times do |c|
|
26
|
+
unless line_or_array[l][c].kind_of?(Numeric)
|
27
|
+
raise ValueError, "Element at [#{l+1}, #{c+1}] is not a number"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
@matrix = line_or_array
|
33
|
+
@line = line
|
34
|
+
@column = column
|
35
|
+
elsif line_or_array.kind_of?(Integer) and column > 0
|
36
|
+
@matrix = Array.new(line_or_array)
|
37
|
+
@matrix.size.times do |l|
|
38
|
+
@matrix[l] = Array.new(column)
|
39
|
+
@matrix[l].size.times do |c|
|
40
|
+
@matrix[l][c] = val
|
41
|
+
end
|
42
|
+
end
|
43
|
+
@line = line_or_array
|
44
|
+
@column = column
|
45
|
+
else
|
46
|
+
raise ArgumentError, "Wrong matrix definition"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def [](line, column)
|
51
|
+
unless (0...@line).to_a.include?(line-1)
|
52
|
+
raise CoordinateError, "Line out of range (#{line} for 1..#{@line})!"
|
53
|
+
end
|
54
|
+
unless (0...@column).to_a.include?(column-1)
|
55
|
+
raise CoordinateError, "Column out of range (#{column} for 1..#{@column})!"
|
56
|
+
end
|
57
|
+
@matrix[line-1][column-1]
|
58
|
+
end
|
59
|
+
|
60
|
+
def []=( line, column, val )
|
61
|
+
unless (0...@line).to_a.include?(line-1)
|
62
|
+
raise CoordinateError, "Line out of range (#{line} for 1..#{@line})!"
|
63
|
+
end
|
64
|
+
unless (0...@column).to_a.include?(column-1)
|
65
|
+
raise CoordinateError, "Column out of range (#{column} for 1..#{@column})!"
|
66
|
+
end
|
67
|
+
@matrix[line-1][column-1] = val
|
68
|
+
end
|
69
|
+
|
70
|
+
def matrix
|
71
|
+
@matrix
|
72
|
+
end
|
73
|
+
alias :to_a :matrix
|
74
|
+
|
75
|
+
def columns
|
76
|
+
@column
|
77
|
+
end
|
78
|
+
|
79
|
+
def lines
|
80
|
+
@line
|
81
|
+
end
|
82
|
+
|
83
|
+
def to_s
|
84
|
+
size = bigger
|
85
|
+
out = ""
|
86
|
+
@line.times do |line|
|
87
|
+
out << "["
|
88
|
+
@column.times do |column|
|
89
|
+
out << sprintf(" %1$*2$s", @matrix[line][column].to_s, size)
|
90
|
+
end
|
91
|
+
out << "]\n"
|
92
|
+
end
|
93
|
+
return out
|
94
|
+
end
|
95
|
+
|
96
|
+
def -(m)
|
97
|
+
matrix = GraphViz::Math::Matrix.new( @line, @column )
|
98
|
+
@line.times do |line|
|
99
|
+
@column.times do |column|
|
100
|
+
matrix[line+1, column+1] = self[line+1, column+1] - m[line+1, column+1]
|
101
|
+
end
|
102
|
+
end
|
103
|
+
return matrix
|
104
|
+
end
|
105
|
+
|
106
|
+
def *(m)
|
107
|
+
matrix = GraphViz::Math::Matrix.new( @line, @line )
|
108
|
+
|
109
|
+
@line.times do |line|
|
110
|
+
@line.times do |column|
|
111
|
+
l = self.line(line+1)
|
112
|
+
c = m.column(column+1)
|
113
|
+
v = 0
|
114
|
+
l.size.times do |i|
|
115
|
+
v += l[i]*c[i]
|
116
|
+
end
|
117
|
+
matrix[line+1,column+1] = v
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
return matrix
|
122
|
+
end
|
123
|
+
|
124
|
+
def line( line )
|
125
|
+
unless (0...@line).to_a.include?(line-1)
|
126
|
+
raise CoordinateError, "Line out of range (#{line} for 1..#{@line})!"
|
127
|
+
end
|
128
|
+
@matrix[line-1]
|
129
|
+
end
|
130
|
+
|
131
|
+
def column( column )
|
132
|
+
col = []
|
133
|
+
unless (0...@column).to_a.include?(column-1)
|
134
|
+
raise CoordinateError, "Column out of range (#{column} for 1..#{@column})!"
|
135
|
+
end
|
136
|
+
@line.times do |line|
|
137
|
+
col << self[line+1, column]
|
138
|
+
end
|
139
|
+
|
140
|
+
return col
|
141
|
+
end
|
142
|
+
|
143
|
+
def transpose
|
144
|
+
matrix = GraphViz::Math::Matrix.new( @column, @line )
|
145
|
+
@line.times do |line|
|
146
|
+
@column.times do |column|
|
147
|
+
matrix[column+1, line+1] = self[line+1, column+1]
|
148
|
+
end
|
149
|
+
end
|
150
|
+
return matrix
|
151
|
+
end
|
152
|
+
|
153
|
+
def ==(m)
|
154
|
+
equal = true
|
155
|
+
@line.times do |line|
|
156
|
+
@column.times do |column|
|
157
|
+
equal &&= (m[line+1, column+1] == self[line+1, column+1])
|
158
|
+
end
|
159
|
+
end
|
160
|
+
return equal
|
161
|
+
end
|
162
|
+
|
163
|
+
def remove_line(n)
|
164
|
+
unless (0...@line).to_a.include?(n-1)
|
165
|
+
raise CoordinateError, "Line out of range (#{n} for 1..#{@line})!"
|
166
|
+
end
|
167
|
+
|
168
|
+
matrix = GraphViz::Math::Matrix.new( @line - 1, @column )
|
169
|
+
nline = 0
|
170
|
+
@line.times do |line|
|
171
|
+
next if line == n - 1
|
172
|
+
@column.times do |column|
|
173
|
+
matrix[nline+1, column+1] = self[line+1, column+1]
|
174
|
+
end
|
175
|
+
nline += 1
|
176
|
+
end
|
177
|
+
return matrix
|
178
|
+
end
|
179
|
+
|
180
|
+
def remove_column(n)
|
181
|
+
unless (0...@column).to_a.include?(n-1)
|
182
|
+
raise CoordinateError, "Column out of range (#{n} for 1..#{@column})!"
|
183
|
+
end
|
184
|
+
|
185
|
+
matrix = GraphViz::Math::Matrix.new( @line, @column - 1 )
|
186
|
+
@line.times do |line|
|
187
|
+
ncolumn = 0
|
188
|
+
@column.times do |column|
|
189
|
+
next if column == n - 1
|
190
|
+
matrix[line+1, ncolumn+1] = self[line+1, column+1]
|
191
|
+
ncolumn += 1
|
192
|
+
end
|
193
|
+
end
|
194
|
+
return matrix
|
195
|
+
end
|
196
|
+
|
197
|
+
def sum_of_column(n)
|
198
|
+
column(n).inject(0){|sum,item| sum + item}
|
199
|
+
end
|
200
|
+
|
201
|
+
def sum_of_line(n)
|
202
|
+
line(n).inject(0){|sum,item| sum + item}
|
203
|
+
end
|
204
|
+
|
205
|
+
def set_matrix(m) #:nodoc:
|
206
|
+
@matrix = m
|
207
|
+
end
|
208
|
+
|
209
|
+
private
|
210
|
+
def bigger
|
211
|
+
b = 0
|
212
|
+
@matrix.each do |line|
|
213
|
+
line.each do |column|
|
214
|
+
b = column.to_s.size if column.to_s.size > b
|
215
|
+
end
|
216
|
+
end
|
217
|
+
return b
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|