comparison variant_effect_predictor/Bio/Graphics/Glyph/ruler_arrow.pm @ 0:1f6dce3d34e0

Uploaded
author mahtabm
date Thu, 11 Apr 2013 02:01:53 -0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:1f6dce3d34e0
1 package Bio::Graphics::Glyph::ruler_arrow;
2 # package to use for drawing an arrow as ruler (5' and 3' are marked as label)
3
4 use strict;
5 use vars '@ISA';
6 use Bio::Graphics::Glyph::generic;
7 @ISA = 'Bio::Graphics::Glyph::generic';
8
9 my %UNITS = (K => 1000,
10 M => 1_000_000,
11 G => 1_000_000_000);
12
13 sub pad_bottom {
14 my $self = shift;
15 my $val = $self->SUPER::pad_bottom(@_);
16 $val += $self->font->height if $self->option('tick');
17 $val;
18 }
19
20 # override draw method
21 sub draw {
22 my $self = shift;
23 my $parallel = $self->option('parallel');
24 $parallel = 1 unless defined $parallel;
25 $self->draw_parallel(@_) if $parallel;
26 $self->draw_perpendicular(@_) unless $parallel;
27 $self->draw_label(@_) if ($self->option('label'));
28 }
29
30 sub draw_perpendicular {
31 my $self = shift;
32 my $gd = shift;
33 my ($dx,$dy) = @_;
34 my ($x1,$y1,$x2,$y2) = $self->bounds(@_);
35
36 my $ne = $self->option('northeast');
37 my $sw = $self->option('southwest');
38 $ne = $sw = 1 unless defined($ne) || defined($sw);
39
40 # draw a perpendicular arrow at position indicated by $x1
41 my $fg = $self->set_pen;
42 my $a2 = ($y2-$y1)/4;
43
44 my @positions = $x1 == $x2 ? ($x1) : ($x1,$x2);
45 for my $x (@positions) {
46 if ($ne) {
47 $gd->line($x,$y1,$x,$y2,$fg);
48 $gd->line($x-$a2,$y1+$a2,$x,$y1,$fg);
49 $gd->line($x+$a2,$y1+$a2,$x,$y1,$fg);
50 }
51 if ($sw) {
52 $gd->line($x,$y1,$x,$y2,$fg);
53 $gd->line($x-$a2,$y2-$a2,$x,$y2,$fg);
54 $gd->line($x+$a2,$y2-$a2,$x,$y2,$fg);
55 }
56 }
57
58 # add a label if requested
59 # $self->draw_label($gd,$dx,$dy) if ($self->option('label') && !$self->option('ruler'));
60 # this draws the label aligned to the left
61 }
62
63 sub draw_parallel {
64 my $self = shift;
65 my $gd = shift;
66 my ($dx,$dy) = @_;
67 my ($x1,$y1,$x2,$y2) = $self->bounds(@_);
68
69 my $fg = $self->set_pen;
70 my $a2 = ($self->height)/2;
71 my $center = $y1+$a2;
72
73 $x1 = $self->panel->left if $x1 < $self->panel->left;
74 $x2 = $self->panel->right if $x2 > $self->panel->right;
75
76 my ($sw,$ne,$base_w,$base_e) = $self->arrowheads;
77 $gd->line($x1,$center,$x2,$center,$fg);
78 $self->arrowhead($gd,$x1,$center,$a2,-1) if $sw; # west arrow
79 $self->arrowhead($gd,$x2,$center,$a2,+1) if $ne; # east arrow
80 $gd->line($x2,$center-$a2,$x2,$center+$a2,$fg) if $base_e; #east base
81 $gd->line($x1,$center-$a2,$x1,$center+$a2,$fg) if $base_w; #west base
82
83 # turn on ticks
84 if ($self->option('tick')) {
85 local $^W = 0; # dumb uninitialized variable warning
86 my $font = $self->font;
87 my $width = $font->width;
88 my $font_color = $self->fontcolor;
89 my $height = $self->height;
90
91 my $relative = $self->option('relative_coords');
92 my $start = $relative ? 1 : $self->feature->start;
93 my $stop = $start + $self->feature->length - 1;
94
95 my $offset = $relative ? $self->feature->start-1 : 0;
96 my $reversed = $self->feature->strand < 0;
97
98 my $units = $self->option('units') || '';
99 my $divisor = $UNITS{$units} || 1 if $units;
100
101 my ($major_ticks,$minor_ticks) = $self->panel->ticks($start,$stop,$font,$divisor);
102
103 ## Does the user want to override the internal scale?
104 my $scale = $self->option('scale');
105
106 my $left = $sw ? $x1+$height : $x1;
107 my $right = $ne ? $x2-$height : $x2;
108
109 my $format = ($major_ticks->[1]-$major_ticks->[0])/($divisor||1) < 1 ? "%.1f$units" : "%d$units";
110
111 for my $i (@$major_ticks) {
112 my $tickpos = $dx + ($reversed ? $self->map_pt($stop - $i + $offset)
113 : $self->map_pt($i + $offset));
114 next if $tickpos < $left or $tickpos > $right;
115 $gd->line($tickpos,$center-$a2,$tickpos,$center+$a2,$fg);
116 my $label = $scale ? $i / $scale : $i;
117 if ($units) {
118 my $scaled = $label/$divisor;
119 $label = sprintf($format,$scaled);
120 }
121 my $middle = $tickpos - (length($label) * $width)/2;
122 $gd->string($font,$middle,$center+$a2-1,$label,$font_color)
123 unless ($self->option('no_tick_label'));
124 }
125
126 if ($self->option('tick') >= 2) {
127 my $a4 = $self->height/4;
128 for my $i (@$minor_ticks) {
129 my $tickpos = $dx + ($reversed ? $self->map_pt($stop - $i + $offset)
130 : $self->map_pt($i + $offset));
131 next if $tickpos < $left or $tickpos > $right;
132 $gd->line($tickpos,$center-$a4,$tickpos,$center+$a4,$fg);
133 }
134 }
135 }
136
137 # add a label if requested
138 # $self->draw_label($gd,$dx,$dy) if ($self->option('label');
139 # $self->draw_description($gd,$dx,$dy) if $self->option('description');
140 }
141
142 sub arrowheads {
143 my $self = shift;
144 my ($ne,$sw,$base_e,$base_w);
145 if ($self->option('double')) {
146 $ne = $sw = 1;
147 } else {
148 $ne = $self->option('northeast') || $self->option('east');
149 $sw = $self->option('southwest') || $self->option('west');
150 }
151 # otherwise use strandedness to define the arrow
152 unless (defined($ne) || defined($sw)) {
153 # turn on both if neither specified
154 $ne = 1 if $self->feature->strand > 0;
155 $sw = 1 if $self->feature->strand < 0;
156 }
157 return ($sw,$ne,0,0) unless $self->option('base');
158 return ($sw,$ne,!$sw,!$ne);
159 }
160
161 sub draw_label {
162 my $self = shift;
163 my ($gd,$left,$top) = @_;
164
165 my $label5 = "5'";
166 my $label3 = "3'";
167 my $relative = $self->option('relative_coords');
168 my $start = $relative ? 1 : $self->feature->start;
169 my $stop = $start + $self->feature->length - 1;
170
171 my $offset = $relative ? $self->feature->start-1 : 0;
172 my $reversed = $self->feature->strand < 0;
173
174 my $units = $self->option('units') || '';
175 my $divisor = $UNITS{$units} || 1 if $units;
176
177 my ($major_ticks,$minor_ticks) = $self->panel->ticks($start,$stop,$self->font,$divisor);
178 my $tick_scale = " ($major_ticks bp/";
179 $tick_scale .= ($self->option('tick') >= 2)?"major tick)":"tick)";
180
181 my $top_left_label = $label5;
182 $top_left_label .= $tick_scale if ($self->option('no_tick_label') && $self->option('tick'));
183 #-1 direction mean lower end is 3' (minus strand on top)
184 ($label5, $label3) = ($label3, $label5) if ($self->option('direction') == -1);
185 my $x = $self->left + $left;
186 $x = $self->panel->left + 1 if $x <= $self->panel->left;
187 my $font = $self->option('labelfont') || $self->font;
188 $gd->string($font,
189 $x,
190 $self->top + $top,
191 $top_left_label,
192 $self->fontcolor);
193 my $x1 = $left + $self->panel->right - $font->width*length($label3);
194 $gd->string($font,
195 $x1,
196 $self->top + $top,
197 $label3,
198 $self->fontcolor);
199 if ($self->option('both')) {#minus strand as well
200 $gd->string($font,
201 $x,
202 $self->bottom - $self->pad_bottom + $top,
203 $label3,
204 $self->fontcolor);
205 my $x1 = $left + $self->panel->right - $font->width*length($label5);
206 $gd->string($font,
207 $x1,
208 $self->bottom - $self->pad_bottom + $top,
209 $label5,
210 $self->fontcolor);
211 }
212 }
213
214
215 1;
216
217
218 __END__
219
220 =head1 NAME
221
222 Bio::Graphics::Glyph::arrow - The "ruler_arrow" glyph
223
224 =head1 SYNOPSIS
225
226 See L<Bio::Graphics::Panel> and L<Bio::Graphics::Glyph>.
227
228 =head1 DESCRIPTION
229
230 This glyph draws arrows. Label, if requested, will be 5' and 3' at both ends
231 and tick scale is printed if no_tick_label option is set and tick option set.
232 Depending on options, the arrows can be labeled, be oriented vertically
233 or horizontally, or can contain major and minor ticks suitable for use as a scale.
234
235 =head2 OPTIONS
236
237 In addition to the common options, the following glyph-specific
238 options are recognized:
239
240 Option Description Default
241 ------ ----------- -------
242
243 -tick Whether to draw major 0
244 and minor ticks.
245 0 = no ticks
246 1 = major ticks
247 2 = minor ticks
248 -label 5' at start, 3' at end 0
249 above arrow
250 -both 5', 3' above, 0
251 and 3', 5' below arrow
252 -direction 0 = ruler is plus strand 0
253 -1 = ruler is minus strand
254
255 -parallel Whether to draw the arrow true
256 parallel to the sequence
257 or perpendicular to it.
258
259 -northeast Force a north or east true
260 arrowhead(depending
261 on orientation)
262
263 -east synonym of above
264
265 -southwest Force a south or west true
266 arrowhead(depending
267 on orientation)
268
269 -west synonym of above
270
271 -double force-doubleheaded arrow
272
273 -base Draw a vertical base at the false
274 non-arrowhead side
275
276 -scale Reset the labels on the arrow false
277 to reflect an externally
278 established scale.
279
280 Set -parallel to false to display a point-like feature such as a
281 polymorphism, or to indicate an important location. If the feature
282 start == end, then the glyph will draw a single arrow at the
283 designated location:
284
285 ^
286 |
287
288 Otherwise, there will be two arrows at the start and end:
289
290 ^ ^
291 | |
292
293 Scale: Pass in a externally established scale to reset the labels on
294 the arrow. This is particularly useful for manually constructed
295 images where the founding parameters of the panel are not 1-based.
296 For example, a genetic map interval ranging from 0.1 - 0.3 can be
297 constructed by first multiplying every value by 100. Passing
298
299 arrow(-scale=>100);
300
301 will draw tick marks labelled appropriately to your external scale.
302
303 =head1 BUGS
304
305 Please report them.
306
307 =head1 SEE ALSO
308
309
310 L<Bio::Graphics::Panel>,
311 L<Bio::Graphics::Glyph>,
312 L<Bio::Graphics::Glyph::arrow>,
313 L<Bio::Graphics::Glyph::cds>,
314 L<Bio::Graphics::Glyph::crossbox>,
315 L<Bio::Graphics::Glyph::diamond>,
316 L<Bio::Graphics::Glyph::dna>,
317 L<Bio::Graphics::Glyph::dot>,
318 L<Bio::Graphics::Glyph::ellipse>,
319 L<Bio::Graphics::Glyph::extending_arrow>,
320 L<Bio::Graphics::Glyph::generic>,
321 L<Bio::Graphics::Glyph::graded_segments>,
322 L<Bio::Graphics::Glyph::heterogeneous_segments>,
323 L<Bio::Graphics::Glyph::line>,
324 L<Bio::Graphics::Glyph::pinsertion>,
325 L<Bio::Graphics::Glyph::primers>,
326 L<Bio::Graphics::Glyph::rndrect>,
327 L<Bio::Graphics::Glyph::segments>,
328 L<Bio::Graphics::Glyph::ruler_arrow>,
329 L<Bio::Graphics::Glyph::toomany>,
330 L<Bio::Graphics::Glyph::transcript>,
331 L<Bio::Graphics::Glyph::transcript2>,
332 L<Bio::Graphics::Glyph::translation>,
333 L<Bio::Graphics::Glyph::triangle>,
334 L<Bio::DB::GFF>,
335 L<Bio::SeqI>,
336 L<Bio::SeqFeatureI>,
337 L<Bio::Das>,
338 L<GD>
339
340 =head1 AUTHOR
341
342 Shengqiang Shu E<lt>sshu@bdgp.lbl.govE<gt>
343 Lincoln Stein E<lt>lstein@cshl.orgE<gt>.
344
345 Copyright (c) 2001 BDGP, Cold Spring Harbor Laboratory
346
347 This library is free software; you can redistribute it and/or modify
348 it under the same terms as Perl itself. See DISCLAIMER.txt for
349 disclaimers of warranty.
350
351 =cut