bio-graphics 1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/doc/classes/Bio.html +135 -0
  2. data/doc/classes/Bio/Graphics.html +247 -0
  3. data/doc/classes/Bio/Graphics/Panel.html +344 -0
  4. data/doc/classes/Bio/Graphics/Panel.src/M000005.html +29 -0
  5. data/doc/classes/Bio/Graphics/Panel.src/M000006.html +19 -0
  6. data/doc/classes/Bio/Graphics/Panel.src/M000007.html +67 -0
  7. data/doc/classes/Bio/Graphics/Panel/Ruler.html +238 -0
  8. data/doc/classes/Bio/Graphics/Panel/Ruler.src/M000008.html +20 -0
  9. data/doc/classes/Bio/Graphics/Panel/Ruler.src/M000009.html +28 -0
  10. data/doc/classes/Bio/Graphics/Panel/Ruler.src/M000010.html +54 -0
  11. data/doc/classes/Bio/Graphics/Panel/Ruler.src/M000013.html +20 -0
  12. data/doc/classes/Bio/Graphics/Panel/Ruler.src/M000014.html +28 -0
  13. data/doc/classes/Bio/Graphics/Panel/Ruler.src/M000015.html +59 -0
  14. data/doc/classes/Bio/Graphics/Panel/Track.html +342 -0
  15. data/doc/classes/Bio/Graphics/Panel/Track.src/M000008.html +23 -0
  16. data/doc/classes/Bio/Graphics/Panel/Track.src/M000009.html +42 -0
  17. data/doc/classes/Bio/Graphics/Panel/Track.src/M000010.html +285 -0
  18. data/doc/classes/Bio/Graphics/Panel/Track.src/M000011.html +23 -0
  19. data/doc/classes/Bio/Graphics/Panel/Track.src/M000012.html +43 -0
  20. data/doc/classes/Bio/Graphics/Panel/Track.src/M000013.html +259 -0
  21. data/doc/classes/Bio/Graphics/Panel/Track/Feature.html +292 -0
  22. data/doc/classes/Bio/Graphics/Panel/Track/Feature.src/M000011.html +65 -0
  23. data/doc/classes/Bio/Graphics/Panel/Track/Feature.src/M000014.html +65 -0
  24. data/doc/classes/Bio/Graphics/Panel/Track/Feature/PixelRange.html +155 -0
  25. data/doc/classes/Bio/Graphics/Panel/Track/Feature/PixelRange.src/M000012.html +18 -0
  26. data/doc/classes/Bio/Graphics/Panel/Track/Feature/PixelRange.src/M000015.html +18 -0
  27. data/doc/classes/ImageMap.html +185 -0
  28. data/doc/classes/ImageMap.src/M000001.html +18 -0
  29. data/doc/classes/ImageMap.src/M000002.html +24 -0
  30. data/doc/classes/ImageMap/ImageMapElement.html +187 -0
  31. data/doc/classes/ImageMap/ImageMapElement.src/M000003.html +19 -0
  32. data/doc/classes/ImageMap/ImageMapElement.src/M000004.html +20 -0
  33. data/doc/created.rid +1 -0
  34. data/doc/files/README_DEV.html +432 -0
  35. data/doc/files/TUTORIAL.html +358 -0
  36. data/doc/files/lib/bio-graphics_rb.html +121 -0
  37. data/doc/files/lib/bio/graphics/feature_rb.html +113 -0
  38. data/doc/files/lib/bio/graphics/image_map_rb.html +113 -0
  39. data/doc/files/lib/bio/graphics/panel_rb.html +113 -0
  40. data/doc/files/lib/bio/graphics/ruler_rb.html +113 -0
  41. data/doc/files/lib/bio/graphics/track_rb.html +113 -0
  42. data/doc/fr_class_index.html +35 -0
  43. data/doc/fr_file_index.html +34 -0
  44. data/doc/fr_method_index.html +41 -0
  45. data/doc/images/example.png +0 -0
  46. data/doc/images/glyph_showcase.png +0 -0
  47. data/doc/images/terms.png +0 -0
  48. data/doc/images/terms.svg +166 -0
  49. data/doc/index.html +24 -0
  50. data/images/example.png +0 -0
  51. data/images/glyph_showcase.png +0 -0
  52. data/images/terms.png +0 -0
  53. data/images/terms.svg +166 -0
  54. data/lib/bio-graphics.rb +18 -0
  55. data/lib/bio/graphics/feature.rb +136 -0
  56. data/lib/bio/graphics/image_map.rb +37 -0
  57. data/lib/bio/graphics/panel.rb +205 -0
  58. data/lib/bio/graphics/ruler.rb +96 -0
  59. data/lib/bio/graphics/track.rb +387 -0
  60. data/samples/arkdb_features.rb +37 -0
  61. data/samples/data.txt +32 -0
  62. data/samples/glyph_showcase.rb +29 -0
  63. metadata +137 -0
@@ -0,0 +1,19 @@
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <!DOCTYPE html
3
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+
6
+ <html>
7
+ <head>
8
+ <title>new (ImageMap::ImageMapElement)</title>
9
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
+ <link rel="stylesheet" href="../../.././rdoc-style.css" type="text/css" media="screen" />
11
+ </head>
12
+ <body class="standalone-code">
13
+ <pre><span class="ruby-comment cmt"># File lib/bio/graphics/image_map.rb, line 25</span>
14
+ <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">initialize</span>(<span class="ruby-identifier">left</span>, <span class="ruby-identifier">top</span>, <span class="ruby-identifier">right</span>, <span class="ruby-identifier">bottom</span>, <span class="ruby-identifier">url</span> = <span class="ruby-keyword kw">nil</span>)
15
+ <span class="ruby-ivar">@left</span>, <span class="ruby-ivar">@top</span>, <span class="ruby-ivar">@right</span>, <span class="ruby-ivar">@bottom</span> = <span class="ruby-identifier">left</span>, <span class="ruby-identifier">top</span>, <span class="ruby-identifier">right</span>, <span class="ruby-identifier">bottom</span>
16
+ <span class="ruby-ivar">@url</span> = ( <span class="ruby-identifier">url</span>.<span class="ruby-identifier">nil?</span> ) <span class="ruby-operator">?</span> <span class="ruby-value str">''</span> <span class="ruby-operator">:</span> <span class="ruby-identifier">url</span>
17
+ <span class="ruby-keyword kw">end</span></pre>
18
+ </body>
19
+ </html>
@@ -0,0 +1,20 @@
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <!DOCTYPE html
3
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+
6
+ <html>
7
+ <head>
8
+ <title>to_s (ImageMap::ImageMapElement)</title>
9
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
+ <link rel="stylesheet" href="../../.././rdoc-style.css" type="text/css" media="screen" />
11
+ </head>
12
+ <body class="standalone-code">
13
+ <pre><span class="ruby-comment cmt"># File lib/bio/graphics/image_map.rb, line 31</span>
14
+ <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">to_s</span>
15
+ <span class="ruby-keyword kw">unless</span> <span class="ruby-ivar">@url</span> <span class="ruby-operator">==</span> <span class="ruby-value str">''</span>
16
+ <span class="ruby-keyword kw">return</span> <span class="ruby-value str">'&lt;area shape=&quot;rect&quot; coords=&quot;'</span> <span class="ruby-operator">+</span> <span class="ruby-ivar">@left</span>.<span class="ruby-identifier">to_s</span> <span class="ruby-operator">+</span> <span class="ruby-value str">' '</span> <span class="ruby-operator">+</span> <span class="ruby-ivar">@top</span>.<span class="ruby-identifier">to_s</span> <span class="ruby-operator">+</span> <span class="ruby-value str">' '</span> <span class="ruby-operator">+</span> <span class="ruby-ivar">@right</span>.<span class="ruby-identifier">to_s</span> <span class="ruby-operator">+</span> <span class="ruby-value str">' '</span> <span class="ruby-operator">+</span> <span class="ruby-ivar">@bottom</span>.<span class="ruby-identifier">to_s</span> <span class="ruby-operator">+</span> <span class="ruby-value str">'&quot; href=&quot;'</span> <span class="ruby-operator">+</span> <span class="ruby-ivar">@url</span> <span class="ruby-operator">+</span> <span class="ruby-value str">'&quot;/&gt;'</span>
17
+ <span class="ruby-keyword kw">end</span>
18
+ <span class="ruby-keyword kw">end</span></pre>
19
+ </body>
20
+ </html>
@@ -0,0 +1 @@
1
+ Mon Oct 01 11:03:19 +0100 2007
@@ -0,0 +1,432 @@
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <!DOCTYPE html
3
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+
6
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7
+ <head>
8
+ <title>File: README.DEV</title>
9
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
+ <meta http-equiv="Content-Script-Type" content="text/javascript" />
11
+ <link rel="stylesheet" href=".././rdoc-style.css" type="text/css" media="screen" />
12
+ <script type="text/javascript">
13
+ // <![CDATA[
14
+
15
+ function popupCode( url ) {
16
+ window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17
+ }
18
+
19
+ function toggleCode( id ) {
20
+ if ( document.getElementById )
21
+ elem = document.getElementById( id );
22
+ else if ( document.all )
23
+ elem = eval( "document.all." + id );
24
+ else
25
+ return false;
26
+
27
+ elemStyle = elem.style;
28
+
29
+ if ( elemStyle.display != "block" ) {
30
+ elemStyle.display = "block"
31
+ } else {
32
+ elemStyle.display = "none"
33
+ }
34
+
35
+ return true;
36
+ }
37
+
38
+ // Make codeblocks hidden by default
39
+ document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
+
41
+ // ]]>
42
+ </script>
43
+
44
+ </head>
45
+ <body>
46
+
47
+
48
+
49
+ <div id="fileHeader">
50
+ <h1>README.DEV</h1>
51
+ <table class="header-table">
52
+ <tr class="top-aligned-row">
53
+ <td><strong>Path:</strong></td>
54
+ <td>README.DEV
55
+ </td>
56
+ </tr>
57
+ <tr class="top-aligned-row">
58
+ <td><strong>Last Update:</strong></td>
59
+ <td>Mon Oct 01 11:03:17 +0100 2007</td>
60
+ </tr>
61
+ </table>
62
+ </div>
63
+ <!-- banner header -->
64
+
65
+ <div id="bodyContent">
66
+
67
+
68
+
69
+ <div id="contextContent">
70
+
71
+ <div id="description">
72
+ <p>
73
+ Copyright (C) 2007 Jan Aerts &lt;jan.aerts@bbsrc.ac.uk&gt;
74
+ </p>
75
+ <h2>README for developers</h2>
76
+ <p>
77
+ This README is mainly meant to explain how the code works (rather than how
78
+ to <em>use</em> the library). It should help if you&#8216;re interested in
79
+ contributing, or if you think you found a bug.
80
+ </p>
81
+ <h3>Overview</h3>
82
+ <p>
83
+ I&#8216;ve tried to document as much as possible in the code itself, see
84
+ for example the comments that accompany the setting of the defaults for <a
85
+ href="../classes/Bio/Graphics.html">Bio::Graphics</a> in the panel.rb file.
86
+ However, the bigger picture can not be explained that way.
87
+ </p>
88
+ <h3>The files</h3>
89
+ <p>
90
+ There&#8216;s one file for each class: panel, track, feature, ruler and
91
+ image_map. See the tutorial on a breakdown what each of these do. All of
92
+ these except the image_map make up a picture. The image_map is used to
93
+ describe the HTML map that can be created to make a picture clickable.
94
+ </p>
95
+ <p>
96
+ Classes are embedded in each other: instead of
97
+ </p>
98
+ <pre>
99
+ Bio::Graphics::Panel
100
+ Bio::Graphics::Ruler
101
+ Bio::Graphics::Track
102
+ Bio::Graphics::Feature
103
+ </pre>
104
+ <p>
105
+ we have:
106
+ </p>
107
+ <pre>
108
+ Bio::Graphics::Panel
109
+ Bio::Graphics::Panel::Ruler
110
+ Bio::Graphics::Panel::Track
111
+ Bio::Graphics::Panel::Track::Feature
112
+ </pre>
113
+ <p>
114
+ There&#8216;s a reason for this. A track can only exist within the confines
115
+ of a panel (i.e. a panel is a container for tracks), and a feature can only
116
+ exist within the confines of a track. In addition, there are quite some
117
+ instances where information from the panel is necessary for the track, and
118
+ from the track for the features.
119
+ </p>
120
+ <h3>The workflow</h3>
121
+ <h4>1. Creating the panel</h4>
122
+ <p>
123
+ The user has to start with a
124
+ </p>
125
+ <pre>
126
+ my_panel = Bio::Graphics::Panel.new(length, width, clickable, display_start, display_stop)
127
+ </pre>
128
+ <p>
129
+ When this happens, among other things, the instance variable @tracks is
130
+ created that will later contain the actual Track objects. In addition,
131
+ there&#8216;s @number_of_times_bumped. You&#8216;ll later see that each
132
+ Track object also has its @number_of_times_bumped. The panel needs this
133
+ information to know how far it has to go down before it can start drawing a
134
+ track: the first track will be just below the ruler, but the vertical
135
+ coordinates of the second one depend on the height of all the ones that
136
+ were drawn previously. And <em>that</em> in turn is defined by the number
137
+ of times a feature would overlap with another one and therefore had to be
138
+ <em>bumped</em> down.
139
+ </p>
140
+ <p>
141
+ @display_start and @display_stop are used for zooming in on a region. Even
142
+ though the full @length of the sequence can be really long, setting
143
+ @display_start and @display_stop will only consider that region.
144
+ </p>
145
+ <p>
146
+ Then there is @rescale_factor, which plays a crucial role in drawing the
147
+ stuff: it tells the script how many basepairs are contained in one pixel.
148
+ This variable will be used <em>very</em> extensively in the drawing code.
149
+ </p>
150
+ <p>
151
+ So this covered the Panel#initialize&#8230;
152
+ </p>
153
+ <h4>2. Adding tracks to the panel</h4>
154
+ <p>
155
+ Because tracks are inherently part of a panel and cannot exist on their
156
+ own, they can only be created by using a Panel method rather than a Track
157
+ method.
158
+ </p>
159
+ <pre>
160
+ my_track_1 = my_panel.add_track(name, feature_colour = [0,0,1], feature_glyph = 'generic')
161
+ </pre>
162
+ <p>
163
+ This creates a new Track object and adds it to the @tracks array of the
164
+ Panel object. Several instance variables are set for the Track object,
165
+ including @features (which is an array of Feature objects for that track)
166
+ and @number_of_times_bumped. Every time a feature cannot be drawn because
167
+ it would overlap with another one, it will be &#8216;bumped&#8217; down
168
+ until it can be drawn. This effectively results in <em>rows</em> that
169
+ contain the features. The @number_of_times_bumped is just the number of
170
+ rows (to be able to calculate the height of the track afterwards). I admit
171
+ that this variable should be renamed to something like
172
+ @number_of_feature_rows or something, because the value is actually the
173
+ number of times bumped + 1. In the example below, @number_of_times_bumped
174
+ is 3 (instead of 2). (I&#8216;ll change that later&#8230;)
175
+ </p>
176
+ <pre>
177
+ ------------------------------------------------------
178
+ ******* **** ********* ***** *****
179
+ ***** ********
180
+ **
181
+ </pre>
182
+ <p>
183
+ The Panel#add_track method returns the Track object itself, because the
184
+ latter has to be accessible to be able to assign features to it.
185
+ </p>
186
+ <h4>3. Adding features to a track</h4>
187
+ <p>
188
+ Same thing as adding a track to a panel: the feature can only be added by
189
+ the user by using the Track#add_feature method. Parameters are the name of
190
+ the feature, the location and the link.
191
+ </p>
192
+ <p>
193
+ The location of a feature can be something like
194
+ &#8216;complement(join(10..20,50..70))&#8217;. To be able to parse this, I
195
+ use the Bio::Locations object from bioruby (see <a
196
+ href="http://www.bioruby.org">www.bioruby.org</a>). A Bio::Locations
197
+ (plural) object contains one or more Bio::Location (singular) objects,
198
+ which are the subfeatures: 10..20 and 50..70. It&#8216;s these
199
+ Bio::Location objects we use to calculate the ultimate start and stop of
200
+ the feature.
201
+ </p>
202
+ <p>
203
+ The Track#add_feature method returns the Track object itself.
204
+ </p>
205
+ <p>
206
+ Now let&#8216;s look at the other end: the Feature object that gets
207
+ created. In the Feature#initialize method, you&#8216;ll notice, apart from
208
+ the obvious variables, the following instances variables:
209
+ @pixel_range_collection, @chopped_at_start, @chopped_at_stop,
210
+ @hidden_subfeatures_at_start and @hidden_subfeatures_at_stop. Let&#8216;s
211
+ take these one by one:
212
+ </p>
213
+ <h5>@pixel_range_collection</h5>
214
+ <p>
215
+ Now <em>this</em> is the crucial bit: it will hold the information on what
216
+ pixels (on the horizontal axis) should be covered. This means that any part
217
+ of the feature that does not fall within the view is <em>not</em> in this
218
+ collection. Basically, for every subfeature (e.g. exon for a gene), the
219
+ location of that subfeature is compared to the region of the view. If a
220
+ subfeature is not in the view at all, its positions are discarded (but
221
+ other stuff does happen, see below); if a subfeature is at the left of the
222
+ picture but actually extends outwith the view, the start pixel will become
223
+ 1. You get the picture. Also see the mini diagrams in the code itself.
224
+ </p>
225
+ <p>
226
+ These start and stop positions are used to create
227
+ Bio::Graphics::Panel::Track::PixelRange objects. Unspliced objects will
228
+ have an array @pixel_range_collection with just one element.
229
+ </p>
230
+ <h5>@chopped_at_start and @chopped_at_stop</h5>
231
+ <p>
232
+ Suppose you&#8216;ve got a directed feature (so one with an arrow), and the
233
+ 3&#8217; end falls outside of the view. What would happen, is that the
234
+ 3&#8217; end that&#8216;s out of view would be chopped of (that&#8216;s
235
+ good), but also that the end of the glyph (which is <em>not</em> the end of
236
+ the feature) becomes an arrow. I don&#8216;t want that. Instead, the arrow
237
+ should be removed.
238
+ </p>
239
+ <p>
240
+ That&#8216;s where the @chopped_at_start and @chopped_at_stop come in. If
241
+ these are set to true (while building the @pixel_range_collection), the
242
+ arrow is not drawn.
243
+ </p>
244
+ <h5>@hidden_subfeatures_at_start and @hidden_subfeatures_at_stop</h5>
245
+ <p>
246
+ For spliced features, it might be that one or more of the subfeatures (e.g.
247
+ exons) lies outwith the view. We normally draw e.g. genes by drawing the
248
+ exons as boxes and connecting them with small lines. The drawing code
249
+ itself (see later) takes all exons within view and draws those connections.
250
+ However, if an exon is outside of the viewing area, this line is not drawn.
251
+ The @hidden_subfeatures_at_start and @hidden_subfeatures_at_stop are just
252
+ flags to capture this.
253
+ </p>
254
+ <h4>4. Drawing the thing</h4>
255
+ <p>
256
+ The Cairo library (<a
257
+ href="http://cairographics.org">cairographics.org</a>) is used for the
258
+ actual drawing. The main concepts in the Cairo drawing model are (please
259
+ also see <a
260
+ href="http://cairographics.org/tutorial">cairographics.org/tutorial</a>):
261
+ </p>
262
+ <ul>
263
+ <li><b>source</b>: the <em>paint</em> you&#8216;ll be using
264
+
265
+ </li>
266
+ <li><b>destination</b>: the <em>surface</em> (Cairo::ImageSurface) that you
267
+ want to draw onto
268
+
269
+ </li>
270
+ <li><b>mask</b>: controls where you apply the source to the destination. Stuff
271
+ like &#8216;line_to&#8217;.
272
+
273
+ </li>
274
+ <li><b>context</b>: tracks one source, one mask and one destination.
275
+
276
+ </li>
277
+ </ul>
278
+ <p>
279
+ From the cairo tutorial: &quot;Before you can start to draw something with
280
+ cairo, you need to create the context. &lt;SNIP&gt; When you create a cairo
281
+ context, it must be tied to a specific surface - for example, an image
282
+ surface if you want to create a PNG file.&quot; So that&#8216;s what we
283
+ have to do: create a Cairo::ImageSurface and connect a Cairo::Context to
284
+ it.
285
+ </p>
286
+ <p>
287
+ Now let&#8216;s walk through the code itself&#8230;
288
+ </p>
289
+ <p>
290
+ When a user draws a panel, the first thing that happens, is the creation of
291
+ a Cairo::ImageSurface (the <em>destination</em>). To be able to do this, we
292
+ need to know the dimensions. But there&#8216;s a slight problem: we
293
+ can&#8216;t know the height of the picture until it&#8216;s actually drawn.
294
+ The way we&#8216;ll circumvent this, is that we create a really high
295
+ picture (called &quot;huge_panel_drawing&quot;) that we&#8216;ll crop
296
+ afterwards.
297
+ </p>
298
+ <h5>Drawing the ruler</h5>
299
+ <p>
300
+ A ruler consists of a line with tickmarks on it. The major issue with
301
+ drawing the ruler, is determining the distance between those ticks. Suppose
302
+ we have zoomed into a small region, we&#8216;d still want to see usable
303
+ ticks; and if we&#8216;ve zoomed out to a huge region, we don&#8216;t want
304
+ to have those ticks all bumping into each other.
305
+ </p>
306
+ <p>
307
+ To calculate the distance between consecutive ticks, we start with a
308
+ distance of 1 basepair, and increase it until the minimal distance
309
+ criterion is met. We also set the distance between major tickmarks (which
310
+ are the ones that will get a number). There&#8216;s a small issue when you
311
+ actually start drawing the ticks. Most of the time, we don&#8216;t want the
312
+ first tick on the very first basepair of the view. Suppose that would be
313
+ position 333 in the sequence. Then the numbers under the major tickmarks
314
+ would be: 343, 353, 363, 373 and so on. Instead, we want 350, 360, 370,
315
+ 380. So we want to find the position of the first tick. If we&#8216;ve
316
+ found that one, it&#8216;s simple to add the rest of them.
317
+ </p>
318
+ <p>
319
+ The ruler height @height consists of the height of the ruler itself plus
320
+ the height of the numbers.
321
+ </p>
322
+ <h5>Drawing the tracks</h5>
323
+ <p>
324
+ Drawing each track starts out with the general header: a line above it and
325
+ the title. Obviously, the more challenging part is drawing the features
326
+ themselves.
327
+ </p>
328
+ <p>
329
+ First thing we have to do, is figure out what the <b>vertical</b>
330
+ <b>coordinates</b> of the glyph should be (i.e. the row). To keep track of
331
+ what parts of the screen are already occupied by features (so that we know
332
+ when a new feature has to be bumped down), I make use of a <b>grid</b>. The
333
+ grid is basically a hash with the keys being the row number, and the values
334
+ arrays of ranges. (These ranges use basepair units rather than pixels, but
335
+ that&#8216;s completely arbitrary.) For each feature, we first check if we
336
+ can draw it at the top of the track (i.e. row 1) and if we can&#8216;t move
337
+ it down a row at a time until there&#8216;s room for it.
338
+ </p>
339
+ <p>
340
+ So for example, suppose we&#8216;ve already drawn two features that have
341
+ the following positions: 100..150 and 200..225. The grid would then look
342
+ like this:
343
+ </p>
344
+ <pre>
345
+ grid = { 1 =&gt; [(100..150),(200..225)] }
346
+ </pre>
347
+ <p>
348
+ If we&#8216;d like to draw a new feature from 125..175 (which overlaps the
349
+ first of the two ranges above), we see that row_available becomes false,
350
+ and the row number is increased. The grid after adding this feature looks
351
+ like:
352
+ </p>
353
+ <pre>
354
+ grid = { 1 =&gt; [(100..150),(200..225)],
355
+ 2 =&gt; [(125..175)] }
356
+ </pre>
357
+ <p>
358
+ So now we know what the vertical coordinates of the glyph should be. Next
359
+ step is to check if there&#8216;s reasons we would like to <b>change</b>
360
+ <b>the</b> <b>requested</b> <b>glyph</b> <b>type</b> <b>from</b>
361
+ <b>directed</b> <b>to</b> <b>undirected</b>. If the user asks for directed
362
+ glyphs (i.e. ones with an arrow at the end), but the view is zoomed
363
+ <em>way</em> out, there&#8216;s no way the arrow will be visible. If
364
+ we&#8216;d try to draw that arrow anyway, it would become bigger than the
365
+ feature itself. Another reason would be if the feature&#8216;s 3&#8217; end
366
+ extends outwith the picture.
367
+ </p>
368
+ <p>
369
+ Finally, we can <b>draw</b>. The actual drawing bit should be quite
370
+ self-explanatory (<em>move_to</em>, <em>line_to</em>, &#8230;).
371
+ </p>
372
+ <p>
373
+ For the spliced features (<em>spliced</em> itself and
374
+ <em>directed_spliced</em>), we first draw the components (i.e. the exons)
375
+ keeping track of the start and stop positions of the gaps (i.e. introns).
376
+ We then add the connections in those gaps. In addition, we draw a line that
377
+ extends to the side of the picture if there are exons out of view. This
378
+ flag was set when the feature was created (see above:
379
+ @hidden_subfeatures_at_start and @hidden_subfeatures_at_stop).
380
+ </p>
381
+ <p>
382
+ When the user wants a clickable map, we also have to record that this
383
+ region should be added to the image map.
384
+ </p>
385
+ <p>
386
+ When everything has been drawn, we finally know the number of rows for that
387
+ track (i.e. the number_of_times_bumped).
388
+ </p>
389
+ <h5>Finalizing the panel</h5>
390
+ <p>
391
+ So now we have a huge panel (see &quot;huge_panel_drawing&quot; above)
392
+ which is way to high. This is converted to a panel of the right size by
393
+ creating a new panel (i.e. the cairo destination), and then using the huge
394
+ panel as a source to be transferred on that new destination.
395
+ </p>
396
+ <p>
397
+ And we just write the PNG to a file. If the user wanted a clickable map,
398
+ also create the HTML file.
399
+ </p>
400
+
401
+ </div>
402
+
403
+
404
+ </div>
405
+
406
+
407
+ </div>
408
+
409
+
410
+ <!-- if includes -->
411
+
412
+ <div id="section">
413
+
414
+
415
+
416
+
417
+
418
+
419
+
420
+
421
+ <!-- if method_list -->
422
+
423
+
424
+ </div>
425
+
426
+
427
+ <div id="validator-badges">
428
+ <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
429
+ </div>
430
+
431
+ </body>
432
+ </html>