bio-svgenes 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +2 -1
- data/Gemfile.lock +3 -1
- data/VERSION +1 -1
- data/bio-svgenes.gemspec +8 -15
- data/lib/bio/graphics/glyph.rb +149 -16
- data/lib/bio/graphics/mini_feature.rb +23 -0
- data/lib/bio/graphics/page.rb +315 -262
- data/lib/bio/graphics/primitive.rb +12 -3
- data/lib/bio/graphics/svgee.rb +19 -6
- data/lib/bio/graphics/track.rb +14 -5
- metadata +21 -15
- data/.DS_Store +0 -0
- data/doc/.DS_Store +0 -0
- data/doc/Bio/.DS_Store +0 -0
- data/examples/.DS_Store +0 -0
- data/examples/drawn_from_json.svg +0 -269
- data/examples/drawn_from_json2.svg +0 -467
- data/lib/.DS_Store +0 -0
- data/lib/bio/.DS_Store +0 -0
- data/test/gene.gff +0 -4
- data/test/test_bio-svgenes.rb +0 -7
data/Gemfile
CHANGED
@@ -7,8 +7,9 @@ source "http://rubygems.org"
|
|
7
7
|
# Include everything needed to run rake, tests, features, etc.
|
8
8
|
group :development do
|
9
9
|
gem "shoulda", ">= 0"
|
10
|
-
gem "bundler", "
|
10
|
+
gem "bundler", ">= 1.0.0"
|
11
11
|
gem "jeweler", "~> 1.6.4"
|
12
12
|
gem "rcov", ">= 0"
|
13
13
|
gem "bio", ">= 1.4.2"
|
14
|
+
gem "json", ">=1.7"
|
14
15
|
end
|
data/Gemfile.lock
CHANGED
@@ -7,6 +7,7 @@ GEM
|
|
7
7
|
bundler (~> 1.0)
|
8
8
|
git (>= 1.2.5)
|
9
9
|
rake
|
10
|
+
json (1.7.7)
|
10
11
|
rake (0.9.2.2)
|
11
12
|
rcov (0.9.11)
|
12
13
|
shoulda (2.11.3)
|
@@ -16,7 +17,8 @@ PLATFORMS
|
|
16
17
|
|
17
18
|
DEPENDENCIES
|
18
19
|
bio (>= 1.4.2)
|
19
|
-
bundler (
|
20
|
+
bundler (>= 1.0.0)
|
20
21
|
jeweler (~> 1.6.4)
|
22
|
+
json (>= 1.7)
|
21
23
|
rcov
|
22
24
|
shoulda
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.1
|
data/bio-svgenes.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "bio-svgenes"
|
8
|
-
s.version = "0.3.
|
8
|
+
s.version = "0.3.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Dan MacLean"]
|
12
|
-
s.date = "2013-03-
|
12
|
+
s.date = "2013-03-05"
|
13
13
|
s.description = "This bio-gem facilitates the creation of pretty, publication quality SVG images from feature data."
|
14
14
|
s.email = "maclean.daniel@gmail.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -17,7 +17,6 @@ Gem::Specification.new do |s|
|
|
17
17
|
"README.rdoc"
|
18
18
|
]
|
19
19
|
s.files = [
|
20
|
-
".DS_Store",
|
21
20
|
".document",
|
22
21
|
"Gemfile",
|
23
22
|
"Gemfile.lock",
|
@@ -26,9 +25,7 @@ Gem::Specification.new do |s|
|
|
26
25
|
"Rakefile",
|
27
26
|
"VERSION",
|
28
27
|
"bio-svgenes.gemspec",
|
29
|
-
"doc/.DS_Store",
|
30
28
|
"doc/Bio.html",
|
31
|
-
"doc/Bio/.DS_Store",
|
32
29
|
"doc/Bio/Graphics.html",
|
33
30
|
"doc/Bio/Graphics/Glyph.html",
|
34
31
|
"doc/Bio/Graphics/MiniFeature.html",
|
@@ -72,12 +69,9 @@ Gem::Specification.new do |s|
|
|
72
69
|
"doc/js/searcher.js",
|
73
70
|
"doc/rdoc.css",
|
74
71
|
"doc/table_of_contents.html",
|
75
|
-
"examples/.DS_Store",
|
76
72
|
"examples/annotate_snps.rb",
|
77
73
|
"examples/data.txt",
|
78
74
|
"examples/draw_from_json.rb",
|
79
|
-
"examples/drawn_from_json.svg",
|
80
|
-
"examples/drawn_from_json2.svg",
|
81
75
|
"examples/eg2.rb",
|
82
76
|
"examples/example.rb",
|
83
77
|
"examples/example.svg",
|
@@ -86,19 +80,15 @@ Gem::Specification.new do |s|
|
|
86
80
|
"examples/get_coverage_in_windows.rb",
|
87
81
|
"examples/make_example.rb",
|
88
82
|
"examples/transcripts.gff",
|
89
|
-
"lib/.DS_Store",
|
90
83
|
"lib/bio-svgenes.rb",
|
91
|
-
"lib/bio/.DS_Store",
|
92
84
|
"lib/bio/graphics/glyph.rb",
|
93
85
|
"lib/bio/graphics/mini_feature.rb",
|
94
86
|
"lib/bio/graphics/page.rb",
|
95
87
|
"lib/bio/graphics/primitive.rb",
|
96
88
|
"lib/bio/graphics/svgee.rb",
|
97
89
|
"lib/bio/graphics/track.rb",
|
98
|
-
"test/gene.gff",
|
99
90
|
"test/helper.rb",
|
100
91
|
"test/json_config.json",
|
101
|
-
"test/test_bio-svgenes.rb",
|
102
92
|
"test/test_glyph.rb",
|
103
93
|
"test/test_mini_feature.rb",
|
104
94
|
"test/test_page.rb",
|
@@ -118,23 +108,26 @@ Gem::Specification.new do |s|
|
|
118
108
|
|
119
109
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
120
110
|
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
121
|
-
s.add_development_dependency(%q<bundler>, ["
|
111
|
+
s.add_development_dependency(%q<bundler>, [">= 1.0.0"])
|
122
112
|
s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
|
123
113
|
s.add_development_dependency(%q<rcov>, [">= 0"])
|
124
114
|
s.add_development_dependency(%q<bio>, [">= 1.4.2"])
|
115
|
+
s.add_development_dependency(%q<json>, [">= 1.7"])
|
125
116
|
else
|
126
117
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
127
|
-
s.add_dependency(%q<bundler>, ["
|
118
|
+
s.add_dependency(%q<bundler>, [">= 1.0.0"])
|
128
119
|
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
129
120
|
s.add_dependency(%q<rcov>, [">= 0"])
|
130
121
|
s.add_dependency(%q<bio>, [">= 1.4.2"])
|
122
|
+
s.add_dependency(%q<json>, [">= 1.7"])
|
131
123
|
end
|
132
124
|
else
|
133
125
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
134
|
-
s.add_dependency(%q<bundler>, ["
|
126
|
+
s.add_dependency(%q<bundler>, [">= 1.0.0"])
|
135
127
|
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
136
128
|
s.add_dependency(%q<rcov>, [">= 0"])
|
137
129
|
s.add_dependency(%q<bio>, [">= 1.4.2"])
|
130
|
+
s.add_dependency(%q<json>, [">= 1.7"])
|
138
131
|
end
|
139
132
|
end
|
140
133
|
|
data/lib/bio/graphics/glyph.rb
CHANGED
@@ -1,10 +1,39 @@
|
|
1
1
|
module Bio
|
2
2
|
class Graphics
|
3
|
+
#A Glyph is an array of Primitive objects, holding information about the type of Glyph being created.
|
4
|
+
#Each different type of Glyph has different arguments, pertaining to how the Glyph will be drawn and the parameters provided to SVGEE.
|
5
|
+
#
|
6
|
+
|
3
7
|
class Glyph
|
4
|
-
|
8
|
+
|
9
|
+
#The different type of Glyphs are:
|
10
|
+
#* generic
|
11
|
+
#* circle
|
12
|
+
#* directed
|
13
|
+
#* \down_triangle
|
14
|
+
#* \up_triangle
|
15
|
+
#* span
|
16
|
+
#* transcript
|
17
|
+
#* scale
|
18
|
+
#* label
|
19
|
+
#* histogram
|
20
|
+
|
21
|
+
attr_reader :glyphs
|
5
22
|
#holds a load of definitions for glyphs .. a glyph is an array of primitives...
|
6
23
|
@glyphs = [:generic, :directed, :transcript, :scale, :label, :histogram, :circle, :down_triangle, :up_triangle, :span]
|
7
|
-
|
24
|
+
#Creates a generic glyph, which is a rectangle
|
25
|
+
#
|
26
|
+
#+args+
|
27
|
+
#* height = the height of the Glyph (10)
|
28
|
+
#* fill_color = the fill colour of the Glyph ('red')
|
29
|
+
#* stroke = the outline colour of the Glyph ("black")
|
30
|
+
#* stroke_width = The width of the outline stroke (1)
|
31
|
+
#* x_round = x-axis radius of the ellipse used to round off the corners of the rectangle (1)
|
32
|
+
#* y_round = y-axis radius of the ellipse used to round off the corners of the rectangle (1)
|
33
|
+
#* style = the opacity of the fill color ("fill-opacity:0.4;")
|
34
|
+
#* x = the co-ordinates of the Glyph for the x-axis
|
35
|
+
#* y = the co-ordinates of the Glyph for the y-axis
|
36
|
+
|
8
37
|
def self.generic(args) #:x, :y, :width :fill, :stroke :stroke_width, :style, :height,
|
9
38
|
args = {
|
10
39
|
:height => 10,
|
@@ -15,8 +44,19 @@ class Glyph
|
|
15
44
|
:y_round => 1,
|
16
45
|
:style => "fill-opacity:0.4;"}.merge!(args)
|
17
46
|
[Bio::Graphics::Primitive.new(:rectangle, args)]
|
18
|
-
end
|
19
|
-
|
47
|
+
end
|
48
|
+
|
49
|
+
#Creates a circular Glyph
|
50
|
+
#
|
51
|
+
#+args+
|
52
|
+
#* radius = the radius of the circle (10)
|
53
|
+
#* fill_color = the fill colour of the Glyph ('red')
|
54
|
+
#* stroke = the outline colour of the Glyph ("black")
|
55
|
+
#* stroke_width = The width of the outline stroke (1)
|
56
|
+
#* style = the opacity of the fill color
|
57
|
+
#* x = x-axis centre of the circle
|
58
|
+
#* y = y-axis centre of the circle
|
59
|
+
|
20
60
|
def self.circle(args)
|
21
61
|
args = {
|
22
62
|
:radius => 10,
|
@@ -30,7 +70,18 @@ class Glyph
|
|
30
70
|
[Bio::Graphics::Primitive.new(:circle, args)]
|
31
71
|
end
|
32
72
|
|
33
|
-
|
73
|
+
#Creates a polygon Glyph to indicate the direction in which the Glyph is pointing
|
74
|
+
#+args+
|
75
|
+
#* width = the width of the feature
|
76
|
+
#* fill_color = the fill colour of the Glyph ('red')
|
77
|
+
#* stroke = the outline colour of the Glyph ("black")
|
78
|
+
#* stroke_width = The width of the outline stroke (1)
|
79
|
+
#* style = the opacity of the fill color
|
80
|
+
#* strand = the strand on which the Glyph is located. May be '+' or '-'
|
81
|
+
#* points = the x and y axis points used to calculate the shape of the polygon
|
82
|
+
#* x = the co-ordinates of the Glyph for the x-axis
|
83
|
+
#* y = the co-ordinates of the Glyph for the y-axis
|
84
|
+
#The points of the polygon are calculated form the +x+ and +y+ co-ordinates
|
34
85
|
def self.directed(args) #:x, :y, :width :fill, :stroke :stroke_width, :style, :height
|
35
86
|
args = {
|
36
87
|
|
@@ -43,11 +94,22 @@ class Glyph
|
|
43
94
|
if args[:strand] == '-'
|
44
95
|
args[:points] = "#{args[:x]},#{args[:y]} #{args[:x] + args[:width]},#{args[:y]} #{args[:x] + args[:width]},#{args[:y] + args[:height] } #{args[:x]},#{args[:y] + (args[:height])} #{args[:x] - (args[:height] * 0.2)},#{args[:y] + (args[:height]/2)}"
|
45
96
|
else
|
46
|
-
args[:points] = "#{args[:x]},#{args[:y]} #{args[:x] + args[:width] - (args[:height] * 0.2)},#{args[:y]} #{args[:x] + args[:width]},#{args[:y] + (args[:height]/2) } #{args[:x] + args[:width] - (args[:height] * 0.2)},#{args[:y] + args[:height]} #{args[:x]},#{args[:y] + args[:height]}"
|
97
|
+
args[:points] = "#{args[:x]},#{args[:y]} #{args[:x] + args[:width] - (args[:height] * 0.2)},#{args[:y]} #{args[:x] + args[:width]},#{args[:y] + (args[:height]/2) } #{args[:x] + args[:width] - (args[:height] * 0.2)},#{args[:y] + args[:height]} #{args[:x]},#{args[:y] + args[:height]}"
|
98
|
+
|
47
99
|
end
|
48
100
|
[Bio::Graphics::Primitive.new(:polygon, args)]
|
49
101
|
end
|
50
|
-
|
102
|
+
#Creates a polygon Glyph for a downward-pointing triangle
|
103
|
+
#+args+
|
104
|
+
#* height = the height of the Glyph (10)
|
105
|
+
#* fill_color = the fill colour of the Glyph ('red')
|
106
|
+
#* stroke = the outline colour of the Glyph ("black")
|
107
|
+
#* stroke_width = The width of the outline stroke (1)
|
108
|
+
#* style = the opacity of the fill color ("fill-opacity:0.4;")
|
109
|
+
#* x = the co-ordinates of the Glyph for the x-axis
|
110
|
+
#* y = the co-ordinates of the Glyph for the y-axis
|
111
|
+
#The points of the triangle are calculated form the +x+ and +y+ co-ordinates
|
112
|
+
|
51
113
|
def self.down_triangle(args) #:x, :y, :width :fill, :stroke :stroke_width, :style, :height
|
52
114
|
args = {
|
53
115
|
|
@@ -56,10 +118,21 @@ class Glyph
|
|
56
118
|
:stroke => "black",
|
57
119
|
:stroke_width => 1,
|
58
120
|
:style => "fill-opacity:0.4;"}.merge!(args)
|
121
|
+
|
59
122
|
args[:points] = "#{args[:x]},#{args[:y]} #{args[:x] + args[:width]},#{args[:y]} #{ args[:x] + (args[:width]/2) },#{(args[:y] + args[:height]) }"
|
60
123
|
[Bio::Graphics::Primitive.new(:polygon, args)]
|
61
124
|
end
|
62
|
-
|
125
|
+
#Creates a polygon Glyph for an upward-pointing triangle
|
126
|
+
#+args+
|
127
|
+
#* height = the height of the Glyph (10)
|
128
|
+
#* fill_color = the fill colour of the Glyph ('red')
|
129
|
+
#* stroke = the outline colour of the Glyph ("black")
|
130
|
+
#* stroke_width = The width of the outline stroke (1)
|
131
|
+
#* style = the opacity of the fill color ("fill-opacity:0.4;")
|
132
|
+
#* x = the co-ordinates of the Glyph for the x-axis
|
133
|
+
#* y = the co-ordinates of the Glyph for the y-axis
|
134
|
+
#The points of the triangle are calculated form the +x+ and +y+ co-ordinates
|
135
|
+
|
63
136
|
def self.up_triangle(args) #:x, :y, :width :fill, :stroke :stroke_width, :style, :height
|
64
137
|
args = {
|
65
138
|
:height => 10,
|
@@ -70,7 +143,16 @@ class Glyph
|
|
70
143
|
args[:points] = "#{args[:x]},#{args[:y] + args[:height]} #{args[:x] + args[:width]},#{args[:y] + args[:height]} #{ args[:x] + (args[:width]/2) },#{args[:y] }"
|
71
144
|
[Bio::Graphics::Primitive.new(:polygon, args)]
|
72
145
|
end
|
73
|
-
|
146
|
+
#Creates a span glyph, which is a line
|
147
|
+
#
|
148
|
+
#+args+
|
149
|
+
#* height = the height of the Glyph (10)
|
150
|
+
#* fill_color = the fill colour of the Glyph ('red')
|
151
|
+
#* stroke = the outline colour of the Glyph ("black")
|
152
|
+
#* stroke_width = The width of the outline stroke (1)
|
153
|
+
#* style = the opacity of the fill color ("fill-opacity:0.4;")
|
154
|
+
#* x = the co-ordinates of the Glyph for the x-axis
|
155
|
+
#* y = the co-ordinates of the Glyph for the y-axis
|
74
156
|
def self.span(args)
|
75
157
|
args = {
|
76
158
|
:height => 10,
|
@@ -85,7 +167,26 @@ class Glyph
|
|
85
167
|
args[:y2] = args[:y]
|
86
168
|
[Bio::Graphics::Primitive.new(:line, args)]
|
87
169
|
end
|
88
|
-
|
170
|
+
#Creates a transcript glyph, which is a number of different types of Glyph, depending on the features
|
171
|
+
#within the transcript
|
172
|
+
#
|
173
|
+
#+args+
|
174
|
+
#* height = the height of the Glyph (10)
|
175
|
+
#* utr_fill_color = the fill colour of the Glyph ('black')
|
176
|
+
#* utr_stroke = the outline colour of the Glyph ("black")
|
177
|
+
#* utr_stroke_width = The width of the outline stroke (1)
|
178
|
+
#* exon_fill_color = the fill colour of the Glyph ('red')
|
179
|
+
#* exon_stroke = the outline colour of the Glyph ("black")
|
180
|
+
#* exon_stroke_width = The width of the outline stroke (1)
|
181
|
+
#* line_color = the colour for any line Glyphs
|
182
|
+
#* line_width = the width for any line Glyphs
|
183
|
+
#* exon_style = the opacity of the fill color for exons ("fill-opacity:0.4;")
|
184
|
+
#* utr_style = the opacity of the fill color for utrs
|
185
|
+
#* line_style = the opacity of the fill color for lines
|
186
|
+
#* block_gaps = ****I'm not sure what these are****
|
187
|
+
#* gap_marker = ****I'm not sure what these are****
|
188
|
+
#* x = the co-ordinates of the Glyph for the x-axis
|
189
|
+
#* y = the co-ordinates of the Glyph for the y-axis
|
89
190
|
def self.transcript(args)
|
90
191
|
args = {
|
91
192
|
:height => 10,
|
@@ -178,10 +279,19 @@ class Glyph
|
|
178
279
|
end
|
179
280
|
composite
|
180
281
|
end
|
181
|
-
|
282
|
+
#Creates the scale across the top of the SVG page
|
283
|
+
#
|
284
|
+
#+args+
|
285
|
+
#* start = the start of the scale
|
286
|
+
#* stop = the end of the scale
|
287
|
+
#* \number_of_intervals = the number of tick-marks on the scale to show the current position
|
288
|
+
#* page_width = the width of the page
|
289
|
+
#
|
290
|
+
#+returns+
|
291
|
+
#
|
292
|
+
#* An Array[http://www.ruby-doc.org/core-2.0/Array.html] of Primitive objects (of type 'line', 'rectangle' and 'text')
|
293
|
+
|
182
294
|
def self.scale(args)
|
183
|
-
|
184
|
-
|
185
295
|
first_mark = args[:start]
|
186
296
|
last_mark = args[:stop]
|
187
297
|
#(num.to_f / @nt_per_px_x.to_f)
|
@@ -217,7 +327,15 @@ class Glyph
|
|
217
327
|
end
|
218
328
|
return a
|
219
329
|
end
|
220
|
-
|
330
|
+
#Creates a label Glyph to write text
|
331
|
+
#
|
332
|
+
#+args+
|
333
|
+
#* text = the text to write
|
334
|
+
#* fill = the colour of the text ("black")
|
335
|
+
#* style = the style of writing ("font-family:monospace;")
|
336
|
+
#* x = the co-ordinates of the Glyph for the x-axis
|
337
|
+
#* y = the co-ordinates of the Glyph for the y-axis
|
338
|
+
|
221
339
|
def self.label(args)
|
222
340
|
[Bio::Graphics::Primitive.new(:text,
|
223
341
|
:text => args[:text],
|
@@ -226,11 +344,26 @@ class Glyph
|
|
226
344
|
:fill => "black",
|
227
345
|
:style => "font-family:monospace;")]
|
228
346
|
end
|
229
|
-
|
347
|
+
#The list of pre-defined gradients
|
230
348
|
def self.gradients #needs to know which of its gradients are predefined
|
231
349
|
[:red_white_h, :green_white_h, :blue_white_h, :yellow_white_h, :red_white_radial, :green_white_radial, :blue_white_radial, :yellow_white_radial ]
|
232
350
|
end
|
233
|
-
|
351
|
+
|
352
|
+
#Sets the the type (linear or radial) and colour of gradient for a pre-defined gradient
|
353
|
+
#along with the pertinent parameters for that type
|
354
|
+
#
|
355
|
+
#+args+
|
356
|
+
#* gradient = a pre-defined gradient
|
357
|
+
#The types of gradient are:
|
358
|
+
#* red_white_h
|
359
|
+
#* green_white_h
|
360
|
+
#* blue_white_h
|
361
|
+
#* yellow_white_h
|
362
|
+
#* red_white_radial
|
363
|
+
#* green_white_radial
|
364
|
+
#* blue_white_radial
|
365
|
+
#* yellow_white_radial
|
366
|
+
|
234
367
|
def self.gradient(gradient)
|
235
368
|
type, color = case gradient
|
236
369
|
when :red_white_h
|
@@ -1,7 +1,30 @@
|
|
1
1
|
module Bio
|
2
2
|
class Graphics
|
3
|
+
##
|
4
|
+
#The MiniFeature class represents any feature (e.g. a gene, transcript, exon, start codon, etc) on a track.
|
5
|
+
#
|
3
6
|
class MiniFeature
|
4
7
|
attr_accessor :start, :end, :strand, :exons, :utrs, :block_gaps, :segment_height, :id
|
8
|
+
#Creates a new MiniFeature
|
9
|
+
#
|
10
|
+
#_Arguments_
|
11
|
+
#* start = the start position of the feature
|
12
|
+
#* end = the end position of the feature
|
13
|
+
#* strand = the strand of the feature
|
14
|
+
#* exons = an array of exon positions
|
15
|
+
#* utrs = an array of utrs positions
|
16
|
+
#* \block_gaps = an array of regions with nothing to be drawn, e.g. introns
|
17
|
+
#* id = the name of the feature such as the gene name or transcript ID
|
18
|
+
#* \segment_height = the height of the current feature
|
19
|
+
#
|
20
|
+
#==Example usage
|
21
|
+
#
|
22
|
+
##@mini1 = Bio::Graphics::MiniFeature.new(:start=>3631, :end=>5899, :strand=>'+',
|
23
|
+
# :exons=>[4000, 4500, 4700, 5000], :utrs=>[3631, 3650], :segment_height=>5, :id=>"AT1G01010")
|
24
|
+
#
|
25
|
+
#===MiniFeatures and Tracks
|
26
|
+
#MiniFeatures are added to Track objects, with overlapping MiniFeatures being placed onto separate rows
|
27
|
+
#
|
5
28
|
def initialize(args)
|
6
29
|
@start = args[:start]
|
7
30
|
@end = args[:end]
|
data/lib/bio/graphics/page.rb
CHANGED
@@ -1,290 +1,343 @@
|
|
1
1
|
module Bio
|
2
2
|
class Graphics
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
3
|
+
|
4
|
+
##
|
5
|
+
#The Page class represents the top level container on which svg objects are written. It will contain a scale
|
6
|
+
#and all the tracks along with their features. The scale will start at the genomic co-ordinates of the start
|
7
|
+
#of the first feature and stop at the end of the last feature)
|
8
|
+
#
|
9
|
+
|
10
|
+
|
11
|
+
class Page
|
12
|
+
#Creates a new Page object.
|
13
|
+
#
|
14
|
+
#A new Page contains the following arguments:
|
15
|
+
#* height = the height of the page
|
16
|
+
#* width = the width of the page
|
17
|
+
#* style = includes the a background colour
|
18
|
+
#* svg = a new SVGEE object
|
19
|
+
#* scale_start = the scale-start of the page (1.0/0.0)
|
20
|
+
#* scale_stop = the scale-stop of the page (-1.0/0.0)
|
21
|
+
#* tracks = an array of track objects with loads of features in it...
|
22
|
+
#* nt_per_percent = the number of nucleotides that are represented by 1% of the page (1);
|
23
|
+
#* num_intervals = the number of intervals
|
24
|
+
#* track_top = the position of the top of the first track (30)
|
25
|
+
#
|
26
|
+
#A new page maybe set up as follows:
|
27
|
+
# @page = Bio::Graphics::Page.new(:width => 800,
|
28
|
+
# :height => 110, :number_of_intervals => 10)
|
29
|
+
#
|
30
|
+
def initialize(args)
|
31
|
+
@height = args[:height]
|
32
|
+
@width = args[:width]
|
33
|
+
args[:style] = "background-color:#{args[:background_color]};" if args[:background_color]
|
34
|
+
@svg = SVGEE.new(args)
|
35
|
+
@scale_start = 1.0/0.0
|
36
|
+
@scale_stop = -1.0/0.0
|
37
|
+
@tracks = [] #array of track objects with loads of features in it...
|
38
|
+
@nt_per_percent = 1;
|
39
|
+
@num_intervals = args[:number_of_intervals]
|
40
|
+
@track_top = 30
|
41
|
+
|
42
|
+
def @svg.update_height(height)
|
43
|
+
@height = height
|
44
|
+
end
|
45
|
+
|
46
|
+
#def @svg.update_width(width)
|
47
|
+
# @width = width
|
48
|
+
#end
|
43
49
|
end
|
50
|
+
#Takes a custom-written json file and writes an svg page to file which will contain the given features described within the json file.
|
51
|
+
#* +args+ - a custom-written json file describing the parameters and resources needed for a new page
|
44
52
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
end
|
53
|
+
def self.from_json(args)
|
54
|
+
require 'rubygems'
|
55
|
+
require 'json'
|
56
|
+
data = JSON.parse(File.open(args[:json], 'r').read)
|
57
|
+
p = Page.new(:width => data["Page"]["width"],
|
58
|
+
:height => data["Page"]["height"],
|
59
|
+
:number_of_intervals => data["Page"]["intervals"])
|
60
|
+
data["Tracks"].each do |track|
|
61
|
+
#prep the track args
|
62
|
+
track_args = track.dup
|
63
|
+
track_args.delete("file")
|
64
|
+
track_args.delete("file_type")
|
65
|
+
track_args = track_args.inject({}) { |memo, (k, v)| memo[k.to_sym] = v; memo }
|
66
|
+
##convert any of the pre-made gradient strings in the keys to symbol
|
67
|
+
track_args.each_key do |k|
|
68
|
+
next unless track_args[k].respond_to?(:to_sym)
|
69
|
+
track_args[k] = track_args[k].to_sym if Glyph.gradients.include?(track_args[k].to_sym)
|
63
70
|
end
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
71
|
+
|
72
|
+
svg_track = p.add_track(track_args)
|
73
|
+
features = [] ##set up the features...
|
74
|
+
|
75
|
+
case track["file_type"] ##deal with the gff and data files
|
76
|
+
when "gff"
|
77
|
+
groups = {}
|
78
|
+
parentless_features = []
|
79
|
+
Page.parse_gff(track["file"]).each do |gff| #gets features in a list and links their children to them as members of the array at the key
|
80
|
+
parent_id = gff.attributes.select { |a| a.first == 'Parent' }
|
81
|
+
if parent_id.empty?
|
82
|
+
parentless_features << gff
|
83
|
+
else
|
84
|
+
if groups[parent_id.first.last].nil?
|
85
|
+
groups[parent_id.first.last] = []
|
86
|
+
groups[parent_id.first.last] << gff
|
87
|
+
else
|
88
|
+
groups[parent_id.first.last] << gff
|
89
|
+
end
|
90
|
+
end
|
79
91
|
end
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
92
|
+
#now flick through the parentless features and add any exons / UTRs
|
93
|
+
parentless_features.each do |plf|
|
94
|
+
require 'pp'
|
95
|
+
#pp parentless_features
|
96
|
+
gff_id = plf.attributes.select { |a| a.first == 'ID' }
|
97
|
+
gff_id = gff_id.first.last
|
98
|
+
exons = []
|
99
|
+
utrs = []
|
100
|
+
children = groups[gff_id] || children = []
|
101
|
+
children.each do |child|
|
102
|
+
if child.feature == 'exon' or child.feature == 'CDS'
|
103
|
+
exons += [child.start, child.end]
|
104
|
+
elsif child.feature =~ /utr/i
|
105
|
+
utrs += [child.start, child.end]
|
106
|
+
end
|
107
|
+
end
|
108
|
+
features << MiniFeature.new(:start => plf.start, :end => plf.end, :exons => exons, :utrs => utrs, :strand => plf.strand, :id => gff_id)
|
109
|
+
end #parentless features end
|
110
|
+
when "data"
|
111
|
+
##each line is a data feature
|
112
|
+
File.open(track["file"], "r").each do |line|
|
113
|
+
start, stop, value = line.split(/\t/)
|
114
|
+
features << MiniFeature.new(:start => start.to_i, :end => stop.to_i, :segment_height => value.to_f)
|
115
|
+
end
|
116
|
+
end #data end
|
117
|
+
features.each { |f| svg_track.add(f) }
|
118
|
+
end #track end
|
119
|
+
p.write(args[:outfile])
|
120
|
+
end
|
121
|
+
|
122
|
+
#Parses a GFF file into an Array of Bio::GFF::GFF3::Record[http://bioruby.org/rdoc/Bio/GFF/GFF3/Record.html] objects
|
123
|
+
#* +gff_file+ - a GFF-formatted file
|
124
|
+
#* +returns+ - an Array of Bio::GFF::GFF3::Record[http://bioruby.org/rdoc/Bio/GFF/GFF3/Record.html] objects
|
125
|
+
def self.parse_gff(gff_file)
|
126
|
+
require 'bio'
|
127
|
+
a = []
|
128
|
+
File.open(gff_file).each do |line|
|
129
|
+
next if line =~ /^#/
|
130
|
+
a << Bio::GFF::GFF3::Record.new(line)
|
88
131
|
end
|
89
|
-
|
90
|
-
features.each {|f| svg_track.add(f) }
|
91
|
-
end #track end
|
92
|
-
p.write(args[:outfile])
|
93
|
-
end
|
94
|
-
|
95
|
-
def self.parse_gff(gff_file)
|
96
|
-
require 'bio'
|
97
|
-
a = []
|
98
|
-
File.open( gff_file ).each do |line|
|
99
|
-
next if line =~ /^#/
|
100
|
-
a << Bio::GFF::GFF3::Record.new(line)
|
101
|
-
end
|
102
|
-
a
|
103
|
-
end
|
104
|
-
|
105
|
-
def add_track(args)
|
106
|
-
#sort out the colour/gradient options
|
107
|
-
[:fill_color, :exon_fill_color, :utr_fill_color].each do |colour_tag|
|
108
|
-
if Glyph.gradients.include?(args[colour_tag])
|
109
|
-
@svg.gradient(Glyph.gradient(args[colour_tag]) )
|
110
|
-
args[colour_tag] = "url(##{args[colour_tag]})"
|
111
|
-
elsif
|
112
|
-
args[colour_tag].instance_of?(Hash)
|
113
|
-
@svg.gradient(args[colour_tag])
|
114
|
-
args[colour_tag] = "url(##{args[colour_tag][:id]})"
|
132
|
+
a
|
115
133
|
end
|
116
|
-
end
|
117
|
-
@tracks << Track.new(args)
|
118
|
-
return @tracks.last
|
119
|
-
end
|
120
|
-
|
121
|
-
def get_limits
|
122
|
-
@tracks.each do |track|
|
123
|
-
lowest = track.features.sort {|x,y| x.start <=> y.start}.first.start
|
124
|
-
highest = track.features.sort {|x,y| y.end <=> x.end}.first.end
|
125
|
-
@scale_start = lowest if lowest < @scale_start
|
126
|
-
@scale_stop = highest if highest > @scale_stop
|
127
|
-
@nt_per_px_x = (@scale_stop - @scale_start).to_f / @width.to_f
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
def draw_scale
|
132
|
-
Glyph.scale(:start => @scale_start,
|
133
|
-
:stop => @scale_stop,
|
134
|
-
:number_of_intervals => @num_intervals, :page_width => @width).each {|g| @svg.add_primitive(g)}
|
135
|
-
end
|
136
|
-
|
137
|
-
def draw_label(args)
|
138
|
-
Glyph.label(:text => args[:text],
|
139
|
-
:x => args[:x],
|
140
|
-
:y => args[:y] ).each {|g| @svg.add_primitive(g)}
|
141
|
-
end
|
142
|
-
|
143
|
-
def draw_generic(args) #remember presentation info comes from track@args when the track is defined
|
144
|
-
Glyph.generic(args).each {|g| @svg.add_primitive(g) }
|
145
|
-
end
|
146
|
-
|
147
|
-
def draw_directed(args)
|
148
|
-
Glyph.directed(args).each {|g| @svg.add_primitive(g) }
|
149
|
-
end
|
150
|
-
|
151
|
-
def draw_circle(args)
|
152
|
-
Glyph.circle(args).each {|g| @svg.add_primitive(g) }
|
153
|
-
end
|
154
|
-
|
155
|
-
def draw_transcript(args)
|
156
|
-
Glyph.transcript(args).each {|g| @svg.add_primitive(g) }
|
157
|
-
end
|
158
|
-
|
159
|
-
def draw_histogram(args)
|
160
|
-
Glyph.generic(args).each {|g| @svg.add_primitive(g) }
|
161
|
-
end
|
162
|
-
|
163
|
-
def draw_up_triangle(args)
|
164
|
-
Glyph.up_triangle(args).each {|g| @svg.add_primitive(g) }
|
165
|
-
end
|
166
134
|
|
167
|
-
|
168
|
-
|
169
|
-
|
135
|
+
#Calculates the colour or gradient for the supplied Bio::Graphics::Track objects and adds them to the Track array for the current Page
|
136
|
+
#* +args+ - an Array of Bio::Graphics::Track objects
|
137
|
+
#* +returns+ - the last element of the Track array
|
138
|
+
def add_track(args)
|
139
|
+
#sort out the colour/gradient options
|
140
|
+
[:fill_color, :exon_fill_color, :utr_fill_color].each do |colour_tag|
|
141
|
+
if Glyph.gradients.include?(args[colour_tag])
|
142
|
+
@svg.gradient(Glyph.gradient(args[colour_tag]))
|
143
|
+
args[colour_tag] = "url(##{args[colour_tag]})"
|
144
|
+
elsif args[colour_tag].instance_of?(Hash)
|
145
|
+
@svg.gradient(args[colour_tag])
|
146
|
+
args[colour_tag] = "url(##{args[colour_tag][:id]})"
|
147
|
+
end
|
148
|
+
end
|
149
|
+
@tracks << Track.new(args)
|
150
|
+
return @tracks.last
|
151
|
+
end
|
170
152
|
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
153
|
+
#Calculates the Page scale-start and scale-stop position and the nucleotides per pixel for the current Page
|
154
|
+
def get_limits
|
155
|
+
@tracks.each do |track|
|
156
|
+
lowest = track.features.sort { |x, y| x.start <=> y.start }.first.start
|
157
|
+
highest = track.features.sort { |x, y| y.end <=> x.end }.first.end
|
158
|
+
@scale_start = lowest if lowest < @scale_start
|
159
|
+
@scale_stop = highest if highest > @scale_stop
|
160
|
+
@nt_per_px_x = (@scale_stop - @scale_start).to_f / @width.to_f
|
161
|
+
end
|
162
|
+
end
|
177
163
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
164
|
+
#Adds the Bio::Graphics::Primitive objects to the SVGEE object
|
165
|
+
def draw_scale
|
166
|
+
Glyph.scale(:start => @scale_start,
|
167
|
+
:stop => @scale_stop,
|
168
|
+
:number_of_intervals => @num_intervals, :page_width => @width).each { |g| @svg.add_primitive(g) }
|
169
|
+
end
|
170
|
+
#Adds the Bio::Graphics::Primitive objects to the SVGEE object
|
171
|
+
#* +args+ - an Array of Bio::Graphics::Primitive object
|
172
|
+
def draw_label(args)
|
173
|
+
Glyph.label(:text => args[:text],
|
174
|
+
:x => args[:x],
|
175
|
+
:y => args[:y]).each { |g| @svg.add_primitive(g) }
|
176
|
+
end
|
177
|
+
#Adds the Bio::Graphics::Primitive objects to the SVGEE object
|
178
|
+
#* +args+ - an Array of Bio::Graphics::Primitive objects of the stated type
|
179
|
+
def draw_generic(args) #remember presentation info comes from track@args when the track is defined
|
180
|
+
Glyph.generic(args).each { |g| @svg.add_primitive(g) }
|
181
|
+
end
|
182
|
+
#Adds the Bio::Graphics::Primitive objects to the SVGEE object
|
183
|
+
#* +args+ - an Array of Bio::Graphics::Primitive objects of the stated type
|
184
|
+
def draw_directed(args)
|
185
|
+
Glyph.directed(args).each { |g| @svg.add_primitive(g) }
|
186
|
+
end
|
187
|
+
#Adds the Bio::Graphics::Primitive objects to the SVGEE object
|
188
|
+
#* +args+ - an Array of Bio::Graphics::Primitive objects of the stated type
|
189
|
+
def draw_circle(args)
|
190
|
+
Glyph.circle(args).each { |g| @svg.add_primitive(g) }
|
183
191
|
end
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
track.features.each do |f|
|
189
|
-
x = to_px(f.start - @scale_start)
|
190
|
-
width = to_px( (f.end - @scale_start) - (f.start - @scale_start) )
|
191
|
-
height = f.segment_height.to_f * data_per_px
|
192
|
-
y = @track_top + track.track_height - height + 5
|
193
|
-
#$stderr.puts f.segment_height, data_per_px, data_interval, max, min, "------"
|
194
|
-
self.send("draw_#{track.glyph}", {:x => x,
|
195
|
-
:y => y,
|
196
|
-
:width => width,
|
197
|
-
:height => height }.merge!(track.args) )
|
192
|
+
#Adds the Bio::Graphics::Primitive objects to the SVGEE object
|
193
|
+
#* +args+ - an Array of Bio::Graphics::Primitive objects of the stated type
|
194
|
+
def draw_transcript(args)
|
195
|
+
Glyph.transcript(args).each { |g| @svg.add_primitive(g) }
|
198
196
|
end
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
197
|
+
#Adds the Bio::Graphics::Primitive objects to the SVGEE object
|
198
|
+
#* +args+ - an Array of Bio::Graphics::Primitive objects of the stated type
|
199
|
+
def draw_histogram(args)
|
200
|
+
Glyph.generic(args).each { |g| @svg.add_primitive(g) }
|
201
|
+
end
|
202
|
+
#Adds the Bio::Graphics::Primitive objects to the SVGEE object
|
203
|
+
#* +args+ - an Array of Bio::Graphics::Primitive objects of the stated type
|
204
|
+
def draw_up_triangle(args)
|
205
|
+
Glyph.up_triangle(args).each { |g| @svg.add_primitive(g) }
|
206
|
+
end
|
207
|
+
#Adds the Bio::Graphics::Primitive objects to the SVGEE object
|
208
|
+
#* +args+ - an Array of Bio::Graphics::Primitive objects of the stated type
|
209
|
+
def draw_down_triangle(args)
|
210
|
+
Glyph.down_triangle(args).each { |g| @svg.add_primitive(g) }
|
211
|
+
end
|
212
|
+
#Adds the Bio::Graphics::Primitive objects to the SVGEE object
|
213
|
+
#* +args+ - an Array of Bio::Graphics::Primitive objects of the stated type
|
214
|
+
def draw_span(args)
|
215
|
+
Glyph.span(args).each { |g| @svg.add_primitive(g) }
|
203
216
|
end
|
204
|
-
track.get_rows ##work out how many rows and which features belong in each row...
|
205
|
-
track.features.each_with_index do |f,index|
|
206
|
-
x = to_px(f.start - @scale_start) #bottom left of feature
|
207
|
-
all_sub_blocks = []
|
208
217
|
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
exons << [to_px(exon[0] - @scale_start), to_px( (exon[1] - @scale_start) - (exon[0] - @scale_start) ) ]
|
216
|
-
end
|
217
|
-
end
|
218
|
-
f.exons = exons
|
218
|
+
#Takes a Bio::Graphics::Track object and sorts out the input information into a user friendly format.
|
219
|
+
#
|
220
|
+
#It examines the the type of track and calculates the required parameters
|
221
|
+
#* +args+ - an Array of Bio::Graphics::Track object
|
222
|
+
def draw_features(track)
|
223
|
+
if [:histogram, "histogram"].include?(track.glyph) #do different stuff for data tracks...
|
219
224
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
utrs << [to_px(utr[0] - @scale_start), to_px( (utr[1] - @scale_start) - (utr[0] - @scale_start) ) ]
|
225
|
+
y = @track_top + (track.track_height)
|
226
|
+
max = track.max_y ? track.max_y : track.features.sort { |a, b| a.segment_height <=> b.segment_height }.last.segment_height
|
227
|
+
min = 0
|
228
|
+
if track.label
|
229
|
+
draw_label(:text => track.name, :y => @track_top += 30, :x => 3)
|
226
230
|
end
|
227
|
-
|
228
|
-
|
231
|
+
draw_label(:text => max, :x => to_px(@scale_stop - @scale_start) + 5, :y => @track_top + 5)
|
232
|
+
draw_label(:text => min, :x => to_px(@scale_stop - @scale_start) + 5, :y => @track_top + track.track_height + 5)
|
233
|
+
data_interval = max - min
|
234
|
+
data_per_px = track.track_height.to_f / data_interval.to_f
|
235
|
+
track.features.each do |f|
|
236
|
+
x = to_px(f.start - @scale_start)
|
237
|
+
width = to_px((f.end - @scale_start) - (f.start - @scale_start))
|
238
|
+
height = f.segment_height.to_f * data_per_px
|
239
|
+
y = @track_top + track.track_height - height + 5
|
240
|
+
#$stderr.puts f.segment_height, data_per_px, data_interval, max, min, "------"
|
241
|
+
self.send("draw_#{track.glyph}", {:x => x,
|
242
|
+
:y => y,
|
243
|
+
:width => width,
|
244
|
+
:height => height}.merge!(track.args))
|
245
|
+
end
|
246
|
+
@track_top += (track.track_height) + 20
|
247
|
+
else ##following stuff for the features
|
248
|
+
if track.label
|
249
|
+
draw_label(:text => track.name, :y => @track_top += 30, :x => 3)
|
250
|
+
end
|
251
|
+
track.get_rows ##work out how many rows and which features belong in each row...
|
252
|
+
track.features.each_with_index do |f, index|
|
253
|
+
x = to_px(f.start - @scale_start) #bottom left of feature
|
254
|
+
all_sub_blocks = []
|
255
|
+
|
256
|
+
#convert the exon and utr start stops to px start stops and px widths
|
257
|
+
exons = []
|
258
|
+
if f.exons
|
259
|
+
f.exons.each_slice(2).each do |exon|
|
260
|
+
all_sub_blocks << exon
|
261
|
+
next if exon.nil?
|
262
|
+
exons << [to_px(exon[0] - @scale_start), to_px((exon[1] - @scale_start) - (exon[0] - @scale_start))]
|
263
|
+
end
|
264
|
+
end
|
265
|
+
f.exons = exons
|
266
|
+
|
267
|
+
utrs = []
|
268
|
+
if f.utrs
|
269
|
+
f.utrs.each_slice(2).each do |utr|
|
270
|
+
all_sub_blocks << utr
|
271
|
+
next if utr.nil?
|
272
|
+
utrs << [to_px(utr[0] - @scale_start), to_px((utr[1] - @scale_start) - (utr[0] - @scale_start))]
|
273
|
+
end
|
274
|
+
end
|
275
|
+
f.utrs = utrs
|
276
|
+
|
277
|
+
#if there are any intron like gaps.. get where they would be
|
278
|
+
if not all_sub_blocks.empty?
|
279
|
+
all_sub_blocks = all_sub_blocks.sort { |a, b| a.first <=> b.first }
|
280
|
+
all_sub_blocks.each_index do |i|
|
281
|
+
next if i + 1 == all_sub_blocks.length or all_sub_blocks[i].last >= all_sub_blocks[i + 1].first #skip if there is no gap
|
282
|
+
f.block_gaps << [to_px(all_sub_blocks[i].last - @scale_start), to_px((all_sub_blocks[i + 1].first - @scale_start) - (all_sub_blocks[i].last - @scale_start))]
|
283
|
+
end
|
284
|
+
end
|
229
285
|
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
286
|
+
width = to_px((f.end - @scale_start) - (f.start - @scale_start))
|
287
|
+
if track.min_width and width < track.min_width
|
288
|
+
width = track.min_width
|
289
|
+
end
|
290
|
+
y = @track_top + (track.feature_rows[index] * 2 * track.feature_height)
|
291
|
+
|
292
|
+
self.send("draw_#{track.glyph}", {:x => x,
|
293
|
+
:y => y,
|
294
|
+
:width => width,
|
295
|
+
:strand => f.strand,
|
296
|
+
:exons => f.exons,
|
297
|
+
:utrs => f.utrs,
|
298
|
+
:block_gaps => f.block_gaps,
|
299
|
+
:height => track.feature_height
|
300
|
+
}.merge!(track.args))
|
301
|
+
|
302
|
+
if f.id
|
303
|
+
draw_label(:y => y, :x => x + width +2, :text => f.id)
|
304
|
+
end
|
236
305
|
end
|
306
|
+
@track_top += (track.feature_height * track.number_rows * 2) + 20
|
237
307
|
end
|
238
308
|
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
end
|
243
|
-
y = @track_top + (track.feature_rows[index] * 2 * track.feature_height)
|
309
|
+
@height = @track_top + 100 #fudge...
|
310
|
+
@svg.update_height(@height)
|
311
|
+
#@svg.update_width(@width + 200)
|
244
312
|
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
313
|
+
end
|
314
|
+
#Provides the number of pixels required for a given number of nucleotides, e.g the length of a certain exon
|
315
|
+
#* +num+ - the number of nucleotides
|
316
|
+
#* +returns+ - the required number of pixels to draw the object
|
317
|
+
def to_px(num)
|
318
|
+
(num.to_f / @nt_per_px_x.to_f)
|
319
|
+
end
|
320
|
+
|
321
|
+
#Pulls together all track information to create svg text which will draw all the features on the page to scale
|
322
|
+
#Uses the methods +get_limits+ and +draw_scale+ and then +draw_feature+ for each track on the page
|
323
|
+
def get_markup
|
324
|
+
get_limits
|
325
|
+
draw_scale
|
326
|
+
@tracks.each do |track|
|
327
|
+
draw_features(track)
|
257
328
|
end
|
329
|
+
@svg.draw
|
330
|
+
end
|
331
|
+
#Prints out the svg text
|
332
|
+
def draw
|
333
|
+
puts get_markup
|
258
334
|
end
|
259
|
-
@track_top += (track.feature_height * track.number_rows * 2) + 20
|
260
|
-
end
|
261
|
-
|
262
|
-
@height = @track_top + 100 #fudge...
|
263
|
-
@svg.update_height(@height)
|
264
|
-
#@svg.update_width(@width + 200)
|
265
335
|
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
def get_markup
|
273
|
-
get_limits
|
274
|
-
draw_scale
|
275
|
-
@tracks.each do |track|
|
276
|
-
draw_features(track)
|
336
|
+
#Writes the svg text to a file
|
337
|
+
#* +file+ - the file to which the svg text should be written
|
338
|
+
def write(file)
|
339
|
+
File.open(file, 'w').write(get_markup)
|
340
|
+
end
|
277
341
|
end
|
278
|
-
@svg.draw
|
279
|
-
end
|
280
|
-
|
281
|
-
def draw
|
282
|
-
puts get_markup
|
283
|
-
end
|
284
|
-
|
285
|
-
def write(file)
|
286
|
-
File.open(file, 'w').write(get_markup)
|
287
342
|
end
|
288
|
-
end
|
289
|
-
end
|
290
343
|
end
|