gviz 0.0.1

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.
@@ -0,0 +1,71 @@
1
+ require_relative "../lib/gviz"
2
+
3
+ simple = Gviz.new
4
+ simple.graph do
5
+ route :main => [:init, :parse, :cleanup, :printf]
6
+ route :init => :make
7
+ route :parse => :execute
8
+ route :execute => [:make, :compare, :printf]
9
+ end
10
+ # simple.save(:a, :svg)
11
+
12
+ enhanced = Gviz.new
13
+ enhanced.graph do
14
+ route :main => [:init, :parse, :cleanup, :printf]
15
+ route :init => :make, :parse => :execute
16
+ route :execute => [:make, :compare, :printf]
17
+ node(:main, :shape => 'box')
18
+ node(:compare, :shape => 'box', :style => 'filled', :color => '.7 .3 1.0')
19
+ node(:make, :label => "make a\nstring")
20
+ edge(:main_printf, :style => 'bold', :label => "100 times", :color => 'red', :weight => 8)
21
+ edge(:main_parse, :weight => 8)
22
+ edge(:main_init, :style => "dotted")
23
+ edge(:execute_compare, :color => 'red')
24
+ end
25
+ # puts enhanced
26
+
27
+ polygonal = Gviz.new
28
+ polygonal.graph do
29
+ route :a => :b, :b => [:c, :d]
30
+ node(:a, :shape => 'polygon', :sides => 5, :peripheries => 3, :style => 'filled', :fillcolor => '#DA70D6')
31
+ node(:c, :shape => 'polygon', :sides => 4, :skew => 0.4, :label => "hellow world", :peripheries => 2, :orientation => 20, :fontname => 'Helvetica', :fontcolor => '#DA70D6')
32
+ node(:d, :shape => 'invtriangle')
33
+ node(:e, :shape => 'polygon', :style => 'setlinewidth(8)', :sides => 4, :distortion => 0.7)
34
+ edge(:b_d, :label => 'path to the world', :decorate => true, :labelfloat => true)
35
+ edge(:a_b, :dir => 'both', :headport => 'se')
36
+ edge(:a_b_1, :dir => 'back')
37
+ global(:rankdir => "TB", :rankseq => 'equally')
38
+ end
39
+ # puts polygonal
40
+
41
+ record = Gviz.new
42
+ record.graph do
43
+ nodes(:shape => 'record')
44
+ route :st1 => [:st2, :st3]
45
+ node(:st1, :label => "<f0> left|<f1> middle|<f2> right")
46
+ node(:st2, :label => "<f0> one|<f1> two")
47
+ node(:st3, :label => "hello\nworld|{b|{c|<here> d|e}|f}|g|h")
48
+ edge("st1:f1_st2:f0")
49
+ edge("st1:f2_st3:here")
50
+ end
51
+ # puts record
52
+
53
+ sub = Gviz.new
54
+ sub.graph do
55
+ subgraph do
56
+ nodes(style:'filled', color:'white')
57
+ global(style:'filled', color:'lightgrey', label:'process #1')
58
+ route(:a0 => :a1, :a1 => :a2, :a2 => :a3)
59
+ end
60
+
61
+ subgraph do
62
+ nodes(style:'filled')
63
+ global(color:'blue', label:'process #2')
64
+ route(:b0 => :b1, :b1 => :b2, :b2 => :b3)
65
+ end
66
+ route :start => [:a0, :b0]
67
+ route :a1 => :b3, :b2 => :a3, :a3 => [:a0, :end], :b3 => :end
68
+ node(:start, shape:'Mdiamond')
69
+ node(:end, shape:'Msquare')
70
+ end
71
+ # sub.save('a', 'png')
Binary file
Binary file
Binary file
@@ -0,0 +1,59 @@
1
+ # encoding: UTF-8
2
+ require "nokogiri"
3
+ require "open-uri"
4
+
5
+ module Gviz
6
+ class Scraper
7
+ URL = "http://www.graphviz.org/content/"
8
+
9
+ class << self
10
+ def build(path)
11
+ @html ||= get(URL+path)
12
+ parse @html
13
+ end
14
+
15
+ def get(url)
16
+ @html = Nokogiri::HTML(open url)
17
+ rescue OpenURI::HTTPError => e
18
+ STDERR.puts "HTTP Access Error:#{e}"
19
+ exit
20
+ end
21
+
22
+ def parse(html)
23
+ q = []
24
+
25
+ # ## shapes
26
+ # html.css("div.content>table td>a").each do |a|
27
+ # q << a.text
28
+ # end
29
+ # return q.uniq
30
+
31
+ ## arrows
32
+ html.css("table").each_with_index do |tbl, i|
33
+ if i == 5
34
+ tbl.css("td").each do |e|
35
+ txt = e.text.strip.chomp
36
+ q << txt unless txt.empty?
37
+ end
38
+ end
39
+ end
40
+ return q.uniq
41
+
42
+ # ## X11 colors scheme
43
+ # table = html.at("div.content>table").css('td>a').each do |color|
44
+ # txt = color.text.gsub(' ','')
45
+ # q << txt unless txt.match(/^\d+$/)
46
+ # end
47
+ # return q.sort.uniq.group_by { |c| c[/^\D+/]; $& }
48
+ # .flat_map { |k, v| v.sort_by { |c| c[/\d+/].to_i } }
49
+
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ if __FILE__ == $0
56
+ # puts Gviz::Scraper.build("node-shapes")
57
+ puts Gviz::Scraper.build("arrow-shapes")
58
+ # puts Gviz::Scraper.build("color-names")
59
+ end
@@ -0,0 +1,108 @@
1
+ digraph G {
2
+ node[style="filled",fillcolor="orchid"];
3
+ edge[arrowhead="none"];
4
+ box[shape="box"];
5
+ polygon[shape="polygon"];
6
+ ellipse[shape="ellipse"];
7
+ oval[shape="oval"];
8
+ circle[shape="circle"];
9
+ point[shape="point"];
10
+ egg[shape="egg"];
11
+ triangle[shape="triangle"];
12
+ plaintext[shape="plaintext"];
13
+ diamond[shape="diamond"];
14
+ trapezium[shape="trapezium"];
15
+ parallelogram[shape="parallelogram"];
16
+ house[shape="house"];
17
+ pentagon[shape="pentagon"];
18
+ hexagon[shape="hexagon"];
19
+ septagon[shape="septagon"];
20
+ octagon[shape="octagon"];
21
+ doublecircle[shape="doublecircle"];
22
+ doubleoctagon[shape="doubleoctagon"];
23
+ tripleoctagon[shape="tripleoctagon"];
24
+ invtriangle[shape="invtriangle"];
25
+ invtrapezium[shape="invtrapezium"];
26
+ invhouse[shape="invhouse"];
27
+ Mdiamond[shape="Mdiamond"];
28
+ Msquare[shape="Msquare"];
29
+ Mcircle[shape="Mcircle"];
30
+ rect[shape="rect"];
31
+ rectangle[shape="rectangle"];
32
+ square[shape="square"];
33
+ none[shape="none"];
34
+ note[shape="note"];
35
+ tab[shape="tab"];
36
+ folder[shape="folder"];
37
+ box3d[shape="box3d"];
38
+ component[shape="component"];
39
+ promoter[shape="promoter"];
40
+ cds[shape="cds"];
41
+ terminator[shape="terminator"];
42
+ utr[shape="utr"];
43
+ primersite[shape="primersite"];
44
+ restrictionsite[shape="restrictionsite"];
45
+ fivepoverhang[shape="fivepoverhang"];
46
+ threepoverhang[shape="threepoverhang"];
47
+ noverhang[shape="noverhang"];
48
+ assembly[shape="assembly"];
49
+ signature[shape="signature"];
50
+ insulator[shape="insulator"];
51
+ ribosite[shape="ribosite"];
52
+ rnastab[shape="rnastab"];
53
+ proteasesite[shape="proteasesite"];
54
+ proteinstab[shape="proteinstab"];
55
+ rpromoter[shape="rpromoter"];
56
+ rarrow[shape="rarrow"];
57
+ larrow[shape="larrow"];
58
+ lpromoter[shape="lpromoter"];
59
+ box -> polygon;
60
+ polygon -> ellipse;
61
+ ellipse -> oval;
62
+ oval -> circle;
63
+ circle -> point[headlabel="point"];
64
+ point -> egg;
65
+ egg -> triangle;
66
+ triangle -> plaintext;
67
+ plaintext -> diamond;
68
+ trapezium -> parallelogram;
69
+ parallelogram -> house;
70
+ house -> pentagon;
71
+ pentagon -> hexagon;
72
+ hexagon -> septagon;
73
+ septagon -> octagon;
74
+ octagon -> doublecircle;
75
+ doublecircle -> doubleoctagon;
76
+ doubleoctagon -> tripleoctagon;
77
+ invtriangle -> invtrapezium;
78
+ invtrapezium -> invhouse;
79
+ invhouse -> Mdiamond;
80
+ Mdiamond -> Msquare;
81
+ Msquare -> Mcircle;
82
+ Mcircle -> rect;
83
+ rect -> rectangle;
84
+ rectangle -> square;
85
+ square -> none;
86
+ note -> tab;
87
+ tab -> folder;
88
+ folder -> box3d;
89
+ box3d -> component;
90
+ component -> promoter;
91
+ promoter -> cds;
92
+ cds -> terminator;
93
+ terminator -> utr;
94
+ utr -> primersite;
95
+ restrictionsite -> fivepoverhang;
96
+ fivepoverhang -> threepoverhang;
97
+ threepoverhang -> noverhang;
98
+ noverhang -> assembly;
99
+ assembly -> signature;
100
+ signature -> insulator;
101
+ insulator -> ribosite;
102
+ ribosite -> rnastab;
103
+ rnastab -> proteasesite;
104
+ proteinstab -> rpromoter;
105
+ rpromoter -> rarrow;
106
+ rarrow -> larrow;
107
+ larrow -> lpromoter;
108
+ }
@@ -0,0 +1,79 @@
1
+ # Shape Varieties
2
+ require_relative "../lib/gviz"
3
+
4
+ shapes = DATA.lines.map(&:chomp).reject { |l| l.empty? }
5
+
6
+ g = Gviz.new
7
+
8
+ g.graph do
9
+ nodes(style:'filled', fillcolor:'orchid')
10
+ edges(arrowhead:'none')
11
+ shapes.each { |shape| node shape.intern, shape: shape }
12
+
13
+ shapes.each_slice(10) do |gr|
14
+ gr.each_cons(2) do |a, b|
15
+ route a.intern => b.intern
16
+ end
17
+ end
18
+ edge(:circle_point, headlabel:'point')
19
+ end
20
+
21
+
22
+ puts g
23
+
24
+ __END__
25
+ box
26
+ polygon
27
+ ellipse
28
+ oval
29
+ circle
30
+ point
31
+ egg
32
+ triangle
33
+ plaintext
34
+ diamond
35
+ trapezium
36
+ parallelogram
37
+ house
38
+ pentagon
39
+ hexagon
40
+ septagon
41
+ octagon
42
+ doublecircle
43
+ doubleoctagon
44
+ tripleoctagon
45
+ invtriangle
46
+ invtrapezium
47
+ invhouse
48
+ Mdiamond
49
+ Msquare
50
+ Mcircle
51
+ rect
52
+ rectangle
53
+ square
54
+ none
55
+ note
56
+ tab
57
+ folder
58
+ box3d
59
+ component
60
+ promoter
61
+ cds
62
+ terminator
63
+ utr
64
+ primersite
65
+ restrictionsite
66
+ fivepoverhang
67
+ threepoverhang
68
+ noverhang
69
+ assembly
70
+ signature
71
+ insulator
72
+ ribosite
73
+ rnastab
74
+ proteasesite
75
+ proteinstab
76
+ rpromoter
77
+ rarrow
78
+ larrow
79
+ lpromoter
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'gviz/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "gviz"
8
+ gem.version = Gviz::VERSION
9
+ gem.authors = ["kyoendo"]
10
+ gem.email = ["postagie@gmail.com"]
11
+ gem.description = %q{Ruby's interface of graphviz}
12
+ gem.summary = %q{Ruby's interface of graphviz. It generate a dot file with simple ruby's syntax. }
13
+ gem.homepage = "https://github.com/melborne/Gviz"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+ end
@@ -0,0 +1,211 @@
1
+ class Gviz
2
+ class Node < Struct.new(:id, :attrs)
3
+ def initialize(id, attrs={})
4
+ raise ArgumentError, "`id` must not include underscores" if id.match(/_/)
5
+ super
6
+ end
7
+
8
+ def to_s
9
+ "#{id}"
10
+ end
11
+ end
12
+
13
+ class Edge < Struct.new(:id, :attrs)
14
+ attr_reader :st, :ed, :seq, :st_port, :ed_port
15
+ def initialize(id, attrs={})
16
+ raise ArgumentError, "`attrs` must a hash" unless attrs.is_a?(Hash)
17
+ id, @st, @ed, @seq, @st_port, @ed_port = parse_id(id)
18
+ super(id, attrs)
19
+ end
20
+
21
+ def to_s
22
+ stp = ":#{st_port}" if st_port
23
+ edp = ":#{ed_port}" if ed_port
24
+ "#{st}#{stp} -> #{ed}#{edp}"
25
+ end
26
+
27
+ def nodes
28
+ [st, ed]
29
+ end
30
+
31
+ private
32
+ def parse_id(id)
33
+ st, ed, seq = "#{id}".split('_')
34
+ st, st_port = st.split(':').map(&:intern)
35
+ ed, ed_port = ed.split(':').map(&:intern)
36
+ id = (seq ? [st, ed, seq] : [st, ed]).join('_').intern
37
+ [id, st, ed, seq.to_i, st_port, ed_port]
38
+ end
39
+ end
40
+
41
+ attr_reader :gnode_attrs, :gedge_attrs, :graph_attrs, :subgraphs, :ranks
42
+ def initialize(name=:G, type=:digraph)
43
+ @name, @type = name, type
44
+ @edges = {}
45
+ @nodes = {}
46
+ @gnode_attrs = {}
47
+ @gedge_attrs = {}
48
+ @graph_attrs = {}
49
+ @subgraphs = []
50
+ @ranks = []
51
+ end
52
+
53
+ def nodeset
54
+ @nodes.values
55
+ end
56
+
57
+ def edgeset
58
+ @edges.values
59
+ end
60
+
61
+ def node(id, attrs={})
62
+ raise ArgumentError, '`id` must a symbol' unless id.is_a?(Symbol)
63
+ Node[id, attrs].tap do |node|
64
+ if exist = @nodes[node.id]
65
+ exist.attrs.update(node.attrs)
66
+ else
67
+ @nodes.update(node.id => node)
68
+ end
69
+ end
70
+ end
71
+
72
+ def edge(id, attrs={})
73
+ unless id.match(/._./)
74
+ raise ArgumentError, '`id` must a symbol in which node names joined with "_"'
75
+ end
76
+ Edge[id.intern, attrs].tap do |edge|
77
+ if exist = @edges[id.intern]
78
+ exist.attrs.update(edge.attrs)
79
+ else
80
+ @edges.update(edge.id => edge)
81
+ create_nodes
82
+ end
83
+ end
84
+ end
85
+
86
+ def nodes(attrs)
87
+ @gnode_attrs.update(attrs)
88
+ end
89
+
90
+ def edges(attrs)
91
+ @gedge_attrs.update(attrs)
92
+ end
93
+
94
+ def global(attrs)
95
+ @graph_attrs.update(attrs)
96
+ end
97
+
98
+ def subgraph(&blk)
99
+ Gviz.new("cluster#{subgraphs.size}", :subgraph).tap do |graph|
100
+ subgraphs << graph
101
+ graph.instance_eval &blk
102
+ end
103
+ end
104
+
105
+ def graph(&blk)
106
+ instance_eval(&blk)
107
+ self
108
+ end
109
+
110
+ def add(*nodes_or_routes)
111
+ nodes_or_routes.each do |unit|
112
+ case unit
113
+ when Hash
114
+ unit.each do |sts, eds|
115
+ Array(sts).product(Array(eds))
116
+ .each { |st, ed| edge([st,ed].join('_').intern) }
117
+ end
118
+ when Symbol
119
+ node(unit)
120
+ else
121
+ raise ArgumentError, 'pass nodes in symbol or edges in hash'
122
+ end
123
+ end
124
+ self
125
+ end
126
+ alias :route :add
127
+
128
+ def rank(type, *nodes)
129
+ types = [:same, :min, :max, :source, :sink]
130
+ unless types.include?(type)
131
+ raise ArgumentError, "type must match any of #{types.join(', ')}"
132
+ end
133
+ @ranks << [type, nodes]
134
+ end
135
+
136
+ def to_s
137
+ result = []
138
+ tabs = " "
139
+ result << "#{@type} #{@name} {"
140
+
141
+ unless graph_attrs.empty?
142
+ result << tabs + build_attrs(graph_attrs, false).join(";\n#{tabs}") + ";"
143
+ end
144
+
145
+ unless gnode_attrs.empty?
146
+ result << tabs + "node#{build_attrs(gnode_attrs)};"
147
+ end
148
+
149
+ unless gedge_attrs.empty?
150
+ result << tabs + "edge#{build_attrs(gedge_attrs)};"
151
+ end
152
+
153
+ @nodes.values.each do |node|
154
+ result << tabs + "#{node.id}#{build_attrs(node.attrs)};"
155
+ end
156
+
157
+ @edges.values.each do |edge|
158
+ result << tabs + "#{edge}#{build_attrs(edge.attrs)};"
159
+ end
160
+
161
+ subgraphs.each do |graph|
162
+ graph.to_s.lines do |line|
163
+ result << tabs + line.chomp
164
+ end
165
+ end
166
+
167
+ @ranks.each do |type, nodes|
168
+ result << tabs + "{ rank=#{type}; #{nodes.join('; ')}; }"
169
+ end
170
+
171
+ result << "}\n"
172
+ result.join("\n")
173
+ end
174
+
175
+ def save(path, type=nil)
176
+ File.open("#{path}.dot", "w") { |f| f.puts self }
177
+ system "dot -T#{type} #{path}.dot -o #{path}.#{type}" if type
178
+ end
179
+
180
+ private
181
+ def create_nodes
182
+ # only create unregistered nodes
183
+ ids = @edges.values.flat_map(&:nodes).uniq - @nodes.keys
184
+ ids.each { |id| node(id) }
185
+ @nodes
186
+ end
187
+
188
+ def build_attrs(attrs, join=true)
189
+ return nil if attrs.empty?
190
+ arr = attrs.map { |k, v| %(#{k}="#{v}").gsub("\n", "\\n") }
191
+ join ? '[' + arr.join(',') + ']' : arr
192
+ end
193
+ end
194
+
195
+ if __FILE__ == $0
196
+ g = Gviz.new
197
+ g.graph do
198
+ add(:main => [:printf, :parse, :init, :cleanup])
199
+ add(:parse => :execute, :init => :make)
200
+ add(:execute => [:printf, :compare, :make])
201
+ node(:main, :shape => 'box')
202
+ node(:make, :label => "make a\nstring")
203
+ node(:compare, :shape => 'box', :style => 'filled', :color => ".7 .3 1.0")
204
+ edge(:main_parse, :weight => 8)
205
+ edge(:main_init, :style => 'dotted')
206
+ edge(:main_printf, :style => 'bold', :label => "100 times", :color => 'red')
207
+ edge(:execute_compare, :color => 'red')
208
+ end
209
+ puts g
210
+ end
211
+