File Coverage

blib/lib/Chart/Split.pm
Criterion Covered Total %
statement 188 318 59.1
branch 51 142 35.9
condition 11 23 47.8
subroutine 8 8 100.0
pod n/a
total 258 491 52.5


line stmt bran cond sub pod time code
1             #====================================================================
2             # Chart::Split
3             #
4             # written by Chart-Group
5             #
6             # maintained by the Chart Group
7             # Chart@wettzell.ifag.de
8             #
9             #---------------------------------------------------------------------
10             # History:
11             #----------
12             # $RCSfile: Split.pm,v $ $Revision: 1.2 $ $Date: 2003/02/14 14:25:30 $
13             # $Author: dassing $
14             # $Log: Split.pm,v $
15             # Revision 1.2 2003/02/14 14:25:30 dassing
16             # First setup to cvs
17             #
18             #====================================================================
19              
20             package Chart::Split;
21              
22 2     2   66 use Chart::Base 2.3;
  2         52  
  2         38  
23 2     2   41 use GD;
  2         18  
  2         37  
24 2     2   37 use Carp;
  2         20  
  2         35  
25 2     2   37 use strict;
  2         19  
  2         30  
26              
27             @Chart::Split::ISA = qw(Chart::Base);
28             $Chart::Split::VERSION = '2.3';
29              
30             #>>>>>>>>>>>>>>>>>>>>>>>>>>#
31             # public methods go here #
32             #<<<<<<<<<<<<<<<<<<<<<<<<<<#
33              
34              
35              
36             #>>>>>>>>>>>>>>>>>>>>>>>>>>>#
37             # private methods go here #
38             #<<<<<<<<<<<<<<<<<<<<<<<<<<<#
39              
40             #draw the ticks
41             sub _draw_x_number_ticks {
42 2     2   20     my $self = shift;
43 2         20     my $data = $self->{'dataref'};
44 2         22     my $font = $self->{'tick_label_font'};
45 2         26     my $textcolor = $self->_color_role_to_index('text');
46 2         31     my $misccolor = $self->_color_role_to_index('misc');
47 2         26     my $num_points = $self->{'num_datapoints'};
48 2         20     my ($h, $w, $width, $step, $start, $interval, $label, $stag, @labels);
49 2         20     my ($x_start, $y_start, $y, $x, $lines, $delta, $ticks);
50 2         24     my $x_label_len = 1;
51 2         19     my $y_label_len = 1;
52 2         19     my $x_max = -0x80000000;
53                 
54 2         134     $self->{'grid_data'}-> {'x'} = [];
55              
56             # find the width
57 2 50       25     $width = $self->{'curr_x_max'} - $self->{'curr_x_min'}; $width = 1 if $width == 0;
  2         26  
58              
59             # make sure we got a real font
60 2 50       28     unless ((ref $font) eq 'GD::Font') {
61 0         0            croak "The tick label font you specified isn\'t a GD Font object";
62                 }
63              
64             # find out how big the font is
65 2         44     ($w, $h) = ($font->width, $font->height);
66              
67 2 50 33     41     unless (defined $self->{'start'} && defined $self->{'interval'}) {
68 0         0            croak "I need two values from you to draw a split chart: start and interval!";
69                 }
70                 else {
71 2         22       $interval = $self->{'interval'};
72 2         19       $start = $self->{'start'};
73 2         20       $ticks = $self->{'interval_ticks'}-1;
74 2         19       $label = $start;
75                 }
76              
77              
78             #look after devision by zero!
79 2 50       23     if ( $ticks ==0 ) { $ticks=1; }
  0         0  
80                 
81             #calculate the step between the ticks
82 2         21     $step = $interval/$ticks;
83              
84 2         24     for (0..$ticks) {
85 21         268          push @labels, $self->{f_x_tick}-> (sprintf ("%.".$self->{'precision'}."f", $label));
86 21         220          $label += $step;
87                 }
88              
89             #find the biggest x value
90 2         19     foreach (@{$data->[0]}) {
  2         26  
91 5201 50       57237       if ($_ > $x_max) {
92 5201         48076         $x_max = $_;
93                   }
94                 }
95              
96             #find the length of the x and y labels
97 2         111     foreach (@labels) {
98 21 100       223       if (length($_) > $x_label_len) {
99 1         10         $x_label_len = length($_);
100                   }
101                 }
102                 
103             #find the amount of lines
104 2         27     $lines = int((($x_max-$start) / $interval)+0.99999999999);
105 2 50       27     $lines = 1 if $lines == 0;
106                 
107             #find the length, of the label.
108 2         21     $y_label_len = length($lines);
109              
110             #get the starting point and the width
111 2 50       25     if ($lines > 1) { #if there are y-ticks
112 2 50       43      if ($self->{'y_axes'} =~ /^right$/i) {
    50          
113 0         0        $x_start = $self->{'curr_x_min'} ;
114 0         0        $width = $self->{'curr_x_max'}-$x_start - $self->{'text_space'}*2- $y_label_len*$w-$self->{'tick_len'};
115              
116                  }
117                  elsif ($self->{'y_axes'} =~ /^both$/i) {
118 0         0         $x_start = $self->{'curr_x_min'} + ($w * $y_label_len) +2*$self->{'text_space'} + $self->{'tick_len'};
119 0         0         $width = $self->{'curr_x_max'} - $x_start- ($w * $y_label_len)
120                              - 2 * $self->{'text_space'} - $self->{'tick_len'};
121                  }
122                  else {
123 2         25          $x_start = $self->{'curr_x_min'} + ($w * $y_label_len)
124                      + 3 * $self->{'text_space'} ;
125 2         41          $width = $self->{'curr_x_max'} - $x_start;
126                  }
127                 }
128                 else { #if there are no y-axes
129 0         0      $x_start = $self->{'curr_x_min'};
130 0         0      $width = $self->{'curr_x_max'} - $x_start;
131                 }
132                 
133             #and the y_start value
134 2         22     $y_start = $self->{'curr_y_max'} - $h - $self->{'text_space'};
135                 
136             #get the delta value
137 2         22     $delta = $width / ($ticks);
138              
139 2 50       26     if ( ! defined($self->{'skip_x_ticks'}) ) {
140 2         25      $self->{'skip_x_ticks'} = 1;
141                 }
142             #draw the labels
143 2 50       28     if ($self->{'x_ticks'} =~ /^normal$/i ) {
    0          
    0          
144 2 50       29       if ($self->{'skip_x_ticks'} > 1) { #draw a normal tick every nth label
    50          
145 0         0          for ( 0..$#labels-1) {
146 0 0       0              if ( defined ($labels[$_*$self->{'skip_x_ticks'}]) ) {
147 0         0                 $x = $x_start + $delta*($_*$self->{'skip_x_ticks'})
148                                  - ($w * length($labels[$_*$self->{'skip_x_ticks'}]))/2;
149 0         0                 $self->{'gd_obj'}->string($font, $x, $y_start,$labels[$_*$self->{'skip_x_ticks'}], $textcolor);
150                          }
151                      }
152                   }
153                   elsif($self->{'custom_x_ticks'}) { #draw only the normal ticks they wanted
154 0         0          foreach (@{$self->{'custom_x_ticks'}}) {
  0         0  
155 0 0       0              if ( defined $labels[$_] ) {
156 0         0                 $x = $x_start + $delta*$_ - ($w * length($labels[$_]))/2;
157 0         0                 $self->{'gd_obj'}->string($font, $x, $y_start, $labels[$_], $textcolor);
158                          }
159                      }
160                   }
161                   else {
162 2         28         for (0..$#labels) { #draw all ticks normal
163 21 50       219             if ( defined $labels[$_] ) {
164 21         191                $x = $x_start + $delta*($_) - ($w * length($labels[$_]))/2;
165 21         378                $self->{'gd_obj'}->string($font, $x, $y_start,$labels[$_], $textcolor);
166                         }
167                     }
168                   }
169                 }
170                 elsif ($self->{'x_ticks'} =~ /^staggered$/i ) {
171 0         0       $stag = 0;
172 0 0       0       if ($self->{'skip_x_ticks'} > 1 ) { #draw a staggered tick every nth label
    0          
173 0         0          for ( 0..$#labels-1) {
174 0 0       0              if ( defined ($labels[$_*$self->{'skip_x_ticks'}])) {
175 0         0                $x = $x_start + $delta*($_*$self->{'skip_x_ticks'})
176                                  - ($w * length($labels[$_*$self->{'skip_x_ticks'}]))/2;
177 0 0       0                if ($stag % 2 == 0) {
178 0         0                   $y_start -= $self->{'text_space'} + $h;
179                            }
180 0         0                $self->{'gd_obj'}->string($font, $x, $y_start,$labels[$_*$self->{'skip_x_ticks'}], $textcolor);
181 0 0       0                if ($stag % 2 == 0) {
182 0         0                   $y_start += $self->{'text_space'} + $h;
183                            }
184 0         0                $stag++;
185                          }
186                      }
187                   }
188                   elsif ($self->{'custom_x_ticks'}) { # draw only the wanted ticks staggered
189 0         0          foreach (sort (@{$self->{'custom_x_ticks'}})) {
  0         0  
190 0 0       0              if ( defined $labels[$_]) {
191 0         0                 $x = $x_start + $delta*$_ - ($w*(length($labels[$_])))/2;
192 0 0       0                 if ($stag % 2 == 0) {
193 0         0                   $y_start -= $self->{'text_space'} + $h;
194                             }
195 0         0                 $self->{'gd_obj'}->string($font, $x, $y_start,$labels[$_], $textcolor);
196 0 0       0                 if ($stag % 2 == 0) {
197 0         0                   $y_start += $self->{'text_space'} + $h;
198                             }
199 0         0                 $stag++;
200                          }
201                      }
202                   }
203                   else { # draw all ticks staggered
204 0         0          for (0..$#labels) {
205 0 0       0             if ( defined $labels[$_] ) {
206 0         0                $x = $x_start + $delta*$_ -($w*(length($labels[$_])))/2;
207 0 0       0               if ($stag % 2 == 0) {
208 0         0                   $y_start -= $self->{'text_space'} + $h;
209                           }
210 0         0               $self->{'gd_obj'}->string($font, $x, $y_start,$labels[$_], $textcolor);
211 0 0       0               if ($stag % 2 == 0) {
212 0         0                   $y_start += $self->{'text_space'} + $h;
213                           }
214 0         0               $stag++;
215                         }
216                      }
217                   }
218                 }
219                 elsif ( $self->{'x_ticks'} =~ /^vertical$/i ) {
220 0         0        $y_start = $self->{'curr_y_max'} - $self->{'text_space'};
221 0 0       0        if ( $self->{'skip_x_ticks'} > 1) { #draw every nth tick vertical
    0          
222 0         0           for (0..$#labels) {
223 0 0       0               if (defined $_) {
224 0         0                  $x = $x_start + $delta*($_ * $self->{'skip_x_ticks'}) - $h/2;
225 0         0                  $y = $y_start - ($x_label_len- length($labels[$_*$self->{'skip_x_ticks'}]))*$w;
226 0         0                  $self->{'gd_obj'}->stringUp($font, $x, $y,$labels[$_*$self->{'skip_x_ticks'}], $textcolor);
227                           }
228                       }
229                    }
230                    elsif ( $self->{'custom_x_ticks'} ) {
231 0         0           foreach ( @{$self->{'custom_x_ticks'}}) { #draw the ticks they want vertical
  0         0  
232 0 0       0              if (defined $labels[$_]) {
233 0         0                 $x = $x_start + $delta*$_ - $h/2;
234 0         0                 $y = $y_start - ($x_label_len- length($labels[$_]))*$w;
235 0         0                 $self->{'gd_obj'}->stringUp($font, $x, $y,$labels[$_], $textcolor);
236                          }
237                       }
238                    }
239                    else { # draw all ticks vertical
240 0         0           for ( 0..$#labels) {
241 0 0       0               if ( defined $labels[$_]) {
242 0         0                  $x = $x_start + $delta*$_ - $h/2;
243 0         0                  $y = $y_start - ($x_label_len- length($labels[$_]))*$w;
244 0         0                  $self->{'gd_obj'}->stringUp($font, $x, $y,$labels[$_], $textcolor);
245                           }
246                       }
247                    }
248                    
249                 }
250                 
251             #update the borders
252 2 100       28     if ($self->{'interval_ticks'} > 0) {
253 1 50       13      if ($self->{'x_ticks'} =~ /^normal$/i ) {
    0          
    0          
254 1         13         $self->{'curr_y_max'} -= $h + $self->{'text_space'}*2;
255                  }
256                  elsif ($self->{'x_ticks'} =~ /^staggered$/i ) {
257 0         0         $self->{'curr_y_max'} -= 2*$h + 3*$self->{'text_space'};
258                  }
259                  elsif ($self->{'x_ticks'} =~ /^vertical$/i ) {
260 0         0         $self->{'curr_y_max'} -= $w * $x_label_len + $self->{'text_space'} * 2;
261                  }
262                 }
263                 
264             #draw the ticks
265 2         20     $y_start = $self->{'curr_y_max'};
266 2         19     $y = $y_start - $self->{'tick_len'};
267              
268 2 50       28     if ($self->{'skip_x_ticks'} > 1) {
    50          
269 0         0        for ( 0..int(($#labels )/$self->{'skip_x_ticks'})) {
270 0         0            $x = $x_start + $delta*($_*$self->{'skip_x_ticks'}) ;
271 0         0            $self->{'gd_obj'}->line($x, $y_start, $x, $y, $misccolor);
272 0 0 0     0            if ( $self->{'grid_lines'} =~ /^true$/i or $self->{'x_grid_lines'} =~ /^true$/i) {
273 0         0                 $self->{'grid_data'} ->{'x'}->[$_] = $x;
274                        }
275                    }
276                 }
277                 elsif ($self->{'custom_x_ticks'}) {
278 0         0        foreach (@{$self->{'custom_x_ticks'}}) {
  0         0  
279 0 0       0            if ($_ <= $ticks) {
280 0         0               $x = $x_start + $delta*$_;
281 0         0               $self->{'gd_obj'}->line($x, $y_start, $x, $y, $misccolor);
282 0 0 0     0               if ( $self->{'grid_lines'} =~ /^true$/i or $self->{'x_grid_lines'} =~ /^true$/i) {
283 0         0                 $self->{'grid_data'} ->{'x'}->[$_] = $x;
284                           }
285                        }
286                    }
287                 }
288                 else {
289 2         25        for (0..$#labels) {
290 21         181            $x = $x_start + $_*$delta;
291 21         349            $self->{'gd_obj'}->line($x, $y_start, $x, $y, $misccolor);
292 21 50 33     309            if ( $self->{'grid_lines'} =~ /^true$/i or $self->{'x_grid_lines'} =~ /^true$/i) {
293 0         0                 $self->{'grid_data'} ->{'x'}->[$_] = $x;
294                        }
295                    }
296                 }
297                 
298             #another update of the borders
299 2 100       32     $self->{'curr_y_max'} -= $self->{'tick_len'} if $self->{'interval_ticks'} > 0;
300              
301             #finally return
302 2         32     return;
303             }
304              
305             # override the funktion implemented in base
306             sub _draw_x_ticks {
307 2     2   24     my $self = shift;
308              
309             #Use always the _draw_x_tick funktion because we always do a xy_plot!!!
310 2         23     $self->_draw_x_number_ticks();
311                 
312             #and return
313 2         26     return 1;
314             }
315              
316             sub _draw_y_ticks {
317 2     2   23     my $self = shift;
318 2   50     25     my $side = shift || 'left';
319 2         21     my $data = $self->{'dataref'};
320 2         329     my $font = $self->{'tick_label_font'};
321 2         30     my $textcolor = $self->_color_role_to_index('text');
322 2         24     my $misccolor = $self->_color_role_to_index('misc');
323 2         19     my @labels = @{$self->{'y_tick_labels'}};
  2         29  
324 2         21     my $num_points = $self->{'num_datapoints'};
325 2         18     my ($w, $h);
326 2         49     my ($x_start, $x, $y_start, $y, $start, $interval);
327 2         25     my ($height, $delta, $label, $lines,$label_len);
328 2         20     my ($s, $f);
329 2         18     my $x_max = -0x80000000;
330 2         24     $self->{grid_data}->{'y'} = [];
331 2         22     $self->{grid_data}->{'y2'} = [];
332              
333             # find the height
334 2         23     $height = $self->{'curr_y_max'} - $self->{'curr_y_min'};
335              
336             # make sure we got a real font
337 2 50       28     unless ((ref $font) eq 'GD::Font') {
338 0         0            croak "The tick label font you specified isn\'t a GD Font object";
339                 }
340              
341             # find out how big the font is
342 2         37     ($w, $h) = ($font->width, $font->height);
343                 
344             #get the base variables
345 2         22     $interval = $self->{'interval'};
346 2         20     $start = $self->{'start'};
347              
348             #find the biggest x value
349 2         20     foreach (@{$data->[0]}) {
  2         23  
350 5201 50       62192       if ($_ > $x_max) {
351 5201         54990         $x_max = $_;
352                   }
353                 }
354             #calculate the number of lines and the length
355 2         37     $lines = int((($x_max-$start)/ $interval)+0.99999999999);
356 2 50       29     $lines = 1 if $lines == 0;
357 2         22     $label_len = length($lines);
358              
359             #get the space between two lines
360 2         18     $delta = $height / $lines;
361              
362             #now draw them
363 2 50       25     if ($lines > 1) {
364 2 50       40      if ( $side =~ /^right$/i ) {
    50          
365             #get the starting point
366 0         0        $x_start = $self->{'curr_x_max'};
367 0         0        $y_start = $self->{'curr_y_min'};
368              
369             #draw the labels
370 0         0        for $label (0..$lines-1) {
371 0         0            $x = $x_start - $self->{'text_space'} - $label_len*$w;
372 0         0            $y = $y_start + $label*$delta + $delta/2 -$h/2;
373 0         0            $self->{'gd_obj'}->string($font, $x, $y, $label, $textcolor);
374                    }
375              
376             #draw the ticks
377 0         0        for $label ( 0..$lines) {
378 0         0            $x = $x_start - $self->{'text_space'} *2 - $label_len*$w - $self->{'tick_len'};
379 0         0            $y = $y_start + $label*$delta;
380 0         0            $self->{'gd_obj'} ->line( $x_start-$self->{'text_space'}, $y, $x, $y, $misccolor);
381             #add data for grid_lines
382 0         0            push @{$self->{grid_data} ->{'y'}}, $y;
  0         0  
383                    }
384              
385             #update the borders
386 0         0        $self->{'curr_x_max'} = $x_start - $self->{'text_space'}*2- $label_len*$w-$self->{'tick_len'};
387              
388                  }
389              
390                  elsif ( $side =~ /^both$/i) {
391             #get the starting point
392 0         0        $x_start = $self->{'curr_x_min'};
393 0         0        $y_start = $self->{'curr_y_min'};
394              
395             #first the left side
396             #draw the labels
397 0         0        for $label (0..$lines-1) {
398 0         0            $x = $self->{'curr_x_min'}+$self->{'text_space'}*2;
399 0         0            $y = $y_start+ $label*$delta + $delta/2 -$h/2;
400 0         0            $self->{'gd_obj'}->string($font, $x, $y, $self->{'f_y_tick'}->($label), $textcolor);
401                    }
402             #draw the ticks
403 0         0        for $label (0..$lines) {
404 0         0            $x = $x_start + $self->{'text_space'}*2+ $label_len*$w+$self->{'tick_len'};
405 0         0            $y = $y_start+ $label*$delta ;
406 0         0            $self->{'gd_obj'}->line( $x_start+$self->{'text_space'}, $y, $x, $y, $misccolor);
407                    }
408                    
409             #then the right side
410             #get the starting point
411 0         0        $x_start = $self->{'curr_x_max'};
412 0         0        $y_start = $self->{'curr_y_min'};
413              
414             #draw the labels
415 0         0        for $label (0..$lines-1) {
416 0         0            $x = $x_start - $self->{'text_space'} - $label_len*$w;
417 0         0            $y = $y_start + $label*$delta + $delta/2 -$h/2;
418 0         0            $self->{'gd_obj'}->string($font, $x, $y, $self->{'f_y_tick'}->($label), $textcolor);
419                    }
420              
421             #draw the ticks
422 0         0        for $label ( 0..$lines) {
423 0         0            $x = $x_start - $self->{'text_space'} *2 - $label_len*$w - $self->{'tick_len'};
424 0         0            $y = $y_start + $label*$delta;
425 0         0            $self->{'gd_obj'} ->line( $x_start-$self->{'text_space'}, $y, $x, $y, $misccolor);
426             #add data for grid_lines
427 0         0            push @{$self->{grid_data} ->{'y'}}, $y;
  0         0  
428                    }
429             #update the borders
430 0         0        $self->{'curr_x_min'} += $self->{'text_space'}*2 + $label_len*$w+$self->{'tick_len'};
431 0         0        $self->{'curr_x_max'} = $x_start -$self->{'text_space'}*2 - $label_len*$w-$self->{'tick_len'};
432              
433                  }
434                  else {
435              
436             #get the starting point
437 2         24        $x_start = $self->{'curr_x_min'};
438 2         21        $y_start = $self->{'curr_y_min'};
439              
440             #draw the labels
441 2         24        for $label (0..$lines-1) {
442 13         121            $x = $self->{'curr_x_min'}+$self->{'text_space'}*2;
443 13         117            $y = $y_start+ $label*$delta + $delta/2 -$h/2;
444 13         153            $self->{'gd_obj'}->string($font, $x, $y, $self->{'f_y_tick'}->($label), $textcolor);
445                    }
446             #draw the ticks
447 2         22        for $label (0..$lines) {
448 15         153            $x = $x_start + $label_len*$w+$self->{'tick_len'}+$self->{'text_space'}*3;
449 15         125            $y = $y_start+ $label*$delta ;
450 15         195            $self->{'gd_obj'}->line( $x_start+$self->{'text_space'}, $y, $x, $y, $misccolor);
451             #this is also where we have to draw the grid_lines
452 15         119            push @{$self->{grid_data}->{'y'}} , $y;
  15         155  
453                    }
454             #update the borders
455 2         24        $self->{'curr_x_min'} = $x_start + $self->{'text_space'}*3+ $label_len*$w;
456                  }
457              
458                 }
459              
460             #finally return
461 2         31     return 1;
462             }
463              
464              
465             #plot the data
466             sub _draw_data {
467 2     2   22     my $self = shift;
468 2         22     my $data = $self->{'dataref'};
469 2         26     my $misccolor = $self->_color_role_to_index('misc');
470 2 50       21     my $num_points = $self->{'num_datapoints'}; $num_points = 1 if $num_points == 0;
  2         25  
471 2 50       20     my $num_sets = $self->{'num_datasets'}; $num_sets = 1 if $num_sets == 0;
  2         25  
472 2         20     my ($lines, $split, $width, $height, $delta_lines, $delta_sets, $map, $last_line );
473 2         18     my ($akt_line, $akt_set, $akt_point, $color, $x_start, $y_start, $x, $y);
474 2         20     my ($x_last, $y_last, $delta_point, $brush, $mod, $x_interval, $start);
475 2         20     my $i =0;
476 2 50       22     my $interval = ($self->{'max_val'} - $self->{'min_val'}); $interval = 1 if $interval == 0;
  2         48  
477 2         19     my $x_max = -0x80000000;
478                 
479             # find the height and the width
480 2 50       20     $width = $self->{'curr_x_max'} - $self->{'curr_x_min'}; $width = 1 if $width == 0;
  2         24  
481 2 50       21     $height = $self->{'curr_y_max'} - $self->{'curr_y_min'}; $height = 1 if $height == 0;
  2         22  
482              
483             # init the imagemap data field if they asked for it
484 2 50       26     if ($self->{'imagemap'} =~ /^true$/i) {
485 0         0        $self->{'imagemap_data'} = [];
486                 }
487             #get the base values
488 2 50       20     $x_interval = $self->{'interval'}; $x_interval = 1 if $x_interval == 0;
  2         23  
489 2         167     $start = $self->{'start'};
490              
491             #find the biggest x value
492 2         28     foreach (@{$data->[0]}) {
  2         27  
493 5201 50       55248       if ($_ > $x_max) {
494 5201         56396         $x_max = $_;
495                   }
496                 }
497                 
498             #calculate the number of lines
499 2 50       37     $lines = int((($x_max-$start)/ $x_interval)+0.99999999999); $lines = 1 if $lines == 0;
  2         29  
500              
501             #find delta_lines for the space between the lines
502             #and delta_sets for the space of the datasets of one line
503             #and the delta_point for the space between the datapoints
504 2         20     $delta_lines = $height / $lines;
505 2         321     $delta_sets = $delta_lines / $num_sets;
506 2         21     $delta_point = $width / ($x_interval);
507              
508             #find $map, for the y values
509 2         19     $map = $delta_sets / $interval;
510              
511             #find the mod and the y_start value
512             #correct the start value, if scale is set! Otherwise the plot is to high or to low!
513             #The corecction, isn't perfect, but it does a good job in most cases.
514 2 100       33     if ($self->{'min_val'} >= 0) {
    50          
515 1         10          $mod = $self->{'min_val'};
516 1 50       14          if ($self->{'scale'} > 1) {
517 0         0              $y_start = $self->{'curr_y_min'}
518                                    +($interval*$map/2) *($self->{'scale'}-1);
519                      }
520                      else {
521 1         12              $y_start = $self->{'curr_y_min'}
522                      }
523                 }
524                 elsif ($self->{'max_val'} <= 0) {
525 0         0          $mod = $self->{'min_val'};
526 0 0       0          if ($self->{'scale'} > 1) {
527 0         0              $y_start = $self->{'curr_y_min'}
528                                   +($interval*$map/2) *($self->{'scale'}-1);
529                      }
530                      else {
531 0         0              $y_start = $self->{'curr_y_min'};
532                      }
533                 }
534                 else {
535 1         12             $y_start = $self->{'curr_y_min'}+ ($map * $self->{'min_val'});
536 1         18             $mod = 0;
537                 }
538              
539             #The upper right corner is the point, where we start
540 2         20     $x_start = $self->{'curr_x_min'};
541              
542             #draw the lines
543 2         23     for $akt_set (0..$num_sets-1) {
544 3         33       for $akt_point (0..$self->{'num_datapoints'}-1) {
545             #get the color for this dataset
546 9201         156902         $color = $self->_color_role_to_index('dataset'.$akt_set);
547 9201         135866         $brush = $self->_prepare_brush ($color, 'line');
548 9201         207788         $self->{'gd_obj'}->setBrush ($brush);
549                     
550             #start with the first point at line number zero
551 9201         118942         $last_line =0;
552 9201         107563         for $akt_line ($last_line..$lines-1) {
553             #update the last line. That makes it a little bit faster.
554 83603         920012            $last_line = $akt_line;
555                        
556             #Don't try to draw, if there is no data
557 83603 50       1070302            if (defined $data->[0][$akt_point]) {
558 83603 100 100     1325461                if ( $data->[0][$akt_point] <= (($akt_line+1)*$x_interval +$start)
559                                && $data->[0][$akt_point] >= $akt_line*$x_interval + $start) {
560              
561             #the current point
562 9219         120313                  $x = $x_start + ($data->[0][$akt_point]
563                                   - ($akt_line *$x_interval)- ($start))* $delta_point;
564 9219         160131                  $y = $y_start + $akt_line*$delta_lines
565                                   + $akt_set*$delta_sets + $delta_sets
566                                   -($data->[1+$akt_set][$akt_point]-$mod) * $map *$self->{'scale'};
567              
568             #draw the line
569 9219 100       157488                  $self->{'gd_obj'}->line($x_last, $y_last, $x, $y, gdBrushed)if $akt_point!=0;
570                            
571             #calculate the start point for the next line
572             #first if the next point is in the same line
573 9219 100 100     201169                  if ( defined ($data->[0][$akt_point+1]) && $data->[0][$akt_point+1] <= (($akt_line+1)*$x_interval +$start)
      66        
574                                   && $data->[0][$akt_point+1] > $akt_line*$x_interval + $start ){
575 9196         98116                     $x_last = $x;
576 9196         104778                     $y_last = $y;
577                              }
578             #second, if the next point is not in the same line
579                              else {
580 23         207                     $x_last = $self->{'curr_x_min'};
581 23         503                     $y_last = $y_start + ($akt_line+1)*$delta_lines
582                                           + $akt_set*$delta_sets + $delta_sets
583                                           -($data->[1+$akt_set][$akt_point]-$mod) * $map *$self->{'scale'};
584                              }
585              
586             # store the imagemap data if they asked for it
587 9219 50       139067                  if ($self->{'imagemap'} =~ /^true$/i) {
588 0         0 $self->{'imagemap_data'}->[$akt_set][$akt_point-1] = [ $x_last, $y_last ];
589 0         0 $self->{'imagemap_data'}->[$akt_set][$akt_point] = [ $x, $y ];
590                                  }
591                            }
592                            else { #Go to the next line. Maybe the current point is in that line!
593 74384         831441                  next;
594                            }
595                        }
596                        else {
597 0 0       0                if ($self->{'imagemap'} =~ /^true$/i) {
598 0         0 $self->{'imagemap_data'}->[$akt_set][$akt_point-1] = [ undef(), undef() ];
599 0         0 $self->{'imagemap_data'}->[$akt_set][$akt_point] = [ undef(), undef() ];
600                            }
601                        }
602                     }
603                   }
604                 }
605              
606 2         26     $y_start = $self->{'curr_y_min'};
607             #draw some nice little lines
608 2         23     for $akt_set (0..$num_sets-1) {
609 3         30         for $akt_line (0..$lines-1) {
610             #draw a line between the sets at the left side of the chart
611 23         319            $self->{'gd_obj'}->line($x_start,
612                                            $y_start+ $akt_line*$delta_lines + $akt_set*$delta_sets,
613                                            $x_start+$self->{'tick_len'},
614                                            $y_start+ $akt_line*$delta_lines + $akt_set*$delta_sets,
615                                            $misccolor);
616             #draw a line between the sets at the right side of the chart
617 23         333            $self->{'gd_obj'}->line($self->{'curr_x_max'},
618                                            $y_start + $akt_line*$delta_lines + $akt_set*$delta_sets,
619                                            $self->{'curr_x_max'}-$self->{'tick_len'},
620                                            $y_start + $akt_line*$delta_lines + $akt_set*$delta_sets,
621                                            $misccolor);
622                     }
623                 }
624                 
625             #Box it off
626 2         125     $self->{'gd_obj'}->rectangle ($self->{'curr_x_min'},
627                $self->{'curr_y_min'},
628             $self->{'curr_x_max'},
629             $self->{'curr_y_max'},
630             $misccolor);
631              
632             #finally retrun
633 2         30     return;
634             }
635              
636             #be a good modul and return 1
637             1;
638              
639