File Coverage

lib/GD/Graph/Thermometer.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             package GD::Graph::Thermometer;
2              
3 1     1   23829 use warnings;
  1         2  
  1         33  
4 1     1   5 use strict;
  1         3  
  1         32  
5 1     1   4 use Carp;
  1         6  
  1         92  
6 1     1   15467 use CGI;
  1         24581  
  1         7  
7 1     1   480 use GD;
  0            
  0            
8             use GD::Text::Align;
9             use Data::Dumper;
10             use constant PI => 3.14;
11              
12             use vars qw($VERSION);
13             $VERSION = '0.05';
14              
15             my $cgi = CGI->new();
16              
17             sub new {
18             my $self = shift;
19             my $args = shift;
20              
21             my $missing_arguments = 0;
22             foreach my $key qw( goal current ){
23             if(!defined($args->{$key})) { $missing_arguments++ };
24             }
25             if($missing_arguments){
26             croak "GD::Graph::Thermometer requires that the 'goal' and 'current' keys be defined in its constructor. All other arguments are optional and default values will be substituted for any missing values";
27             }
28              
29             if(!defined($args->{'title'})){
30             $args->{'title'} = "";
31             carp "The call to GD::Graph::Thermometer failed to define a title for the resulting graph.";
32             }
33              
34             if(!defined($args->{'width'})){
35             $args->{'width'} = '100';
36             }
37              
38             if(!defined($args->{'height'})){
39             $args->{'height'} = '200';
40             }
41              
42             my $image = new GD::Image($args->{width},$args->{height});
43             my $colors = $self->_define_colors($image, {
44             background_color => $args->{'background_color'},
45             outline_color => $args->{'outline_color'},
46             text_color => $args->{'text_color'},
47             mercury_color => $args->{'mercury_color'}
48             });
49              
50             my $top = ($args->{'height'} * .04);
51             my $bottom = ($args->{'height'} * .80);
52             my $diff = $bottom - $top;
53             my $left_text_margin = ($args->{'width'} * .38);
54             my $diameter = ($args->{'width'} * .36);
55              
56             # background, set tranparent if you want
57             $image->filledRectangle( 0, 0, $args->{'width'}, $args->{'height'}, $colors->{'background_color'} );
58              
59             # $image->rectangle($x1,$y1,$x2,$y2,$color)
60             if($args->{'transparent'} == '1'){
61             $image->transparent($colors->{'background_color'});
62             }
63             $image->rectangle(($args->{'width'} * .16),($args->{'height'} * .04),($args->{'width'} * .32),($args->{'height'} * .85),$colors->{'outline_color'});
64              
65             # $image->filledEllipse($cx,$cy,$width,$height,$color)
66             $image->filledEllipse(($args->{'width'} * .24),($args->{'height'} * .90),($args->{'width'} * .36),($args->{'width'} * .36),$colors->{'mercury_color'});
67            
68             # mercury rising . . .
69             $image->filledRectangle(($args->{'width'} * .16),($args->{'height'} * .80),($args->{'width'} * .32),($args->{'height'} * .85),$colors->{'mercury_color'});
70            
71             # add labels to graph
72             $image = $self->_add_labels($image,$args->{'goal'},$args->{'current'},$colors->{'text_color'},$colors->{'mercury_color'},$left_text_margin,$top,$bottom,$diff,$args->{'width'},$args->{'height'});
73              
74             # display title
75             $self->_display_title($image,$colors->{'text_color'},$args->{'title'},$args->{'width'},$bottom);
76              
77             # render image as a .png file
78             $self->_render_image($image, $args->{'image_path'}, $args->{'type'});
79              
80             return;
81             }
82              
83             sub _render_image {
84             my $self = shift;
85             my $image = shift;
86             my $image_path = shift;
87             my $type = shift;
88              
89             if(!defined($type)){
90             $type = 'png';
91             }
92              
93             if(defined($image_path)){
94             open( "IMAGE", ">", "$image_path") || die "Couldn't open file: $image_path. $!\n";
95             binmode( IMAGE );
96             print IMAGE $image->$type();
97             close IMAGE;
98             } else {
99             print $cgi->header("image/$type");
100             binmode STDOUT;
101             print $image->$type;
102             }
103              
104             return;
105             }
106              
107             sub _add_labels {
108             my($self,$image,$goal,$current,$text_color,$red,$left_text_margin,$top,$bottom,$diff,$w,$h) = @_;
109             my $text = new GD::Text::Align(
110             $image,
111             font => gdTinyFont,
112             text => $goal.' Goal',
113             color => $text_color,
114             valign => "center",
115             halign => "left",
116             );
117            
118             #draw goal at top
119             $text->draw($left_text_margin,$top);
120            
121             #draw start at bottom
122             if (($current / $goal) > .10){
123             $text->set_text('0 Start');
124             $text->draw($left_text_margin,$bottom);
125             }
126             my $curpix = ($h * .80) - ($diff/$goal) * $current;
127              
128             # draw
129             $text->set_text("$current Current");
130             $text->draw($left_text_margin,$curpix);
131             $image->filledRectangle(($w * .16),$curpix,($w * .32),($h * .85),$red);
132             return $image;
133             }
134              
135             sub _display_title {
136             my ($self,$image,$color,$title,$w,$bottom) = @_;
137             my $set_title = GD::Text::Align->new($image,
138             vtitle => 'top',
139             htitle => 'right',
140             color => $color,
141             );
142             $set_title->set_font('arial', 12);
143             $set_title->set_text($title);
144             my @bb = $set_title->bounding_box(($w * .10), $bottom, (PI/2));
145             $set_title->draw(($w * .10),$bottom,(PI/2));
146             return $image;
147             }
148            
149             sub _define_colors {
150             my $self = shift;
151             my $image = shift;
152             my $custom_colors = shift;
153              
154             my $background_color;
155             if (defined($custom_colors->{'background_color'})) {
156             $background_color = $image->colorAllocate(
157             $custom_colors->{'background_color'}[0],
158             $custom_colors->{'background_color'}[1],
159             $custom_colors->{'background_color'}[2]
160             );
161             } else {
162             $background_color = $self->_white($image);
163             }
164              
165             my $outline_color;
166             if (defined($custom_colors->{'outline_color'})) {
167             $outline_color = $image->colorAllocate(
168             $custom_colors->{'outline_color'}[0],
169             $custom_colors->{'outline_color'}[1],
170             $custom_colors->{'outline_color'}[2]
171             );
172             } else {
173             $outline_color = $self->_black($image);
174             }
175              
176             my $text_color;
177             if (defined($custom_colors->{'text_color'})) {
178             $text_color = $image->colorAllocate(
179             $custom_colors->{'text_color'}[0],
180             $custom_colors->{'text_color'}[1],
181             $custom_colors->{'text_color'}[2]
182             );
183             } else {
184             $text_color = $self->_black($image);
185             }
186              
187             my $mercury_color;
188             if (defined($custom_colors->{'mercury_color'})) {
189             $mercury_color = $image->colorAllocate(
190             $custom_colors->{'mercury_color'}[0],
191             $custom_colors->{'mercury_color'}[1],
192             $custom_colors->{'mercury_color'}[2]
193             );
194             } else {
195             $mercury_color = $self->_red($image);
196             }
197              
198             my $colors = {
199             background_color => $background_color,
200             outline_color => $outline_color,
201             text_color => $text_color,
202             mercury_color => $mercury_color
203             };
204              
205             return $colors;
206             }
207              
208             sub _black {
209             my $self = shift;
210             my $image = shift;
211             my $color = $image->colorAllocate(0,0,0);
212             return $color;
213             }
214              
215             sub _white {
216             my $self = shift;
217             my $image = shift;
218             my $color = $image->colorAllocate(255,255,255);
219             return $color;
220             }
221              
222             sub _red {
223             my $self = shift;
224             my $image = shift;
225             my $color = $image->colorAllocate(255,0,0);
226             return $color;
227             }
228              
229             1; # Magic true value required at end of module
230             __END__