File Coverage

blib/lib/Chart/Bars.pm
Criterion Covered Total %
statement 59 68 86.8
branch 25 34 73.5
condition n/a
subroutine 5 5 100.0
pod n/a
total 89 107 83.2


line stmt bran cond sub pod time code
1             #====================================================================
2             # Chart::Bars
3             #
4             # written by david bonner
5             # dbonner@cs.bu.edu
6             #
7             # maintained by the Chart Group
8             # Chart@wettzell.ifag.de
9             #
10             #---------------------------------------------------------------------
11             # History:
12             #----------
13             # $RCSfile: Bars.pm,v $ $Revision: 1.4 $ $Date: 2003/02/14 13:10:05 $
14             # $Author: dassing $
15             # $Log: Bars.pm,v $
16             # Revision 1.4 2003/02/14 13:10:05 dassing
17             # Circumvent division of zeros
18             #
19             #====================================================================
20              
21             package Chart::Bars;
22              
23 17     17   500 use Chart::Base 2.3;
  17         520  
  17         290  
24 17     17   379 use GD;
  17         243  
  17         350  
25 17     17   299 use Carp;
  17         156  
  17         280  
26 17     17   284 use strict;
  17         967  
  17         542  
27              
28             @Chart::Bars::ISA = qw(Chart::Base);
29             $Chart::Bars::VERSION = '2.3';
30              
31             #>>>>>>>>>>>>>>>>>>>>>>>>>>#
32             # public methods go here #
33             #<<<<<<<<<<<<<<<<<<<<<<<<<<#
34              
35              
36             #>>>>>>>>>>>>>>>>>>>>>>>>>>>#
37             # private methods go here #
38             #<<<<<<<<<<<<<<<<<<<<<<<<<<<#
39              
40              
41             ## finally get around to plotting the data
42             sub _draw_data {
43 17     17   170   my $self = shift;
44 17         209   my $data = $self->{'dataref'};
45 17         232   my $misccolor = $self->_color_role_to_index('misc');
46 17         173   my ($x1, $x2, $x3, $y1, $y2, $y3);
47 17         193   my ($width, $height, $delta1, $delta2, $map, $mod, $cut, $pink);
48 17         157   my ($i, $j, $color);
49 17         992   my $temp=0;
50              
51             # init the imagemap data field if they wanted it
52 17 100       356   if ($self->{'imagemap'} =~ /^true$/i) {
53 2         40     $self->{'imagemap_data'} = [];
54               }
55              
56             # find both delta values ($delta1 for stepping between different
57             # datapoint names, $delta2 for stepping between datasets for that
58             # point) and the mapping constant
59 17         186   $width = $self->{'curr_x_max'} - $self->{'curr_x_min'};
60 17         177   $height = $self->{'curr_y_max'} - $self->{'curr_y_min'};
61 17 50       291   $delta1 = ( $self->{'num_datapoints'} > 0 ) ? $width / ($self->{'num_datapoints'}*1) : $width; ###
62              
63 17 50       306    $map = ( ($self->{'max_val'} - $self->{'min_val'}) > 0 ) ? $height / ($self->{'max_val'} - $self->{'min_val'}) : $height;
64 17 100       236   if ($self->{'spaced_bars'} =~ /^true$/i) {
65             #OLD: $delta2 = $delta1 / ($self->{'num_datasets'} + 2);
66 16 50       340     $delta2 = ( ($self->{'num_datasets'} + 2) > 0 ) ? $delta1 / ($self->{'num_datasets'} + 2) : $delta1;
67                 }
68               else {
69 1 50       14     $delta2 = ( $self->{'num_datasets'} > 0 ) ? $delta1 / $self->{'num_datasets'} : $delta1;
70               }
71              
72             # get the base x-y values
73 17         197   $x1 = $self->{'curr_x_min'};
74              
75 17 100       285   if ($self->{'min_val'} >= 0) {
    50          
76 12         118     $y1 = $self->{'curr_y_max'};
77 12         119     $mod = $self->{'min_val'};
78               }
79               elsif ($self->{'max_val'} <= 0) {
80 0         0     $y1 = $self->{'curr_y_min'};
81 0         0     $mod = $self->{'max_val'};
82               }
83               else {
84 5         59    $y1 = $self->{'curr_y_min'} + ($map * $self->{'max_val'});
85 5         45    $mod = 0;
86 5         127    $self->{'gd_obj'}->line ($self->{'curr_x_min'}, $y1,
87                                         $self->{'curr_x_max'}, $y1,
88                                         $misccolor);
89               }
90               
91             # draw the bars
92 17         194   for $i (1..$self->{'num_datasets'}) {
93             # get the color for this dataset
94 44         695     $color = $self->_color_role_to_index('dataset'.($i-1));
95                 
96             # draw every bar for this dataset
97 44         521     for $j (0..$self->{'num_datapoints'}) {
98                 
99             # don't try to draw anything if there's no data
100 20406 100       232501       if (defined ($data->[$i][$j])) {
101             # find the bounds of the rectangle
102 20362 100       266323         if ($self->{'spaced_bars'} =~ /^true$/i) {
103 20356         219794           $x2 = ($x1 + ($j * $delta1) + ($i * $delta2));
104             }
105             else {
106 6         61 $x2 = $x1 + ($j * $delta1) + (($i - 1) * $delta2);
107             }
108 20362         206329 $y2 = $y1;
109 20362         189250 $x3 = $x2 + $delta2;
110 20362         241976 $y3 = $y1 - (($data->[$i][$j] - $mod) * $map);
111            
112             #cut the bars off, if needed
113 20362 50       303047         if ($data->[$i][$j] > $self->{'max_val'}) {
    50          
114 0         0            $y3 = $y1 - (($self->{'max_val'} - $mod ) * $map) ;
115 0         0            $cut = 1;
116                     }
117                     elsif ($data->[$i][$j] < $self->{'min_val'}) {
118 0         0            $y3 = $y1 - (($self->{'min_val'} - $mod ) * $map) ;
119 0         0            $cut = 1;
120                     }
121                     else {
122 20362         202669            $cut = 0;
123                     }
124                     
125             # draw the bar
126             ## y2 and y3 are reversed in some cases because GD's fill
127             ## algorithm is lame
128 20362 100       229771 if ($data->[$i][$j] > 0) {
129 10355         182633 $self->{'gd_obj'}->filledRectangle ($x2, $y3, $x3, $y2, $color);
130 10355 100       125863 if ($self->{'imagemap'} =~ /^true$/i) {
131 18         259 $self->{'imagemap_data'}->[$i][$j] = [$x2, $y3, $x3, $y2];
132             }
133             }
134             else {
135 10007         152867 $self->{'gd_obj'}->filledRectangle ($x2, $y2, $x3, $y3, $color);
136 10007 50       132155 if ($self->{'imagemap'} =~ /^true$/i) {
137 0         0 $self->{'imagemap_data'}->[$i][$j] = [$x2, $y2, $x3, $y3];
138             }
139             }
140              
141             # now outline it. outline red if the bar had been cut off
142 20362 50       205017         unless ($cut){
143 20362         386224 $self->{'gd_obj'}->rectangle ($x2, $y3, $x3, $y2, $misccolor);
144                     }
145                     else {
146 0         0           $pink = $self->{'gd_obj'}->colorAllocate(255,0,255);
147 0         0           $self->{'gd_obj'}->rectangle ($x2, $y3, $x3, $y2, $pink);
148                     }
149              
150                    } else {
151 44 100       834 if ($self->{'imagemap'} =~ /^true$/i) {
152 3         45             $self->{'imagemap_data'}->[$i][$j] = [undef(), undef(), undef(), undef()];
153                       }
154            
155                    }
156                   
157                  }
158                
159               }
160                   
161             # and finaly box it off
162 17         1154   $self->{'gd_obj'}->rectangle ($self->{'curr_x_min'},
163                $self->{'curr_y_min'},
164             $self->{'curr_x_max'},
165             $self->{'curr_y_max'},
166             $misccolor);
167 17         553   return;
168              
169             }
170              
171             ## be a good module and return 1
172             1;
173