Mercurial > repos > mahtabm > ensembl
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 |