moving stuff around
[cview.git] / lib / CXGN / Cview / Ruler.pm
blob7f032160628fd47bcbf4d62fa1b49bdf55189b04
2 =head1 NAME
4 CXGN::Cview::Ruler - an class for drawing rulers
6 =head1 DESCRIPTION
8 Inherits from L<CXGN::Cview::ImageObject>. The basic class draws a simple linear ruler with the default units of cM. Each chromosome object knows what type of ruler it should use and the ruler for a given chromosome object can be obtained with get_ruler(). (set_ruler() is called in the chromosome objects constructor, where it constructs the right type of ruler to go with the chromosome).
10 =head1 KNOWN SUBCLASSES
12 L<CXGN::Cview::Ruler::PachyteneRuler> implements a ruler for fish chromosomes.
14 =head1 SEE ALSO
16 See also the documentation in L<CXGN::Cview>.
18 =head1 AUTHOR(S)
20 Lukas Mueller (lam87@cornell.edu)
22 =head1 FUNCTIONS
25 =cut
29 use strict;
30 use CXGN::Cview::ImageObject;
32 package CXGN::Cview::Ruler;
34 use base qw( CXGN::Cview::ImageObject );
36 =head2 function new()
38 Synopsis: constructor.
39 Arguments: x-position, y-position, height, start value,
40 end_value.
41 Returns: a CXGN::Cview::Ruler object.
42 Side effects: sets the default units to "cM".
43 use set_unit() to change the units.
44 Description:
46 =cut
48 sub new {
49 my $class = shift;
50 my $args ={};
51 my $self = $class -> SUPER::new(@_);
52 my $x = shift;
53 my $y = shift;
54 $self ->{height} = shift;
55 $self ->{start_value} = shift;
56 $self ->{end_value} = shift;
57 $self -> {font} = GD::Font->Small();
58 $self -> set_color (50, 50, 50);
59 $self -> {label_side} = "left";
60 $self -> set_units("cM");
61 return $self;
64 =head2 function set_color()
66 Synopsis: sets the color of the ruler
67 Arguments:
68 Returns:
69 Side effects:
70 Description:
72 =cut
74 # Note: this function is defined in the parent class and
75 # there is no need to override it here.
77 # sub set_color {
78 # my $self = shift;
79 # $self -> {color}[0] = shift;
80 # $self -> {color}[1] = shift;
81 # $self -> {color}[2] = shift;
82 # }
84 =head2 functions set_labels_right(), set_labels_left(), set_labels_none()
86 Synopsis:
87 Arguments:
88 Returns:
89 Side effects:
90 Description:
92 =cut
94 sub set_labels_right {
95 my $self = shift;
96 $self->{label_side} = "right";
99 sub set_labels_left {
100 my $self = shift;
101 $self ->{label_side} = "left";
104 sub set_labels_none {
105 my $self = shift;
106 $self -> {label_side} = "";
109 =head2 functions get_units(), set_units()
111 Synopsis: sets the units displayed on the ruler.
112 default is "cM".
113 Arguments:
114 Returns:
115 Side effects:
116 Description:
118 =cut
120 sub set_units {
121 my $self=shift;
122 $self->{unit}=shift;
125 sub get_units {
126 my $self = shift;
127 return $self->{unit};
130 =head2 function get_start_value()
132 Synopsis: accessor for the start_value property
133 Arguments:
134 Returns:
135 Side effects:
136 Description:
138 =cut
140 sub get_start_value {
141 my $self=shift;
142 return $self->{start_value};
145 =head2 function set_start_value()
147 Synopsis: setter function for the start_value property
148 Arguments: the start value in map units
149 Returns: nothing
150 Side effects: defines the start value of the chromosome section
151 in map units.
152 Description:
154 =cut
156 sub set_start_value {
157 my $self=shift;
158 $self->{start_value}=shift;
161 =head2 function get_end_value(), set_end_value()
163 Synopsis:
164 Arguments:
165 Returns:
166 Side effects:
167 Description:
169 =cut
171 sub get_end_value {
172 my $self=shift;
173 return $self->{end_value};
176 sub set_end_value {
177 my $self=shift;
178 $self->{end_value}=shift;
181 =head2 function render()
183 Synopsis: renders the ruler on $image
184 Arguments: $image (GD::Image object).
185 Returns: nothing
186 Side effects: draws the ruler image on $image.
187 Description:
189 =cut
192 sub render {
193 my $self = shift;
194 my $image=shift;
196 my $color = $image -> colorResolve($self->{color}[0], $self->{color}[1], $self->{color}[2]);
198 $self->_calculate_scaling_factor();
200 #draw line
201 $image -> line($self->get_horizontal_offset(), $self->get_vertical_offset(), $self->get_horizontal_offset(), $self->get_vertical_offset()+$self->{height}, $color);
202 my $length = 1;
203 if ($self->{scaling_factor}) {
204 $length = $self->get_height()/$self->{scaling_factor};
208 print STDERR "Length = $length\n";
209 # draw tick marks
211 my $tick_spacing = 1;
212 if ($length < 1000) { $tick_spacing=50; }
213 if ($length < 500) { $tick_spacing = 25; }
214 if ($length < 250) { $tick_spacing = 10; }
215 if ($length < 100) { $tick_spacing = 5; }
216 if ($length < 50) { $tick_spacing = 2; }
217 if ($length < 10) { $tick_spacing = 0.5; }
218 if ($length < 1) { $tick_spacing=0.1; }
220 #my $tick_spacing = int($self->get_height()/40); # the spacing of the ticks in map units
222 # the minor ticks need to be at least 10 pixels apart...
224 if ($tick_spacing*$self->{scaling_factor}<10) {
225 print STDERR "tick spacing too small... setting to 10.\n";
226 $tick_spacing=10;
228 my $label_spacing = 2 * $tick_spacing; # the spacing of the labels in map units
231 # if the labels overlap, then we increment the label_spacing such that they don't.
233 if ($self->{scaling_factor}) {
234 #otherwise this is an infinite loop....
235 while (($label_spacing * abs($self->{scaling_factor})) < ($self->{font}->height())) {
236 $label_spacing +=10;
237 print STDERR "Extending label_spacing... $label_spacing scaling: $self->{scaling_factor}\n";
240 #if ($self->{end_value} < 100) { $label_spacing=10; $tick_spacing=5; }
241 my $tick_number = int($self->{end_value}-$self->{start_value})/$tick_spacing;
243 for (my $i=0; $i<$tick_number; $i++) {
244 my $y = $self->get_vertical_offset() + (($i*$tick_spacing)*$self->{scaling_factor});
245 $image -> line($self->get_horizontal_offset()-2, $y, $self->get_horizontal_offset()+2, $y, $color);
247 if ($i*$tick_spacing % $label_spacing ==0) {
248 if ($self->{label_side} eq "left") {
249 $image -> string($self->{font}, $self->get_horizontal_offset()-$self->{font}->width*length($i*$tick_spacing)-2, $y - $self->{font}->height/2, $i*$tick_spacing, $color);
251 if ($self->{label_side} eq "right") {
252 $image -> string($self->{font}, $self->get_horizontal_offset()+4, $y - $self->{font}->height/2, $i*$tick_spacing, $color);
256 my $label = "[".$self->{unit}."]";
257 $image -> string($self->{font}, $self->get_horizontal_offset()-$self->{font}->width()*length($label)/2, $self->get_vertical_offset()-$self->{font}->height()-3, $label, $color);
261 sub _calculate_scaling_factor {
262 my $self = shift;
263 my $dist = ($self->{end_value}-$self->{start_value});
264 if ($dist ==0) { return 0; }
265 $self -> {scaling_factor} = $self->{height}/($self -> {end_value} - $self->{start_value});
266 return $self->{scaling_factor};