r2142 - in packages: . libchart-perl libchart-perl/branches libchart-perl/branches/upstream libchart-perl/branches/upstream/current libchart-perl/branches/upstream/current/Chart libchart-perl/branches/upstream/current/doc libchart-perl/branches/upstream/current/doc/LaTeX libchart-perl/branches/upstream/current/patterns libchart-perl/branches/upstream/current/t

Krzysztof Krzyzaniak eloy at costa.debian.org
Thu Feb 16 14:32:34 UTC 2006


Author: eloy
Date: 2006-02-16 14:32:00 +0000 (Thu, 16 Feb 2006)
New Revision: 2142

Added:
   packages/libchart-perl/
   packages/libchart-perl/branches/
   packages/libchart-perl/branches/upstream/
   packages/libchart-perl/branches/upstream/current/
   packages/libchart-perl/branches/upstream/current/Chart.pod
   packages/libchart-perl/branches/upstream/current/Chart/
   packages/libchart-perl/branches/upstream/current/Chart/Bars.pm
   packages/libchart-perl/branches/upstream/current/Chart/Base.pm
   packages/libchart-perl/branches/upstream/current/Chart/Composite.pm
   packages/libchart-perl/branches/upstream/current/Chart/Direction.pm
   packages/libchart-perl/branches/upstream/current/Chart/ErrorBars.pm
   packages/libchart-perl/branches/upstream/current/Chart/HorizontalBars.pm
   packages/libchart-perl/branches/upstream/current/Chart/Lines.pm
   packages/libchart-perl/branches/upstream/current/Chart/LinesPoints.pm
   packages/libchart-perl/branches/upstream/current/Chart/Mountain.pm
   packages/libchart-perl/branches/upstream/current/Chart/Pareto.pm
   packages/libchart-perl/branches/upstream/current/Chart/Pie.pm
   packages/libchart-perl/branches/upstream/current/Chart/Points.pm
   packages/libchart-perl/branches/upstream/current/Chart/Split.pm
   packages/libchart-perl/branches/upstream/current/Chart/StackedBars.pm
   packages/libchart-perl/branches/upstream/current/Documentation.pdf
   packages/libchart-perl/branches/upstream/current/MANIFEST
   packages/libchart-perl/branches/upstream/current/MANIFEST.SKIP
   packages/libchart-perl/branches/upstream/current/META.yml
   packages/libchart-perl/branches/upstream/current/Makefile
   packages/libchart-perl/branches/upstream/current/Makefile.PL
   packages/libchart-perl/branches/upstream/current/README
   packages/libchart-perl/branches/upstream/current/TODO
   packages/libchart-perl/branches/upstream/current/doc/
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/Aufbau.png
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/Aufbau1.png
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/Documentation.dvi
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/Documentation.pdf
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/Documentation.tex
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/Elemente.png
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/bars.tex
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/base.tex
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/composite.png
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/composite.tex
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/composite_f.png
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/d_bars.png
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/d_hbars4.png
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/d_lines2.png
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/d_linesp2.png
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/d_pareto2.png
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/d_pie3.png
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/definitions.tex
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/description.tex
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/direction.png
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/direction.tex
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/error.png
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/error.tex
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/example.tex
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/hbars.tex
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/lines.tex
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/linespoints.tex
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/mountain-1.png
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/mountain.png
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/mountain.tex
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/ort.png
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/pareto.tex
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/pie.tex
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/points.png
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/points.tex
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/split.tex
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/stacked.tex
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/stackedbars.png
   packages/libchart-perl/branches/upstream/current/doc/LaTeX/stunde.png
   packages/libchart-perl/branches/upstream/current/patterns/
   packages/libchart-perl/branches/upstream/current/patterns/PATTERN0.GIF
   packages/libchart-perl/branches/upstream/current/patterns/PATTERN0.PNG
   packages/libchart-perl/branches/upstream/current/patterns/PATTERN1.GIF
   packages/libchart-perl/branches/upstream/current/patterns/PATTERN1.PNG
   packages/libchart-perl/branches/upstream/current/patterns/PATTERN2.GIF
   packages/libchart-perl/branches/upstream/current/patterns/PATTERN2.PNG
   packages/libchart-perl/branches/upstream/current/patterns/PATTERN3.GIF
   packages/libchart-perl/branches/upstream/current/patterns/PATTERN3.PNG
   packages/libchart-perl/branches/upstream/current/patterns/PATTERN4.GIF
   packages/libchart-perl/branches/upstream/current/patterns/PATTERN4.PNG
   packages/libchart-perl/branches/upstream/current/patterns/PATTERN5.GIF
   packages/libchart-perl/branches/upstream/current/patterns/PATTERN5.PNG
   packages/libchart-perl/branches/upstream/current/pm_to_blib
   packages/libchart-perl/branches/upstream/current/rgb.txt
   packages/libchart-perl/branches/upstream/current/t/
   packages/libchart-perl/branches/upstream/current/t/Humidity.t
   packages/libchart-perl/branches/upstream/current/t/Math_1_over_x.t
   packages/libchart-perl/branches/upstream/current/t/bars.t
   packages/libchart-perl/branches/upstream/current/t/bars_10.t
   packages/libchart-perl/branches/upstream/current/t/bars_2.t
   packages/libchart-perl/branches/upstream/current/t/bars_3.t
   packages/libchart-perl/branches/upstream/current/t/bars_4.t
   packages/libchart-perl/branches/upstream/current/t/bars_5.t
   packages/libchart-perl/branches/upstream/current/t/bars_6.t
   packages/libchart-perl/branches/upstream/current/t/bars_7.t
   packages/libchart-perl/branches/upstream/current/t/bars_8.t
   packages/libchart-perl/branches/upstream/current/t/bars_9.t
   packages/libchart-perl/branches/upstream/current/t/composite.png
   packages/libchart-perl/branches/upstream/current/t/composite.t
   packages/libchart-perl/branches/upstream/current/t/composite_1.t
   packages/libchart-perl/branches/upstream/current/t/composite_2.t
   packages/libchart-perl/branches/upstream/current/t/composite_3.t
   packages/libchart-perl/branches/upstream/current/t/composite_4.t
   packages/libchart-perl/branches/upstream/current/t/composite_5.t
   packages/libchart-perl/branches/upstream/current/t/composite_6.t
   packages/libchart-perl/branches/upstream/current/t/composite_f.t
   packages/libchart-perl/branches/upstream/current/t/direction_1.t
   packages/libchart-perl/branches/upstream/current/t/direction_2.t
   packages/libchart-perl/branches/upstream/current/t/direction_3.t
   packages/libchart-perl/branches/upstream/current/t/direction_4.t
   packages/libchart-perl/branches/upstream/current/t/error_1.t
   packages/libchart-perl/branches/upstream/current/t/error_2.t
   packages/libchart-perl/branches/upstream/current/t/f_ticks.t
   packages/libchart-perl/branches/upstream/current/t/hbars_1.t
   packages/libchart-perl/branches/upstream/current/t/hbars_2.t
   packages/libchart-perl/branches/upstream/current/t/hbars_3.t
   packages/libchart-perl/branches/upstream/current/t/hbars_4.t
   packages/libchart-perl/branches/upstream/current/t/lines.t
   packages/libchart-perl/branches/upstream/current/t/lines_1.t
   packages/libchart-perl/branches/upstream/current/t/lines_2.t
   packages/libchart-perl/branches/upstream/current/t/lines_3.t
   packages/libchart-perl/branches/upstream/current/t/lines_4.t
   packages/libchart-perl/branches/upstream/current/t/lines_5.t
   packages/libchart-perl/branches/upstream/current/t/lines_6.t
   packages/libchart-perl/branches/upstream/current/t/lines_7.t
   packages/libchart-perl/branches/upstream/current/t/lines_8.t
   packages/libchart-perl/branches/upstream/current/t/linespoints.t
   packages/libchart-perl/branches/upstream/current/t/linespoints_1.t
   packages/libchart-perl/branches/upstream/current/t/linespoints_2.t
   packages/libchart-perl/branches/upstream/current/t/linespoints_3.t
   packages/libchart-perl/branches/upstream/current/t/linespoints_4.t
   packages/libchart-perl/branches/upstream/current/t/linespoints_5.t
   packages/libchart-perl/branches/upstream/current/t/linespoints_6.t
   packages/libchart-perl/branches/upstream/current/t/linespoints_7.t
   packages/libchart-perl/branches/upstream/current/t/mapbars.t
   packages/libchart-perl/branches/upstream/current/t/mapcomp.t
   packages/libchart-perl/branches/upstream/current/t/mountain.t
   packages/libchart-perl/branches/upstream/current/t/mountain_2.t
   packages/libchart-perl/branches/upstream/current/t/pareto_1.t
   packages/libchart-perl/branches/upstream/current/t/pareto_2.t
   packages/libchart-perl/branches/upstream/current/t/pareto_3.t
   packages/libchart-perl/branches/upstream/current/t/pie_1.t
   packages/libchart-perl/branches/upstream/current/t/pie_10.t
   packages/libchart-perl/branches/upstream/current/t/pie_2.t
   packages/libchart-perl/branches/upstream/current/t/pie_3.t
   packages/libchart-perl/branches/upstream/current/t/pie_4.t
   packages/libchart-perl/branches/upstream/current/t/pie_5.t
   packages/libchart-perl/branches/upstream/current/t/pie_6.t
   packages/libchart-perl/branches/upstream/current/t/pie_7.t
   packages/libchart-perl/branches/upstream/current/t/pie_8.t
   packages/libchart-perl/branches/upstream/current/t/pie_9.t
   packages/libchart-perl/branches/upstream/current/t/points.t
   packages/libchart-perl/branches/upstream/current/t/points_100.t
   packages/libchart-perl/branches/upstream/current/t/points_2.t
   packages/libchart-perl/branches/upstream/current/t/split_1.t
   packages/libchart-perl/branches/upstream/current/t/split_2.t
   packages/libchart-perl/branches/upstream/current/t/stackedbars.t
   packages/libchart-perl/branches/upstream/current/t/stackedbars_2.t
   packages/libchart-perl/branches/upstream/current/t/stackedbars_3.t
   packages/libchart-perl/tags/
Log:
[svn-inject] Installing original source of libchart-perl

Added: packages/libchart-perl/branches/upstream/current/Chart/Bars.pm
===================================================================
--- packages/libchart-perl/branches/upstream/current/Chart/Bars.pm	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/Chart/Bars.pm	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,172 @@
+#====================================================================
+#  Chart::Bars
+#
+#  written by david bonner
+#  dbonner at cs.bu.edu
+#
+#  maintained by the Chart Group
+#  Chart at wettzell.ifag.de
+#
+#---------------------------------------------------------------------
+# History:
+#----------
+# $RCSfile: Bars.pm,v $ $Revision: 1.4 $ $Date: 2003/02/14 13:10:05 $
+# $Author: dassing $
+# $Log: Bars.pm,v $
+# Revision 1.4  2003/02/14 13:10:05  dassing
+# Circumvent division of zeros
+#
+#====================================================================
+
+package Chart::Bars;
+
+use Chart::Base '2.4.1';
+use GD;
+use Carp;
+use strict;
+
+ at Chart::Bars::ISA = qw(Chart::Base);
+$Chart::Bars::VERSION = '2.4.1';
+
+#>>>>>>>>>>>>>>>>>>>>>>>>>>#
+#  public methods go here  #
+#<<<<<<<<<<<<<<<<<<<<<<<<<<#
+
+
+#>>>>>>>>>>>>>>>>>>>>>>>>>>>#
+#  private methods go here  #
+#<<<<<<<<<<<<<<<<<<<<<<<<<<<#
+
+
+## finally get around to plotting the data
+sub _draw_data {
+  my $self = shift;
+  my $data = $self->{'dataref'};
+  my $misccolor = $self->_color_role_to_index('misc');
+  my ($x1, $x2, $x3, $y1, $y2, $y3);
+  my ($width, $height, $delta1, $delta2, $map, $mod, $cut, $pink);
+  my ($i, $j, $color);
+  my $temp=0;
+ 
+  # init the imagemap data field if they wanted it
+  if ($self->{'imagemap'} =~ /^true$/i) {
+    $self->{'imagemap_data'} = [];
+  }
+
+  # find both delta values ($delta1 for stepping between different
+  # datapoint names, $delta2 for stepping between datasets for that
+  # point) and the mapping constant
+  $width = $self->{'curr_x_max'} - $self->{'curr_x_min'};
+  $height = $self->{'curr_y_max'} - $self->{'curr_y_min'};
+  $delta1 = ( $self->{'num_datapoints'} > 0 ) ? $width / ($self->{'num_datapoints'}*1) : $width;    ###
+ 
+   $map = ( ($self->{'max_val'} - $self->{'min_val'}) > 0 ) ? $height / ($self->{'max_val'} - $self->{'min_val'}) : $height;
+  if ($self->{'spaced_bars'} =~ /^true$/i) {
+    #OLD: $delta2 = $delta1 / ($self->{'num_datasets'} + 2);
+    $delta2 = ( ($self->{'num_datasets'} + 2) > 0 ) ? $delta1 / ($self->{'num_datasets'} + 2) : $delta1;
+    }
+  else {
+    $delta2 = ( $self->{'num_datasets'} > 0 ) ? $delta1 / $self->{'num_datasets'} : $delta1;
+  }
+
+  # get the base x-y values
+  $x1 = $self->{'curr_x_min'};
+
+  if ($self->{'min_val'} >= 0) {
+    $y1 = $self->{'curr_y_max'};
+    $mod = $self->{'min_val'};
+  }
+  elsif ($self->{'max_val'} <= 0) {
+    $y1 = $self->{'curr_y_min'};
+    $mod = $self->{'max_val'};
+  }
+  else {
+   $y1 = $self->{'curr_y_min'} + ($map * $self->{'max_val'});
+   $mod = 0;
+   $self->{'gd_obj'}->line ($self->{'curr_x_min'}, $y1,
+                            $self->{'curr_x_max'}, $y1,
+                            $misccolor);
+  }
+  
+  # draw the bars
+  for $i (1..$self->{'num_datasets'}) {   
+    # get the color for this dataset
+    $color = $self->_color_role_to_index('dataset'.($i-1));        
+    
+    # draw every bar for this dataset
+    for $j (0..$self->{'num_datapoints'}) {
+    
+      # don't try to draw anything if there's no data
+      if (defined ($data->[$i][$j]) && $data->[$i][$j] =~ /^[\-\+]{0,1}\s*[\d\.eE\-\+]+/ ) {
+	# find the bounds of the rectangle
+        if ($self->{'spaced_bars'} =~ /^true$/i) {
+          $x2 = ($x1 + ($j * $delta1) + ($i * $delta2)); 
+	  }
+	else {
+	  $x2 = $x1 + ($j * $delta1) + (($i - 1) * $delta2);
+	}
+	$y2 = $y1;
+	$x3 = $x2 + $delta2;
+	$y3 = $y1 - (($data->[$i][$j] - $mod) * $map);
+	
+        #cut the bars off, if needed
+        if ($data->[$i][$j] > $self->{'max_val'}) {
+           $y3 = $y1 - (($self->{'max_val'} - $mod ) * $map) ;
+           $cut = 1;
+        }
+        elsif  ($data->[$i][$j] < $self->{'min_val'}) {
+           $y3 = $y1 - (($self->{'min_val'} - $mod ) * $map) ;
+           $cut = 1;
+        }
+        else {
+           $cut = 0;
+        }
+        	
+	# draw the bar
+	## y2 and y3 are reversed in some cases because GD's fill
+	## algorithm is lame
+	if ($data->[$i][$j] > 0) {
+	  $self->{'gd_obj'}->filledRectangle ($x2, $y3, $x3, $y2, $color);
+	  if ($self->{'imagemap'} =~ /^true$/i) {
+	    $self->{'imagemap_data'}->[$i][$j] = [$x2, $y3, $x3, $y2];
+	  }
+	}
+	else {
+	  $self->{'gd_obj'}->filledRectangle ($x2, $y2, $x3, $y3, $color);
+	  if ($self->{'imagemap'} =~ /^true$/i) {
+	    $self->{'imagemap_data'}->[$i][$j] = [$x2, $y2, $x3, $y3];
+	  }
+	}
+
+        # now outline it. outline red if the bar had been cut off
+        unless ($cut){
+	  $self->{'gd_obj'}->rectangle ($x2, $y3, $x3, $y2, $misccolor);
+        }
+        else {
+          $pink = $self->{'gd_obj'}->colorAllocate(255,0,255);
+          $self->{'gd_obj'}->rectangle ($x2, $y3, $x3, $y2, $pink);
+        }
+
+       } else {
+	  if ($self->{'imagemap'} =~ /^true$/i) {
+            $self->{'imagemap_data'}->[$i][$j] = [undef(), undef(), undef(), undef()];
+          }
+	 
+       }
+      
+     }
+   
+  }
+      
+  # and finaly box it off 
+  $self->{'gd_obj'}->rectangle ($self->{'curr_x_min'},
+  				$self->{'curr_y_min'},
+				$self->{'curr_x_max'},
+				$self->{'curr_y_max'},
+				$misccolor);
+  return;
+
+}
+
+## be a good module and return 1
+1;

Added: packages/libchart-perl/branches/upstream/current/Chart/Base.pm
===================================================================
--- packages/libchart-perl/branches/upstream/current/Chart/Base.pm	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/Chart/Base.pm	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,3318 @@
+#===================================================================
+#  Chart::Base 
+#
+#  written by david bonner 
+#  dbonner at cs.bu.edu
+#
+#  maintained by the Chart Group
+#  Chart at wettzell.ifag.de
+#---------------------------------------------------------------------
+# History:
+# --------
+# $RCSfile: Base.pm,v $ $Revision: 1.8 $ $Date: 2003/04/08 16:03:41 $
+# $Author: dassing $
+# $Log: Base.pm,v $
+# Revision 1.8  2003/04/08 16:03:41  dassing
+# _draw_y_grid_lines does plot all lines now
+#
+# Revision 1.7  2003/03/20 15:01:11  dassing
+# Some print statements did not go to STDERR
+#
+# Revision 1.6  2003/01/14 13:38:37  dassing
+# Big changes for Version 2.0
+#
+# Revision 1.5  2002/06/19 12:36:58  dassing
+# Correcting some undefines
+#
+# Revision 1.4  2002/06/06 07:38:25  dassing
+# Updates in Function _find_y_scale by David Pottage
+#
+# Revision 1.3  2002/05/31 13:18:02  dassing
+# Release 1.1
+#
+# Revision 1.2  2002/05/29 16:13:20  dassing
+# Changes included by David Pottage
+#
+#=======================================================================
+
+package Chart::Base;
+
+use GD;
+use strict;
+use Carp;
+use FileHandle;
+
+$Chart::Base::VERSION = '2.4.1';
+
+use vars qw(%named_colors);
+
+
+#>>>>>>>>>>>>>>>>>>>>>>>>>>#
+#  public methods go here  #
+#<<<<<<<<<<<<<<<<<<<<<<<<<<#
+
+##  standard nice object creator
+sub new {
+  my $proto = shift;
+  my $class = ref($proto) || $proto;
+  my $self = {};
+
+  bless $self, $class;
+  $self->_init(@_);
+
+  return $self;
+}
+
+
+##  main method for customizing the chart, lets users
+##  specify values for different parameters
+sub set {
+  my $self = shift;
+  my %opts = @_;
+  
+  # basic error checking on the options, just warn 'em
+  unless ($#_ % 2) {
+    carp "Whoops, some option to be set didn't have a value.\n",
+         "You might want to look at that.\n";
+  }
+ 
+  
+  # set the options
+  for (keys %opts) {
+
+    $self->{$_} = $opts{$_};
+    
+    # if someone wants to change the grid_lines color, we should set all
+    # the colors of the grid_lines
+    if ($_ =~ /^colors$/ ) {
+      my %hash = %{$opts{$_}};
+      foreach my $key (sort keys %hash){
+          if ($key =~ /^grid_lines$/) {
+            $self->{'colors'}{'y_grid_lines'} = $hash{'grid_lines'};
+            $self->{'colors'}{'x_grid_lines'} = $hash{'grid_lines'};
+            $self->{'colors'}{'y2_grid_lines'} = $hash{'grid_lines'};
+         }
+      }
+    }
+  }
+
+  # now return
+  return 1;
+}
+
+
+##  Graph API
+sub add_pt {
+  my $self = shift;
+  my @data = @_;
+
+  # error check the data (carp, don't croak)
+  if ($self->{'dataref'} && ($#{$self->{'dataref'}} != $#data)) {
+    carp "New point to be added has an incorrect number of data sets";
+    return 0;
+  }
+
+  # copy it into the dataref
+  for (0..$#data) {
+    push @{$self->{'dataref'}->[$_]}, $data[$_];
+  }
+  
+  # now return
+  return 1;
+}
+
+
+##  more Graph API
+sub add_dataset {
+  my $self = shift;
+  my @data = @_;
+
+  # error check the data (carp, don't croak)
+  if ($self->{'dataref'} && ($#{$self->{'dataref'}->[0]} != $#data)) {
+    carp "New data set to be added has an incorrect number of points";
+  }
+
+  # copy it into the dataref
+  push @{$self->{'dataref'}}, [ @data ];
+  
+  # now return
+  return 1;
+}
+
+# it's also possible to add a complete datafile
+sub add_datafile  {
+   my $self = shift;
+   my $filename = shift;
+   my $format = shift;
+   my ($File, @array);
+   
+   # do some ugly checking to see if they gave me
+   # a filehandle or a file name
+   if ((ref \$filename) eq 'SCALAR') {
+    # they gave me a file name
+    open ($File, $filename) or croak "Can't open the datafile: $filename.\n";
+   }
+   elsif ((ref \$filename) =~ /^(?:REF|GLOB)$/) {
+    # either a FileHandle object or a regular file handle
+    $File = $filename;
+   }
+   else {
+    carp "I'm not sure what kind of datafile you gave me,\n",
+          "but it wasn't a filename or a filehandle.\n";
+   }
+
+   #add the data
+   while(<$File>) {
+      @array = split;
+      if ( $#array > -1 ) {
+        if ($format =~ m/^pt$/i) {
+          $self->add_pt(@array);
+        }
+        elsif ($format =~ m/^set$/i) {
+          $self->add_dataset(@array);
+        }
+        else {
+          carp "Tell me what kind of file you gave me: 'pt' or 'set'\n";
+        }
+      }
+   }
+   close ($File);
+}
+
+##  even more Graph API
+sub clear_data {
+  my $self = shift;
+
+  # undef the internal data reference
+  $self->{'dataref'} = undef;
+
+  # now return
+  return 1;
+}
+
+
+##  and the last of the Graph API
+sub get_data {
+  my $self = shift;
+  my $ref = [];
+  my ($i, $j);
+
+  # give them a copy, not a reference into the object
+  for $i (0..$#{$self->{'dataref'}}) {
+    @{ $ref->[$i] } = @{ $self->{'dataref'}->[$i] }
+## speedup, compared to...
+#   for $j (0..$#{$self->{'dataref'}->[$i]}) {
+#     $ref->[$i][$j] = $self->{'dataref'}->[$i][$j];
+#   }
+  }
+
+  # return it
+  return $ref;
+}
+
+
+##  called after the options are set, this method
+##  invokes all my private methods to actually
+##  draw the chart and plot the data
+sub png {
+  my $self = shift;
+  my $file = shift;
+  my $dataref = shift;
+  my $fh;
+
+  # do some ugly checking to see if they gave me
+  # a filehandle or a file name
+  if ((ref \$file) eq 'SCALAR') {  
+    # they gave me a file name
+    # Try to delete an existing file
+    if ( -f $file ) {
+       my $number_deleted_files = unlink $file;
+       if ( $number_deleted_files != 1 ) {
+          croak "Error: File \"$file\" did already exist, but it fails to delete it"; 
+       }
+    }
+    $fh = FileHandle->new (">$file");
+    if( !defined $fh) { 
+       croak "Error: File \"$file\" could not be created!\n";
+    }
+  }
+  elsif ((ref \$file) =~ /^(?:REF|GLOB)$/) {
+    # either a FileHandle object or a regular file handle
+    $fh = $file;
+  }
+  else {
+    croak "I'm not sure what you gave me to write this png to,\n",
+          "but it wasn't a filename or a filehandle.\n";
+  }
+
+  # allocate the background color
+  $self->_set_colors();
+
+  # make sure the object has its copy of the data
+  $self->_copy_data($dataref);
+
+  # do a sanity check on the data, and collect some basic facts
+  # about the data
+  $self->_check_data();
+
+  # pass off the real work to the appropriate subs
+  $self->_draw();
+
+  # now write it to the file handle, and don't forget
+  # to be nice to the poor ppl using nt
+  binmode $fh;
+
+  print $fh $self->{'gd_obj'}->png();
+  
+  # now exit
+  return 1;
+}
+
+
+##  called after the options are set, this method
+##  invokes all my private methods to actually
+##  draw the chart and plot the data
+sub cgi_png {
+  my $self = shift;
+  my $dataref = shift;
+
+  # allocate the background color
+  $self->_set_colors();
+
+  # make sure the object has its copy of the data
+  $self->_copy_data($dataref);
+
+  # do a sanity check on the data, and collect some basic facts
+  # about the data
+  $self->_check_data();
+
+  # pass off the real work to the appropriate subs
+  $self->_draw();
+
+  # print the header (ripped the crlf octal from the CGI module)
+  if ($self->{no_cache} =~ /^true$/i) {
+      print "Content-type: image/png\015\012Pragma: no-cache\015\012\015\012";
+  } else {
+      print "Content-type: image/png\015\012\015\012";
+  }
+
+  # now print the png, and binmode it first so nt likes us
+  binmode STDOUT;
+  print STDOUT $self->{'gd_obj'}->png();
+
+  # now exit
+  return 1;
+}
+
+##  called after the options are set, this method
+##  invokes all my private methods to actually
+##  draw the chart and plot the data
+sub scalar_png {
+  my $self = shift;
+  my $dataref = shift;
+
+  # make sure the object has its copy of the data
+  $self->_copy_data($dataref);
+
+  # do a sanity check on the data, and collect some basic facts
+  # about the data
+  $self->_check_data();
+
+  # pass off the real work to the appropriate subs
+  $self->_draw();
+
+  # returns the png image as a scalar value, so that
+  # the programmer-user can do whatever the heck
+  # s/he wants to with it
+  $self->{'gd_obj'}->png();
+}
+
+
+##  called after the options are set, this method
+##  invokes all my private methods to actually
+##  draw the chart and plot the data
+sub jpeg {
+  my $self = shift;
+  my $file = shift;
+  my $dataref = shift;
+  my $fh;
+
+  # do some ugly checking to see if they gave me
+  # a filehandle or a file name
+  if ((ref \$file) eq 'SCALAR') {  
+    # they gave me a file name
+    $fh = FileHandle->new (">$file");
+    # they gave me a file name
+    # Try to delete an existing file
+    if ( -f $file ) {
+       my $number_deleted_files = unlink $file;
+       if ( $number_deleted_files != 1 ) {
+          croak "Error: File \"$file\" did already exist, but it fails to delete it"; 
+       }
+    }
+    $fh = FileHandle->new (">$file");
+    if( !defined $fh) { 
+       croak "Error: File \"$file\" could not be created!\n";
+    }
+  }
+  elsif ((ref \$file) =~ /^(?:REF|GLOB)$/) {
+    # either a FileHandle object or a regular file handle
+    $fh = $file;
+  }
+  else {
+    croak "I'm not sure what you gave me to write this jpeg to,\n",
+          "but it wasn't a filename or a filehandle.\n";
+  }
+
+  # allocate the background color
+  $self->_set_colors();
+
+  # make sure the object has its copy of the data
+  $self->_copy_data($dataref);
+
+  # do a sanity check on the data, and collect some basic facts
+  # about the data
+  $self->_check_data;
+
+  # pass off the real work to the appropriate subs
+  $self->_draw();
+
+  # now write it to the file handle, and don't forget
+  # to be nice to the poor ppl using nt
+  binmode $fh;
+  print $fh $self->{'gd_obj'}->jpeg([100]);   # high quality need
+
+  # now exit
+  return 1;
+}
+
+##  called after the options are set, this method
+##  invokes all my private methods to actually
+##  draw the chart and plot the data
+sub cgi_jpeg {
+  my $self = shift;
+  my $dataref = shift;
+
+  # allocate the background color
+  $self->_set_colors();
+
+  # make sure the object has its copy of the data
+  $self->_copy_data($dataref);
+
+  # do a sanity check on the data, and collect some basic facts
+  # about the data
+  $self->_check_data();
+
+  # pass off the real work to the appropriate subs
+  $self->_draw();
+
+  # print the header (ripped the crlf octal from the CGI module)
+  if ($self->{no_cache} =~ /^true$/i) {
+      print "Content-type: image/jpeg\015\012Pragma: no-cache\015\012\015\012";
+  } else {
+      print "Content-type: image/jpeg\015\012\015\012";
+  }
+
+  # now print the png, and binmode it first so nt likes us
+  binmode STDOUT;
+  print STDOUT $self->{'gd_obj'}->jpeg([100]);
+
+  # now exit
+  return 1;
+}
+
+##  called after the options are set, this method
+##  invokes all my private methods to actually
+##  draw the chart and plot the data
+sub scalar_jpeg {
+  my $self = shift;
+  my $dataref = shift;
+
+  # make sure the object has its copy of the data
+  $self->_copy_data($dataref);
+
+  # do a sanity check on the data, and collect some basic facts
+  # about the data
+  $self->_check_data();
+
+  # pass off the real work to the appropriate subs
+  $self->_draw();
+
+  # returns the png image as a scalar value, so that
+  # the programmer-user can do whatever the heck
+  # s/he wants to with it
+  $self->{'gd_obj'}->jpeg([100]);
+}
+
+sub make_gd {
+  my $self = shift;
+  my $dataref = shift;
+
+  # allocate the background color
+  $self->_set_colors();
+
+  # make sure the object has its copy of the data
+  $self->_copy_data($dataref);
+
+  # do a sanity check on the data, and collect some basic facts
+  # about the data
+  $self->_check_data();
+
+  # pass off the real work to the appropriate subs
+  $self->_draw();
+
+  # return the GD::Image object that we've drawn into
+  return $self->{'gd_obj'};
+}
+
+
+##  get the information to turn the chart into an imagemap
+sub imagemap_dump {
+  my $self = shift;
+  my $ref = [];
+  my ($i, $j);
+ 
+  # croak if they didn't ask me to remember the data, or if they're asking
+  # for the data before I generate it
+  unless (($self->{'imagemap'} =~ /^true$/i) && $self->{'imagemap_data'}) {
+    croak "You need to set the imagemap option to true, and then call the png method, before you can get the imagemap data";
+  }
+
+  # can't just return a ref to my internal structures...
+  for $i (0..$#{$self->{'imagemap_data'}}) {
+    for $j (0..$#{$self->{'imagemap_data'}->[$i]}) {
+      $ref->[$i][$j] = [ @{ $self->{'imagemap_data'}->[$i][$j] } ];
+    }
+  }
+
+  # return their copy
+  return $ref;
+}
+
+# determine minimum of an array of values
+sub minimum 
+{
+   my $self = shift;
+   my @array = @_;
+   
+   return undef if !@array;
+   my $min = $array[0];
+   for ( my $iIndex=0; $iIndex < scalar @array; $iIndex++ )
+   {
+      $min = $array[$iIndex] if ( $min > $array[$iIndex] );
+   }
+   $min;
+}
+
+# determine maximum of an array of values
+sub maximum
+{
+   my $self = shift;
+   my @array = @_;
+   
+   return undef if !@array;
+   my $max = $array[0];
+   for ( my $iIndex=0; $iIndex < scalar @array; $iIndex++ )
+   {
+      $max = $array[$iIndex] if ( $max < $array[$iIndex] );
+   }
+   $max;
+}
+
+# arccos(a)
+sub arccos
+{
+   my $self = shift;
+   my $a = shift;
+   
+   return ( atan2( sqrt(1-$a*$a),$a) );
+}
+
+# arcsin(a)
+sub arcsin
+{
+   my $self = shift;
+   my $a = shift;
+   
+   return ( atan2( $a, sqrt(1-$a*$a)) );
+}
+   
+#>>>>>>>>>>>>>>>>>>>>>>>>>>>#
+#  private methods go here  #
+#<<<<<<<<<<<<<<<<<<<<<<<<<<<#
+
+##  initialize all the default options here
+sub _init {
+  my $self = shift;
+  my $x = shift || 400;  # give them a 400x300 image
+  my $y = shift || 300;  # unless they say otherwise
+  
+  # get the gd object
+  $self->{'gd_obj'} = GD::Image->new($x, $y);
+
+  # start keeping track of used space
+  $self->{'curr_y_min'} = 0;
+  $self->{'curr_y_max'} = $y;
+  $self->{'curr_x_min'} = 0;
+  $self->{'curr_x_max'} = $x;
+
+  # use a 10 pixel border around the whole png
+  $self->{'png_border'} = 10;
+
+  # leave some space around the text fields
+  $self->{'text_space'} = 2;
+
+  # and leave some more space around the chart itself
+  $self->{'graph_border'} = 10;
+
+  # leave a bit of space inside the legend box
+  $self->{'legend_space'} = 4;
+  
+  # set some default fonts
+  $self->{'title_font'} = gdLargeFont;
+  $self->{'sub_title_font'} = gdLargeFont;
+  $self->{'legend_font'} = gdSmallFont;
+  $self->{'label_font'} = gdMediumBoldFont;
+  $self->{'tick_label_font'} = gdSmallFont;
+
+  # put the legend on the bottom of the chart
+  $self->{'legend'} = 'right';
+
+  # default to an empty list of labels
+  $self->{'legend_labels'} = [];
+
+  # use 20 pixel length example lines in the legend
+  $self->{'legend_example_size'} = 20;
+
+  # Set the maximum & minimum number of ticks to use.
+  $self->{'y_ticks'} = 6;
+  $self->{'min_y_ticks'} = 6;
+  $self->{'max_y_ticks'} = 100;
+  $self->{'x_number_ticks'} = 1;
+  $self->{'min_x_ticks'} = 6;
+  $self->{'max_x_ticks'} = 100;
+
+  # make the ticks 4 pixels long
+  $self->{'tick_len'} = 4;
+
+  # no custom y tick labels
+  $self->{'y_tick_labels'} = undef;
+  
+  # no patterns
+  $self->{'patterns'} = undef;
+
+  # let the lines in Chart::Lines be 6 pixels wide
+  $self->{'brush_size'} = 6;
+
+  # let the points in Chart::Points and Chart::LinesPoints be 18 pixels wide
+  $self->{'pt_size'} = 18;
+
+  # use the old non-spaced bars
+  $self->{'spaced_bars'} = 'true';
+
+  # use the new grey background for the plots
+  $self->{'grey_background'} = 'true';
+
+  # don't default to transparent
+  $self->{'transparent'} = 'false';
+
+  # default to "normal" x_tick drawing
+  $self->{'x_ticks'} = 'normal';
+
+  # we're not a component until Chart::Composite says we are
+  $self->{'component'} = 'false';
+
+  # don't force the y-axes in a Composite chare to be the same
+  $self->{'same_y_axes'} = 'false';
+  
+  # plot rectangeles in the legend instead of lines in a composite chart
+  $self->{'legend_example_height'} = 'false';
+    
+  # don't force integer y-ticks
+  $self->{'integer_ticks_only'} = 'false';
+  
+  # don't forbid a false zero scale.
+  $self->{'include_zero'} = 'false';
+
+  # don't waste time/memory by storing imagemap info unless they ask
+  $self->{'imagemap'} = 'false';
+
+  # default for grid_lines is off
+  $self->{grid_lines} = 'false';
+  $self->{x_grid_lines} = 'false';
+  $self->{y_grid_lines} = 'false';
+  $self->{y2_grid_lines} = 'false';
+
+  # default for no_cache is false.  (it breaks netscape 4.5)
+  $self->{no_cache} = 'false';
+
+  $self->{typeStyle} = 'default';
+
+  # default value for skip_y_ticks for the labels
+  $self->{skip_y_ticks} = 1;
+
+  # default value for skip_int_ticks only for integer_ticks_only
+  $self->{skip_int_ticks} = 1;
+
+  # default value for precision
+  $self->{precision} = 3;	
+
+  # default value for legend label values in pie charts
+  $self->{legend_label_values} = 'value';
+  
+  # default value for the labels in a pie chart
+  $self->{label_values} = 'percent';
+  
+  # default position for the y-axes
+  $self->{y_axes} = 'left';
+  
+  # copies of the current values at the x-ticks function
+  $self->{temp_x_min} = 0;
+  $self->{temp_x_max} = 0;
+  $self->{temp_y_min} = 0;
+  $self->{temp_y_max} = 0;
+
+  # Instance for summe
+  $self->{sum} = 0;
+  
+  # Don't sort the data unless they ask
+  $self->{'sort'} = 'false';
+  
+  # The Interval for drawing the x-axes in the split module
+  $self->{'interval'} = undef;
+  
+  # The start value for the split chart
+  $self->{'start'} = undef;
+  
+  # How many ticks do i have to draw at the x-axes in one interval of a split-plot?
+  $self->{'interval_ticks'} = 6;
+  
+  # Draw the Lines in the split-chart normal
+  $self->{'scale'} = 1;
+  
+  # Make a x-y plot
+  $self->{'xy_plot'} = 'false';
+  
+  # min and max for xy plot
+  $self->{'x_min_val'} =1;
+  $self->{'x_max_val'} =1;
+  
+  # use the same error value in ErrorBars
+  $self->{'same_error'} = 'false';
+  
+
+  # Set the minimum and maximum number of circles to draw in a direction chart
+  $self->{'min_circles'} = 4;
+  $self->{'max_circles'} = 100;
+  
+  # set the style of a direction diagramm
+  $self->{'point'} = 'true';
+  $self->{'line'} = 'false';
+  $self->{'arrow'} = 'false';
+  
+  # The number of angel axes in a direction Chart
+  $self->{'angle_interval'} = 30;
+  
+  # dont use different 'x_axes' in a direction Chart
+  $self->{'pairs'} = 'false';
+  
+  # polarplot for a direction Chart (not yet tested)
+  $self->{'polar'} = 'false';
+  
+  # guiding lines in a Pie Chart
+  $self->{'legend_lines'} = 'false';
+  
+  # Ring Chart instead of Pie
+  $self->{'ring'} = 1; # width of ring; i.e. normal pie
+  
+  # stepline for Lines, LinesPoints
+  $self->{'stepline'}      = 'false';
+  $self->{'stepline_mode'} = 'end'; # begin, end
+  
+  # used function to transform x- and y-tick labels to strings
+  $self->{f_x_tick} = \&_default_f_tick;
+  $self->{f_y_tick} = \&_default_f_tick;
+  $self->{f_z_tick} = \&_default_f_tick;
+  # default color specs for various color roles.
+  # Subclasses should extend as needed.
+  my $d = 0;
+  $self->{'colors_default_spec'} = {
+    background	=> 'white',
+    misc	=> 'black',
+    text	=> 'black',
+    y_label	=> 'black',
+    y_label2	=> 'black',
+    grid_lines	=> 'black',
+    grey_background => 'grey',
+    (map { 'dataset'.$d++ => $_ } qw (red green blue purple peach orange mauve olive pink light_purple light_blue plum yellow turquoise light_green brown 
+                                      HotPink PaleGreen1 DarkBlue BlueViolet orange2 chocolate1 LightGreen pink light_purple light_blue plum yellow turquoise light_green brown 
+                                      pink PaleGreen2 MediumPurple PeachPuff1 orange3 chocolate2 olive pink light_purple light_blue plum yellow turquoise light_green brown 
+                                      DarkOrange PaleGreen3 SlateBlue BlueViolet PeachPuff2 orange4 chocolate3 LightGreen pink light_purple light_blue plum yellow turquoise light_green brown) ),
+
+  };
+  
+  # get default color specs for some color roles from alternate role.
+  # Subclasses should extend as needed.
+  $self->{'colors_default_role'} = {
+    'x_grid_lines'	=> 'grid_lines',
+    'y_grid_lines'	=> 'grid_lines',
+    'y2_grid_lines'	=> 'grid_lines', # should be added by Char::Composite...
+  };
+
+  # and return
+  return 1;
+}
+
+
+##  be nice and leave their data alone
+sub _copy_data {
+  my $self = shift;
+  my $extern_ref = shift;
+  my ($ref, $i, $j);
+
+  # look to see if they used the other api
+  if ($self->{'dataref'}) {
+    # we've already got a copy, thanks
+    return 1;
+  }
+  else {
+    # get an array reference
+    $ref = [];
+    
+    # loop through and copy
+    for $i (0..$#{$extern_ref}) {
+      @{ $ref->[$i] } = @{ $extern_ref->[$i] };
+## Speedup compared to:
+#     for $j (0..$#{$extern_ref->[$i]}) {
+#       $ref->[$i][$j] = $extern_ref->[$i][$j];
+#     }
+    }
+
+    # put it in the object
+    $self->{'dataref'} = $ref;
+  }
+}
+
+
+##  make sure the data isn't really weird
+##  and collect some basic info about it
+sub _check_data {
+  my $self = shift;
+  my $length = 0;
+
+  # first make sure there's something there
+  unless (scalar (@{$self->{'dataref'}}) >= 2) {
+    croak "Call me again when you have some data to chart";
+  }
+
+  # make sure we don't end up dividing by zero if they ask for
+  # just one y_tick
+  if ($self->{'y_ticks'} <= 1) {
+    $self->{'y_ticks'} = 2;
+    carp "The number of y_ticks displayed must be at least 2";
+  }
+
+  # remember the number of datasets
+  $self->{'num_datasets'} = $#{$self->{'dataref'}};
+
+  # remember the number of points in the largest dataset
+  $self->{'num_datapoints'} = 0;
+  for (0..$self->{'num_datasets'}) {
+    if (scalar(@{$self->{'dataref'}[$_]}) > $self->{'num_datapoints'}) {
+      $self->{'num_datapoints'} = scalar(@{$self->{'dataref'}[$_]});
+    }
+  }
+
+  # find good min and max y-values for the plot
+  $self->_find_y_scale;
+  
+
+
+  # find the longest x-tick label
+  $length = 0;
+  for (@{$self->{'dataref'}->[0]}) {
+        next if !defined($_);
+        if (length($self->{f_x_tick}->($_)) > $length) {
+           $length = length ($self->{f_x_tick}->($_));
+        }
+  }
+  if ( $length <= 0 ) { $length = 1; }    # make sure $length is positive and greater 0
+
+  # now store it in the object
+  $self->{'x_tick_label_length'} = $length;
+
+  # find x-scale, if a x-y plot is wanted
+  # makes only sense for some charts
+  if ( $self->{'xy_plot'} =~ /^true$/i && ($self->isa('Chart::Lines') || $self->isa('Chart::Points')
+       || $self->isa('Chart::LinesPoints') || $self->isa('Chart::Split') || $self->isa('Chart::ErrorBars')) ) {
+     $self->_find_x_scale;
+  }
+  
+  return 1;
+}
+
+
+##  plot the chart to the gd object
+sub _draw {
+  my $self = shift;
+  
+## No Longer needed.
+#   # use their colors if they want
+#   if ($self->{'colors'}) {
+#     $self->_set_user_colors();
+#   }
+
+## Moved to png(), cgi_png(), etc.
+#   # fill in the defaults for the colors
+#   $self->_set_colors();
+
+  # leave the appropriate border on the png
+  $self->{'curr_x_max'} -= $self->{'png_border'};
+  $self->{'curr_x_min'} += $self->{'png_border'};
+  $self->{'curr_y_max'} -= $self->{'png_border'};
+  $self->{'curr_y_min'} += $self->{'png_border'};
+
+  # draw in the title
+  $self->_draw_title() if $self->{'title'};
+
+  # have to leave this here for backwards compatibility
+  $self->_draw_sub_title() if $self->{'sub_title'};
+
+  # sort the data if they want to (mainly here to make sure
+  # pareto charts get sorted)
+  $self->_sort_data() if ($self->{'sort'} =~ /^true$/i);
+
+  # start drawing the data (most methods in this will be
+  # overridden by the derived classes)
+  # include _draw_legend() in this to ensure that the legend
+  # will be flush with the chart
+  $self->_plot();
+
+  # and return
+  return 1;
+}
+
+
+%named_colors = (
+  'white'		=> [255,255,255],
+  'black'		=> [0,0,0],
+  'red'			=> [200,0,0],
+  'green'		=> [0,175,0],
+  'blue'		=> [0,0,200],
+  'orange'		=> [250,125,0],
+  'orange2'		=> [238,154,0],
+  'orange3'		=> [205,133,0],
+  'orange4'		=> [139,90,0],
+  'yellow'		=> [225,225,0],
+  'purple'		=> [200,0,200],
+  'light_blue'		=> [0,125,250],
+  'light_green'		=> [125,250,0],
+  'light_purple'	=> [145,0,250],
+  'pink'		=> [250,0,125],
+  'peach'		=> [250,125,125],
+  'olive'		=> [125,125,0],
+  'plum'		=> [125,0,125],
+  'turquoise'		=> [0,125,125],
+  'mauve'		=> [200,125,125],
+  'brown'		=> [160,80,0],
+  'grey'		=> [225,225,225],
+  'HotPink'             => [255,105,180],
+  'PaleGreen1'          => [154,255,154],
+  'PaleGreen2'          => [144,238,144],
+  'PaleGreen3'          => [124,205,124],
+  'PaleGreen4'          => [84,138,84],
+  'DarkBlue'            => [0,0,139],
+  'BlueViolet'          => [138,43,226],
+  'PeachPuff'           => [255,218,185],
+  'PeachPuff1'          => [255,218,185],
+  'PeachPuff2'          => [238,203,173],
+  'PeachPuff3'          => [205,175,149],
+  'PeachPuff4'          => [139,119,101],
+  'chocolate1'          => [255,127,36], 
+  'chocolate2'          => [238,118,33], 
+  'chocolate3'          => [205,102,29], 
+  'chocolate4'          => [139,69,19],
+  'LightGreen'          => [144,238,144],
+  'lavender'            => [230,230,250],
+  'MediumPurple'        => [147,112,219],
+  'DarkOrange'          => [255,127,0],
+  'DarkOrange2'         => [238,118,0],
+  'DarkOrange3'         => [205,102,0],
+  'DarkOrange4'         => [139,69,0],
+  'SlateBlue'           => [106,90,205],
+  'BlueViolet'          => [138,43,226],
+  'RoyalBlue'           => [65,105,225],
+);
+
+
+## No Longer needed.
+##  let the user specify their own colors in $self->{'colors'}
+# sub _set_user_colors {
+#   my $self = shift;
+#   my $color_table = {};
+#   my @rgb;
+#   
+#   # see if they want a different background
+#   if (($self->{'colors'}{'background'}) &&
+#       (scalar(@{$self->{'colors'}{'background'}}) == 3)) {
+#     @rgb = @{$self->{'colors'}{'background'}};
+#     $color_table->{'background'} = $self->{'gd_obj'}->colorAllocate(@rgb);
+#   }
+#   else { # make sure white becomes the background color
+#     @rgb = (255, 255, 255);
+#     $color_table->{'background'} = $self->{'gd_obj'}->colorAllocate(@rgb);
+#   }
+# 
+#   # make the background transparent if they asked nicely
+#   if ($self->{'transparent'} =~ /^true$/i) {
+#     $self->{'gd_obj'}->transparent ($color_table->{'background'});
+#   }
+# 
+#   # next check for the color for the miscellaneous stuff
+#   # (the axes on the plot, the box around the legend, etc.)
+#   if (($self->{'colors'}{'misc'}) &&
+#       (scalar(@{$self->{'colors'}{'misc'}}) == 3)) {
+#     @rgb = @{$self->{'colors'}{'misc'}};
+#     $color_table->{'misc'} = $self->{'gd_obj'}->colorAllocate(@rgb);
+#   }
+# 
+#   # what about the text?
+#   if (($self->{'colors'}{'text'}) &&
+#       (scalar(@{$self->{'colors'}{'text'}}) == 3)) {
+#     @rgb = @{$self->{'colors'}{'text'}};
+#     $color_table->{'text'} = $self->{'gd_obj'}->colorAllocate(@rgb);
+#   }
+# 
+#   # and how about y_labels?
+#   if (($self->{'colors'}{'y_label'}) &&
+#       (scalar(@{$self->{'colors'}{'y_label'}}) == 3)) {
+#     @rgb = @{$self->{'colors'}{'y_label'}};
+#     $color_table->{'y_label'} = $self->{'gd_obj'}->colorAllocate(@rgb);
+#   }
+#  
+#   if (($self->{'colors'}{'y_label2'}) &&
+#       (scalar(@{$self->{'colors'}{'y_label2'}}) == 3)) {
+#     @rgb = @{$self->{'colors'}{'y_label2'}};
+#     $color_table->{'y_label2'} = $self->{'gd_obj'}->colorAllocate(@rgb);
+#   }
+# 
+#   # set user-specified "default" grid_lines color 
+#   if (($self->{'colors'}{'grid_lines'}) &&
+#       (scalar(@{$self->{'colors'}{'grid_lines'}}) == 3)) {
+#     @rgb = @{$self->{'colors'}{'grid_lines'}};
+#     $color_table->{'grid_lines'} = $self->{'gd_obj'}->colorAllocate(@rgb);
+#   }
+# 
+#   # x_grid_lines color
+#   if (($self->{'colors'}{'x_grid_lines'}) &&
+#       (scalar(@{$self->{'colors'}{'x_grid_lines'}}) == 3)) {
+#     @rgb = @{$self->{'colors'}{'x_grid_lines'}};
+#     $color_table->{'x_grid_lines'} = $self->{'gd_obj'}->colorAllocate(@rgb);
+#   }
+# 
+#   # y_grid_lines color
+#   if (($self->{'colors'}{'y_grid_lines'}) &&
+#       (scalar(@{$self->{'colors'}{'y_grid_lines'}}) == 3)) {
+#     @rgb = @{$self->{'colors'}{'y_grid_lines'}};
+#     $color_table->{'y_grid_lines'} = $self->{'gd_obj'}->colorAllocate(@rgb);
+#   }
+# 
+#   # y2_grid_lines color
+#   if (($self->{'colors'}{'y2_grid_lines'}) &&
+#       (scalar(@{$self->{'colors'}{'y2_grid_lines'}}) == 3)) {
+#     @rgb = @{$self->{'colors'}{'y2_grid_lines'}};
+#     $color_table->{'y2_grid_lines'} = $self->{'gd_obj'}->colorAllocate(@rgb);
+#   }
+# 
+#   # okay, now go for the data sets
+#   for (keys(%{$self->{'colors'}})) {
+#     if (($_ =~ /^dataset/i) &&
+#         (scalar(@{$self->{'colors'}{$_}}) == 3)) {
+#       @rgb = @{$self->{'colors'}{$_}};
+#       $color_table->{$_} = $self->{'gd_obj'}->colorAllocate(@rgb);
+#     }
+#   }
+# 
+#   # stick the color table in the object
+#   $self->{'color_table'} = $color_table;
+# 
+#   # and return
+#   return 1;
+# }
+
+
+##  specify my colors
+sub _set_colors {
+  my $self = shift;
+  
+
+  my $index = $self->_color_role_to_index('background'); # allocate GD color
+  if ( $self->{'transparent'} =~ m/^true$/i ) {
+    $self->{'gd_obj'}->transparent($index);
+  }
+  # all other roles are initialized by calling $self->_color_role_to_index(ROLENAME);	
+
+
+
+## Replaced by above, and calls to _color_role_to_index method elsewhere.
+#   my ($color_table, @rgb, @colors);
+# 
+#   # check to see if they specified colors
+#   if ($self->{'color_table'}) {
+#     $color_table = $self->{'color_table'};
+#   }
+#   else {
+#     $color_table = {};
+#   }
+#   
+#   # put the background in first
+#   unless ($color_table->{'background'}) {
+#     @rgb = @{$colors{'white'}};
+#     $color_table->{'background'} = $self->{'gd_obj'}->colorAllocate(@rgb);    
+#   }
+# 
+#   # make the background transparent if they asked for it
+#   if ($self->{'transparent'} =~ /^true$/i) {
+#     $self->{'gd_obj'}->transparent ($color_table->{'background'});
+#   }
+# 
+#   # now get all my named colors
+#   for (keys (%colors)) {
+#     @rgb = @{$colors{$_}};
+#     $color_table->{$_} = $self->{'gd_obj'}->colorAllocate(@rgb);
+#   }
+# 
+#   # set up the datatset* colors
+#   @colors = qw (red green blue purple peach orange mauve olive pink light_purple light_blue plum yellow turquoise light_green brown);
+#   for (0..$#colors) {
+#     unless ($color_table->{'dataset'.$_}) { # don't override their colors
+#       $color_table->{'dataset'.$_} = $color_table->{$colors[$_]};
+#     }
+#   }
+# 
+#   # set up the miscellaneous color
+#   unless ($color_table->{'misc'}) {
+#     $color_table->{'misc'} = $color_table->{'black'};
+#   }
+# 
+#   # and the text color
+#   unless ($color_table->{'text'}) {
+#     $color_table->{'text'} = $color_table->{'black'};
+#   }
+# 
+#   unless ($color_table->{'y_label'}) {
+#     $color_table->{'y_label'} = $color_table->{'black'};
+#   }
+#   unless ($color_table->{'y_label2'}) {
+#     $color_table->{'y_label2'} = $color_table->{'black'};
+#   }
+# 
+#   unless ($color_table->{'grid_lines'}) {
+#     $color_table->{'grid_lines'} = $color_table->{'black'};
+#   }
+# 
+#   unless ($color_table->{'x_grid_lines'}) {
+#     $color_table->{'x_grid_lines'} = $color_table->{'grid_lines'};
+#   }
+# 
+#   unless ($color_table->{'y_grid_lines'}) {
+#     $color_table->{'y_grid_lines'} = $color_table->{'grid_lines'};
+#   }
+# 
+#   unless ($color_table->{'y2_grid_lines'}) {
+#     $color_table->{'y2_grid_lines'} = $color_table->{'grid_lines'};
+#   }
+# 
+#   # put the color table back in the object
+#   $self->{'color_table'} = $color_table;
+#   
+#   # and return
+#   return 1; 
+}
+
+sub _color_role_to_index {
+    my $self = shift;
+    
+    # Return a (list of) color index(es) corresponding to the (list of) role(s) in @_.
+    my @result =  map {
+    my $role = $_;
+    my $index = $self->{'color_table'}->{$role};
+    
+    #print STDERR "Role = $_\n"; 
+      
+      unless ( defined $index ) {
+        my $spec = $self->{'colors'}->{$role} 
+          || $self->{'colors_default_spec'}->{$role}
+          || $self->{'colors_default_spec'}->{$self->{'colors_default_role'}->{$role}};
+          
+      
+        my @rgb = $self->_color_spec_to_rgb($role, $spec);
+        #print STDERR "spec = $spec\n";
+       
+        my $string = sprintf " RGB(%d,%d,%d)", map { $_ + 0 } @rgb;
+        
+        $index = $self->{'color_table'}->{$string};
+        unless ( defined $index ) {
+          $index = $self->{'gd_obj'}->colorAllocate(@rgb);
+         $self->{'color_table'}->{$string} = $index;
+        }
+        
+        $self->{'color_table'}->{$role} = $index;
+      }
+      $index;
+    } @_;
+    #print STDERR "Result= ".$result[0]."\n";
+    (wantarray && @_ > 1 ? @result : $result[0]);
+  }
+      
+  sub _color_spec_to_rgb {
+    my $self = shift;
+    my $role = shift; # for error messages
+    my $spec = shift; # [r,g,b] or name
+    my @rgb;
+    if ( ref($spec) eq 'ARRAY' ) {
+      @rgb = @{ $spec };
+      croak "Invalid color RGB array (" . join(',', @rgb) . ") for $role\n" 
+        unless @rgb == 3 && grep( ! m/^\d+$/ || $_ > 255, @rgb) == 0;
+    }
+    elsif ( ! ref($spec) ) {
+      croak "Unknown named color ($spec) for $role\n"
+        unless $named_colors{$spec};
+      @rgb = @{ $named_colors{$spec} };
+    }
+    else {
+      croak "Unrecognized color for $role\n";
+    }
+    @rgb;
+  }
+
+
+##  draw the title for the chart
+sub _draw_title {
+  my $self = shift;
+  my $font = $self->{'title_font'};
+  my $color;
+  my ($h, $w, @lines, $x, $y);
+
+  #get the right color
+  if (defined $self->{'colors'}{'title'} ) {
+      $color = $self->_color_role_to_index('title') ;
+  }
+  else {
+      $color = $self->_color_role_to_index('text') ;
+  }
+  # make sure we're actually using a real font
+  unless ((ref $font) eq 'GD::Font') {
+    croak "The title font you specified isn\'t a GD Font object";
+  }
+
+  # get the height and width of the font
+  ($h, $w) = ($font->height, $font->width);
+
+  # split the title into lines
+  @lines = split (/\\n/, $self->{'title'});
+
+  # write the first line
+  $x = ($self->{'curr_x_max'} - $self->{'curr_x_min'}) / 2
+         + $self->{'curr_x_min'} - (length($lines[0]) * $w) /2;
+  $y = $self->{'curr_y_min'} + $self->{'text_space'};
+  $self->{'gd_obj'}->string($font, $x, $y, $lines[0], $color);
+
+  # now loop through the rest of them
+  for (1..$#lines) {
+    $self->{'curr_y_min'} += $self->{'text_space'} + $h;
+    $x = ($self->{'curr_x_max'} - $self->{'curr_x_min'}) / 2
+           + $self->{'curr_x_min'} - (length($lines[$_]) * $w) /2;
+    $y = $self->{'curr_y_min'} + $self->{'text_space'};
+    $self->{'gd_obj'}->string($font, $x, $y, $lines[$_], $color);
+  }
+
+  # mark off that last space
+  $self->{'curr_y_min'} += 2 * $self->{'text_space'} + $h;
+
+  # and return
+  return 1;
+}
+
+
+##  pesky backwards-compatible sub
+sub _draw_sub_title {
+  my $self = shift;
+  my $font = $self->{'sub_title_font'};
+  my $color = $self->_color_role_to_index('text');
+  my $text = $self->{'sub_title'};
+  my ($h, $w, $x, $y);
+
+  # make sure we're using a real font
+  unless ((ref ($font)) eq 'GD::Font') {
+    croak "The subtitle font you specified isn\'t a GD Font object";
+  }
+
+  # get the size of the font
+  ($h, $w) = ($font->height, $font->width);
+
+  # figure out the placement
+  $x = ($self->{'curr_x_max'} - $self->{'curr_x_min'}) / 2
+         + $self->{'curr_x_min'} - (length($text) * $w) / 2;
+  $y = $self->{'curr_y_min'}; 
+  
+  # now draw the subtitle
+  $self->{'gd_obj'}->string ($font, $x, $y, $text, $color);
+
+  # Adapt curr_y_min
+  $self->{'curr_y_min'} += $self->{'text_space'} + $h;
+
+  # and return
+  return 1;
+}
+
+
+##  sort the data nicely (mostly for the pareto charts and xy-plots)
+sub _sort_data {
+   my $self = shift;
+   my $data_ref = $self->{'dataref'};
+   my @data = @{$self->{'dataref'}};
+   my @sort_index;
+
+   #sort the data with slices
+   @sort_index = sort { $data[0][$a] <=> $data[0][$b] } (0..scalar(@{$data[1]})-1);
+   for (1..$#data) {
+       @{$self->{'dataref'}->[$_]} = @{$self->{'dataref'}->[$_]}[@sort_index];
+   }
+   @{$data_ref->[0]} = sort {$a <=> $b} @{$data_ref->[0]};
+
+   #finally return
+   return 1;
+}
+
+#For a xy-plot do the same for the x values, as _find_y_scale does for the y values!
+sub _find_x_scale {
+    my $self = shift;
+    my @data = @{$self->{'dataref'}};
+    my ($i, $j);
+    my ($d_min, $d_max);
+    my ($p_min, $p_max, $f_min, $f_max);
+    my ($tickInterval, $tickCount, $skip);
+    my @tickLabels;
+    my $maxtickLabelLen = 0;
+    
+    #look, if we have numbers
+    for $i (0..($self->{'num_datasets'})) 
+    {
+        for $j (0..($self->{'num_datapoints'}-1)) 
+        {
+            #the following regular Expression matches all possible numbers, including scientific numbers!!
+            if ($data[$i][$j] !~ m/^[+-]?((\.\d+)|(\d+\.?\d*))([eE][+-]?\d+)?[fFdD]?$/ ) 
+            {
+                croak "<$data[$i][$j]> You should give me numbers for drawing a xy plot!\n";
+            }
+        }
+    }
+    
+    #find the dataset min and max
+    ($d_min, $d_max) = $self->_find_x_range();
+
+   # Force the inclusion of zero if the user has requested it.
+    if( $self->{'include_zero'} =~ m!^true$!i )    
+    {
+        if( ($d_min * $d_max) > 0 ) # If both are non zero and of the same sign.
+        {
+            if( $d_min > 0 ) # If the whole scale is positive.
+            {
+                $d_min = 0;
+            }
+            else	# The scale is entirely negative.
+            {
+    	        $d_max = 0;
+            }
+        }
+   }
+
+   # Calculate the width of the dataset. (possibly modified by the user)
+   my $d_width = $d_max - $d_min;
+
+   # If the width of the range is zero, forcebly widen it
+   # (to avoid division by zero errors elsewhere in the code).
+   if ( 0 == $d_width )  {
+       $d_min--;
+       $d_max++;
+       $d_width = 2;
+   }
+
+   # Descale the range by converting the dataset width into
+   # a floating point exponent & mantisa pair.
+   my( $rangeExponent, $rangeMantisa ) = $self->_sepFP( $d_width );
+   my $rangeMuliplier = 10 ** $rangeExponent;
+
+   # Find what tick
+   # to use & how many ticks to plot,
+   # round the plot min & max to suatable round numbers.
+   ($tickInterval, $tickCount, $p_min, $p_max)
+    = $self->_calcXTickInterval($d_min/$rangeMuliplier, $d_max/$rangeMuliplier,
+				$f_min, $f_max,
+				$self->{'min_x_ticks'}, $self->{'max_x_ticks'});
+   # Restore the tickInterval etc to the correct scale
+   $_ *= $rangeMuliplier foreach($tickInterval, $p_min, $p_max);
+
+   #get teh precision for the labels
+   my $precision = $self->{'precision'};
+
+   # Now sort out an array of tick labels.
+   for( my $labelNum = $p_min; $labelNum<$p_max+$tickInterval/2; $labelNum+=$tickInterval ) 
+   {
+	my $labelText;
+
+        if( defined $self->{f_y_tick} )  {
+           # Is _default_f_tick function used?
+           if ( $self->{f_y_tick} == \&_default_f_tick) {
+                  $labelText = sprintf("%.".$precision."f", $labelNum);
+           }
+           else {
+                  $labelText = $self->{f_y_tick}->($labelNum);
+           }
+        }
+        else {
+           $labelText = sprintf("%.".$precision."f", $labelNum);
+       }
+
+       push @tickLabels, $labelText;
+       $maxtickLabelLen = length $labelText if $maxtickLabelLen < length $labelText;
+   }
+
+   # Store the calculated data.
+   $self->{'x_min_val'} = $p_min;
+   $self->{'x_max_val'} = $p_max;
+   $self->{'x_tick_labels'} = \@tickLabels;
+   $self->{'x_tick_label_length'} = $maxtickLabelLen;
+   $self->{'x_number_ticks'} = $tickCount;
+   return 1;
+}
+
+
+##  find good values for the minimum and maximum y-value on the chart
+# New version, re-written by David Pottage of Tao Group.
+# This code is *AS IS* and comes with *NO WARRANTY*
+#
+# This Sub calculates correct values for the following class local variables,
+# if they have not been set by the user.
+#
+# max_val, min_val: 	The maximum and minimum values for the y axis.
+# 
+# y_ticks:		The number of ticks to plot on the y scale, including
+#			the end points. e.g. If the scale runs from 0 to 50,
+#			with ticks every 10, y_ticks will have the value of 6.
+# 
+# y_tick_labels:	An array of strings, each is a label for the y axis.
+# 
+# y_tick_labels_length:	The length to allow for B tick labels. (How long is
+#						the longest?)	
+
+sub _find_y_scale 
+{
+	my $self = shift;
+	
+	# Predeclare vars.
+	my ($d_min, $d_max);		# Dataset min & max.
+	my ($p_min, $p_max);		# Plot min & max.
+	my ($tickInterval, $tickCount, $skip);
+	my @tickLabels;				# List of labels for each tick.
+	my $maxtickLabelLen = 0;	# The length of the longest tick label.
+	my $prec_test=0;                # Boolean which indicate if precision < |rangeExponent|
+	my $temp_rangeExponent;
+	
+	# Find the datatset minimum and maximum.
+	($d_min, $d_max) = $self->_find_y_range(); 
+
+	# Force the inclusion of zero if the user has requested it.
+	if( $self->{'include_zero'} =~ m!^true$!i )
+	{ 
+	#print "include_zero = true\n";
+	    if( ($d_min * $d_max) > 0 )	# If both are non zero and of the same sign.
+	    {
+	        if( $d_min > 0 )	# If the whole scale is positive.
+		{
+		    $d_min = 0;
+		}
+		else				# The scale is entirely negative.
+		{
+		    $d_max = 0;
+		}
+	    }
+	}
+	
+        if ( $self->{'integer_ticks_only'} =~ /^\d$/ ) 
+        {
+            if ( $self->{'integer_ticks_only'} == 1 ) 
+            {
+                $self->{'integer_ticks_only'} = 'true';
+            } 
+            else 
+            {
+                $self->{'integer_ticks_only'} = 'false';
+            }
+        }
+	if( $self->{'integer_ticks_only'} =~ m!^true$!i )
+	{
+            # Allow the dataset range to be overidden by the user.
+	    # f_min/max are booleans which indicate that the min & max should not be modified.
+	    my $f_min = defined $self->{'min_val'};
+	    $d_min = $self->{'min_val'} if $f_min;
+
+	    my $f_max = defined $self->{'max_val'};
+	    $d_max = $self->{'max_val'} if $f_max;
+
+	    # Assert against the min is larger than the max.
+	    if( $d_min > $d_max )
+	    {
+	        croak "The the specified 'min_val' & 'max_val' values are reversed (min > max: $d_min>$d_max)";
+	    }
+	    # The user asked for integer ticks, force the limits to integers.
+	    # & work out the range directly.
+	    #$p_min = $self->_round2Tick($d_min, 1, -1);
+	    #$p_max = $self->_round2Tick($d_max, 1, 1);
+
+	    $skip = $self->{skip_int_ticks};
+            $skip = 1 if $skip < 1;      
+	    
+            $p_min = $self->_round2Tick($d_min, 1, -1);
+            $p_max = $self->_round2Tick($d_max, 1, 1); 
+            if ( ($p_max - $p_min ) == 0 )
+	    {
+	        $p_max++, $p_min--;
+	    }
+
+	    $tickInterval = $skip;
+            $tickCount = ($p_max - $p_min ) / $skip + 1;
+                
+
+            # Now sort out an array of tick labels.
+                
+	    for( my $labelNum = $p_min; $labelNum<$p_max+$tickInterval/3; $labelNum+=$tickInterval )
+	    {
+                my $labelText;
+		
+		if ( defined $self->{f_y_tick} )
+	        {	
+                    # Is _default_f_tick function used?
+                    if ( $self->{f_y_tick} == \&_default_f_tick) 
+		    {
+		        $labelText = sprintf("%d", $labelNum);
+                    }
+		    else 
+		    {
+			$labelText = $self->{f_y_tick}->($labelNum);	
+                    }
+		}
+		else
+		{
+		    $labelText = sprintf("%d", $labelNum);
+		}	
+		
+                push @tickLabels, $labelText;
+		$maxtickLabelLen = length $labelText if $maxtickLabelLen < length $labelText;
+	    }
+	}
+	else
+	{  
+	    # Allow the dataset range to be overidden by the user.
+	    # f_min/max are booleans which indicate that the min & max should not be modified.
+	    my $f_min = defined $self->{'min_val'};
+	    $d_min = $self->{'min_val'} if $f_min;
+
+	    my $f_max = defined $self->{'max_val'};
+	    $d_max = $self->{'max_val'} if $f_max;
+	    
+	  #  print "fmin $f_min fmax $f_max\n";
+          #  print "dmin $d_min dmax $d_max\n";
+	    
+	    # Assert against the min is larger than the max.
+	    if( $d_min > $d_max )
+	    {
+	        croak "The the specified 'min_val' & 'max_val' values are reversed (min > max: $d_min>$d_max)";
+	    }
+
+	     # Calculate the width of the dataset. (possibly modified by the user)
+	     my $d_width = $d_max - $d_min;
+		
+	     # If the width of the range is zero, forcibly widen it
+	     # (to avoid division by zero errors elsewhere in the code).
+	     if ( $d_width == 0 )
+	     { 
+	   	$d_min--;
+	   	$d_max++;
+	   	$d_width = 2;
+	     }
+		  
+	  		
+             # Descale the range by converting the dataset width into
+             # a floating point exponent & mantisa pair.
+             my( $rangeExponent, $rangeMantisa ) = $self->_sepFP( $d_width );
+	     my $rangeMuliplier = 10 ** $rangeExponent;
+	   
+	    # print "fmin $f_min fmax $f_max\n";
+            # print "dmin $d_min dmax $d_max\n";
+	   		
+	     # Find what tick
+	     # to use & how many ticks to plot,
+	     # round the plot min & max to suitable round numbers.
+	     ($tickInterval, $tickCount, $p_min, $p_max)
+		= $self->_calcTickInterval($d_min/$rangeMuliplier, $d_max/$rangeMuliplier,
+				$f_min, $f_max,
+				$self->{'min_y_ticks'}, $self->{'max_y_ticks'});
+	     # Restore the tickInterval etc to the correct scale
+	     $_ *= $rangeMuliplier foreach($tickInterval, $p_min, $p_max);
+	
+	     # Is precision < |rangeExponent|?
+	     if ($rangeExponent < 0) 
+             {
+	         $temp_rangeExponent = -$rangeExponent;
+             }
+	     else 
+	     {
+	         $temp_rangeExponent = $rangeExponent;
+	     }
+		
+	    # print "pmin $p_min pmax $p_max\n";	
+	    # print "range exponent $rangeExponent\n"; 	
+	     
+            #get the precision for the labels
+	    my $precision = $self->{'precision'};
+	     
+	    if ( $temp_rangeExponent != 0 && $rangeExponent < 0 && $temp_rangeExponent > $precision) 
+            {
+	  	$prec_test = 1;
+	    }
+	   	     	 
+            # Now sort out an array of tick labels.
+            for( my $labelNum = $p_min; $labelNum<$p_max+$tickInterval/2; $labelNum+=$tickInterval )
+	    {
+	        my $labelText;
+		if( defined $self->{f_y_tick} )
+		{
+                    # Is _default_f_tick function used?
+                    if (( $self->{f_y_tick} == \&_default_f_tick) && ($prec_test == 0)) 
+                    {
+		        $labelText = sprintf("%.".$precision."f", $labelNum);
+		    }
+		    # If precision <|rangeExponent| print the labels whith exponents 
+		    elsif (($self->{f_y_tick} == \&_default_f_tick) && ($prec_test == 1)) 
+                    {
+			$labelText = $self->{f_y_tick}->($labelNum); 
+			#  print "precision $precision\n"; 
+			#  print "temp range exponent $temp_rangeExponent\n";
+			#  print "range exponent $rangeExponent\n";
+			#  print "labelText $labelText\n";
+			  
+                    }
+		    else 
+                    {
+			$labelText = $self->{f_y_tick}->($labelNum);
+		    }
+		}
+		else
+		{
+		    $labelText = sprintf("%.".$precision."f", $labelNum);
+		}
+		push @tickLabels, $labelText;
+		$maxtickLabelLen = length $labelText if $maxtickLabelLen < length $labelText;
+	     } # end for
+	}
+	
+	# Store the calculated data.
+        #### begin debugging output
+	#if ( defined $self->{'y_ticks'} )
+        #{
+        #   print "_find_y_scale: self->{'y_ticks'}=".$self->{'y_ticks'}."\n";	
+        #}
+        #else
+        #{
+        #   print "_find_y_scale: self->{'y_ticks'}= NOT DEFINED\n";	
+        #}
+        #if ( defined $self->{'min_val'} )
+        #{
+	#    print "_find_y_scale: self->{'min_val'}=".$self->{'min_val'}."\n";	
+        #}
+        #else
+        #{
+	#    print "_find_y_scale: self->{'min_val'}=NOT DEFINED\n";	
+        #}
+        #if ( defined $self->{'max_val'} )
+        #{
+	#    print "_find_y_scale: self->{'max_val'}=".$self->{'max_val'}."\n";
+        #}
+        #else
+        #{
+	#    print "_find_y_scale: self->{'max_val'}= NOT DEFINED\n";
+        #}	
+        #### end debugging output
+        
+        $self->{'min_val'}             = $p_min;
+        $self->{'max_val'}             = $p_max;
+	$self->{'y_ticks'}             = $tickCount;
+	$self->{'y_tick_labels'}       = \@tickLabels;
+	$self->{'y_tick_label_length'} = $maxtickLabelLen;
+        
+	
+	# and return.
+	return 1;
+}
+
+
+
+# Calculates the tick  in normalised units.
+# Result will need multiplying by the multipler to get the true tick interval.
+# written by David Pottage of Tao Group.
+sub _calcTickInterval
+{       my $self = shift;
+	my(
+		$min, $max,		# The dataset min & max.
+		$minF, $maxF,	# Indicates if those min/max are fixed.
+		$minTicks, $maxTicks,	# The minimum & maximum number of ticks.
+	) = @_;
+	
+#	print "calcTickInterval min $min max $max minF $minF maxF $maxF\n"; 
+	
+	# Verify the supplied 'min_y_ticks' & 'max_y_ticks' are sensible.
+	if( $minTicks < 2 )
+	{
+		#print STDERR "Chart::Base : Incorrect value for 'min_y_ticks', too small (less than 2).\n";
+		$minTicks = 2;
+	}
+	
+	if( $maxTicks < 5*$minTicks  )
+	{
+		#print STDERR "Chart::Base : Incorrect value for 'max_y_ticks', too small (<5*minTicks).\n";
+		$maxTicks = 5*$minTicks;
+	}
+	
+	my $width = $max - $min;
+	my @divisorList;
+	
+	for( my $baseMul = 1; ; $baseMul *= 10 )
+	{
+		TRY: foreach my $tryMul (1, 2, 5)
+		{
+			# Calc a fresh, smaller tick interval.
+			my $divisor = $baseMul * $tryMul;
+			
+			# Count the number of ticks.
+			my ($tickCount, $pMin, $pMax) = $self->_countTicks($min, $max, 1/$divisor);
+			
+			# Look a the number of ticks.
+			if( $maxTicks < $tickCount )
+			{
+				# If it is to high, Backtrack.
+				$divisor = pop @divisorList;
+                                # just for security:
+                                if ( !defined($divisor) || $divisor == 0 ) { $divisor = 1; } 
+				($tickCount, $pMin, $pMax) = $self->_countTicks($min, $max, 1/$divisor);
+				#print STDERR "\nChart::Base : Caution: Tick limit of $maxTicks exceeded. Backing of to an interval of ".1/$divisor." which plots $tickCount ticks\n";
+				return(1/$divisor, $tickCount, $pMin, $pMax);
+			}
+			elsif( $minTicks > $tickCount )
+			{
+				# If it is to low, try again.
+				next TRY;
+			}
+			else
+			{
+				# Store the divisor for possible later backtracking.
+				push @divisorList, $divisor;
+			
+				# if the min or max is fixed, check they will fit in the interval.
+				next TRY if( $minF && ( int ($min*$divisor) != ($min*$divisor) ) );
+				next TRY if( $maxF && ( int ($max*$divisor) != ($max*$divisor) ) );
+				
+				# If everything passes the tests, return.
+				return(1/$divisor, $tickCount, $pMin, $pMax)
+			}
+		}
+	}
+	
+	die "can't happen!";
+}
+
+
+sub _calcXTickInterval
+{       my $self = shift;
+	my(
+		$min, $max,		# The dataset min & max.
+		$minF, $maxF,	# Indicates if those min/max are fixed.
+		$minTicks, $maxTicks,	# The minimum & maximum number of ticks.
+	) = @_;
+
+	# Verify the supplied 'min_y_ticks' & 'max_y_ticks' are sensible.
+	if( $minTicks < 2 )
+	{
+		#print STDERR "Chart::Base : Incorrect value for 'min_y_ticks', too small.\n";
+		$minTicks = 2;
+	}
+
+	if( $maxTicks < 5*$minTicks  )
+	{
+		#print STDERR "Chart::Base : Incorrect value for 'max_y_ticks', to small.\n";
+		$maxTicks = 5*$minTicks;
+	}
+
+	my $width = $max - $min;
+	my @divisorList;
+
+	for( my $baseMul = 1; ; $baseMul *= 10 )
+	{
+		TRY: foreach my $tryMul (1, 2, 5)
+		{
+			# Calc a fresh, smaller tick interval.
+			my $divisor = $baseMul * $tryMul;
+
+			# Count the number of ticks.
+			my ($tickCount, $pMin, $pMax) = $self->_countTicks($min, $max, 1/$divisor);
+
+			# Look a the number of ticks.
+			if( $maxTicks < $tickCount )
+			{
+				# If it is to high, Backtrack.
+				$divisor = pop @divisorList;
+                                # just for security:
+                                if ( !defined($divisor) || $divisor == 0 ) { $divisor = 1; }
+				($tickCount, $pMin, $pMax) = $self->_countTicks($min, $max, 1/$divisor);
+				#print STDERR "\nChart::Base : Caution: Tick limit of $maxTicks exceeded. Backing of to an interval of ".1/$divisor." which plots $tickCount ticks\n";
+				return(1/$divisor, $tickCount, $pMin, $pMax);
+			}
+			elsif( $minTicks > $tickCount )
+			{
+				# If it is to low, try again.
+				next TRY;
+			}
+			else
+			{
+				# Store the divisor for possible later backtracking.
+				push @divisorList, $divisor;
+
+				# if the min or max is fixed, check they will fit in the interval.
+				next TRY if( $minF && ( int ($min*$divisor) != ($min*$divisor) ) );
+				next TRY if( $maxF && ( int ($max*$divisor) != ($max*$divisor) ) );
+
+				# If everything passes the tests, return.
+				return(1/$divisor, $tickCount, $pMin, $pMax)
+			}
+		}
+	}
+
+	die "can't happen!";
+}
+
+# Works out how many ticks would be displayed at that interval
+# e.g min=2, max=5, interval=1, result is 4 ticks.
+# written by David Pottage of Tao Group.
+sub _countTicks
+{
+        my $self = shift;
+	my( $min, $max, $interval) = @_;
+	
+	my $minR = $self->_round2Tick( $min, $interval, -1);
+	my $maxR = $self->_round2Tick( $max, $interval, 1);
+	
+	my $tickCount = ( $maxR/$interval ) - ( $minR/$interval ) +1;
+	
+	return ($tickCount, $minR, $maxR);
+}
+
+# Rounds up or down to the next tick of interval size.
+# $roundUP can be +1 or -1 to indicate if rounding should be up or down.
+# written by David Pottage of Tao Group.
+sub _round2Tick
+{
+        my $self = shift;
+	my($input, $interval, $roundUP) = @_;
+	return $input if $interval == 0;
+	die unless 1 == $roundUP*$roundUP;
+	
+	my $intN  = int ($input/$interval);
+	my $fracN = ($input/$interval) - $intN;
+	
+	my $retN = ( ( 0 == $fracN ) || ( ($roundUP * $fracN) < 0 ) )
+		? $intN
+		: $intN + $roundUP;
+	
+	return $retN * $interval;
+}
+
+# Seperates a number into it's base 10 floating point exponent & mantisa.
+# written by David Pottage of Tao Group.
+sub _sepFP
+{
+        my $self = shift;
+	my($num) = @_;
+	return(0,0) if $num == 0;
+	
+	my $sign = ( $num > 0 ) ? 1 : -1;
+	$num *= $sign;
+	
+	my $exponent = int ( log($num)/log(10) );
+	my $mantisa  = $sign *($num / (10**$exponent) );
+	
+	return ( $exponent, $mantisa );
+}
+
+sub _find_y_range {
+  my $self = shift;
+  my $data = $self->{'dataref'};
+
+  my $max = undef;
+  my $min = undef;
+  for my $dataset ( @$data[1..$#$data] ) {
+    for my $datum ( @$dataset ) {
+      if ( defined $datum && $datum =~ /^[\-\+]{0,}\s*[\d\.eE\-\+]+/ ) {
+      # if ( defined $datum  ) {
+## Prettier, but probably slower:
+#         $max = $datum unless defined $max && $max >= $datum;
+#         $min = $datum unless defined $min && $min <= $datum;
+       if ( defined $max && $max =~ /^[\-\+]{0,}\s*[\d\.eE\-\+]+/ ) {
+       # if ( defined $max ) {
+          if ( $datum > $max ) { $max = $datum }
+          elsif ( $datum < $min ) { $min = $datum }
+        }
+        else { $min = $max = $datum }
+      }
+    }
+  }
+  ($min, $max);
+}
+
+sub _find_x_range {
+  my $self = shift;
+  my $data = $self->{'dataref'};
+
+  my $max = undef;
+  my $min = undef;
+
+    for my $datum ( @{$data->[0]} ) {
+     if ( defined $datum && $datum =~ /^[\-\+]{0,1}\s*[\d\.eE\-\+]+/ ) {
+     # if ( defined $datum ) {
+       if ( defined $max && $max =~ /^[\-\+]{0,1}\s*[\d\.eE\-\+]+/ ) {
+     # if ( defined $max  ) {
+          if ( $datum > $max ) { $max = $datum }
+          elsif ( $datum < $min ) { $min = $datum }
+        }
+        else { $min = $max = $datum }
+      }
+    }
+
+ return ($min, $max);
+}
+## main sub that controls all the plotting of the actual chart
+sub _plot {
+  my $self = shift;
+
+  # draw the legend first
+  $self->_draw_legend;
+
+  # mark off the graph_border space
+  $self->{'curr_x_min'} += $self->{'graph_border'};
+  $self->{'curr_x_max'} -= $self->{'graph_border'};
+  $self->{'curr_y_min'} += $self->{'graph_border'};
+  $self->{'curr_y_max'} -= $self->{'graph_border'};
+
+  # draw the x- and y-axis labels
+  $self->_draw_x_label if $self->{'x_label'};
+  $self->_draw_y_label('left') if $self->{'y_label'};
+  $self->_draw_y_label('right') if $self->{'y_label2'};
+
+  # draw the ticks and tick labels
+  $self->_draw_ticks;
+  
+  # give the plot a grey background if they want it
+  $self->_grey_background if ($self->{'grey_background'} =~ /^true$/i);
+  
+  #draw the ticks again if grey_background has ruined it in a Direction Chart.
+  if ($self->{'grey_background'} =~ /^true$/i && $self->isa("Chart::Direction")) {
+    $self->_draw_ticks;
+  }
+  $self->_draw_grid_lines if ($self->{'grid_lines'} =~ /^true$/i);
+  $self->_draw_x_grid_lines if ($self->{'x_grid_lines'} =~ /^true$/i);
+  $self->_draw_y_grid_lines if ($self->{'y_grid_lines'} =~ /^true$/i);
+  $self->_draw_y2_grid_lines if ($self->{'y2_grid_lines'} =~ /^true$/i);
+
+  # plot the data
+  $self->_draw_data();
+  
+  # and return
+  return 1;
+}
+
+
+##  let them know what all the pretty colors mean
+sub _draw_legend {
+  my $self = shift;
+  my ($length);
+
+  # check to see if legend type is none..
+  if ($self->{'legend'} =~ /^none$/) {
+    return 1;
+  }
+  # check to see if they have as many labels as datasets,
+  # warn them if not
+  if (($#{$self->{'legend_labels'}} >= 0) && 
+       ((scalar(@{$self->{'legend_labels'}})) != $self->{'num_datasets'})) {
+    carp "The number of legend labels and datasets doesn\'t match";
+  }
+
+  # init a field to store the length of the longest legend label
+  unless ($self->{'max_legend_label'}) {
+    $self->{'max_legend_label'} = 0;
+  }
+
+  # fill in the legend labels, find the longest one
+  for (1..$self->{'num_datasets'}) {
+    unless ($self->{'legend_labels'}[$_-1]) {
+      $self->{'legend_labels'}[$_-1] = "Dataset $_";
+    }
+    $length = length($self->{'legend_labels'}[$_-1]);
+    if ($length > $self->{'max_legend_label'}) {
+      $self->{'max_legend_label'} = $length;
+    }
+  }
+      
+  # different legend types
+  if ($self->{'legend'} eq 'bottom') {
+    $self->_draw_bottom_legend;
+  }
+  elsif ($self->{'legend'} eq 'right') {
+    $self->_draw_right_legend;
+  }
+  elsif ($self->{'legend'} eq 'left') {
+    $self->_draw_left_legend;
+  }
+  elsif ($self->{'legend'} eq 'top') {
+    $self->_draw_top_legend;
+  } else {
+    carp "I can't put a legend there (at ".$self->{'legend'}.")\n";
+  }
+
+  # and return
+  return 1;
+}
+
+
+## put the legend on the bottom of the chart
+sub _draw_bottom_legend {
+  my $self = shift;
+  my @labels = @{$self->{'legend_labels'}};
+  my ($x1, $y1, $x2, $x3, $y2, $empty_width, $max_label_width, $cols, $rows, $color, $brush);
+  my ($col_width, $row_height, $r, $c, $index, $x, $y, $w, $h, $axes_space);
+  my $font = $self->{'legend_font'};
+
+  # make sure we're using a real font
+  unless ((ref ($font)) eq 'GD::Font') {
+    croak "The subtitle font you specified isn\'t a GD Font object";
+  }
+
+  # get the size of the font
+  ($h, $w) = ($font->height, $font->width);
+
+  # find the base x values
+  $axes_space = ($self->{'y_tick_label_length'} * $self->{'tick_label_font'}->width)
+	        + $self->{'tick_len'} + (3 * $self->{'text_space'});
+  $x1 = $self->{'curr_x_min'} + $self->{'graph_border'};
+  $x2 = $self->{'curr_x_max'} - $self->{'graph_border'};
+
+  if ($self->{'y_axes'} =~ /^right$/i) {
+     $x2 -= $axes_space;
+  }
+  elsif ($self->{'y_axes'} =~ /^both$/i) {
+     $x2 -= $axes_space;
+     $x1 += $axes_space;
+  }
+  else {
+     $x1 += $axes_space;
+  }
+
+
+  if ($self->{'y_label'}) {
+    $x1 += $self->{'label_font'}->height + 2 * $self->{'text_space'};
+  }
+  if ($self->{'y_label2'}) {
+    $x2 -= $self->{'label_font'}->height + 2 * $self->{'text_space'};
+  }
+
+  # figure out how wide the columns need to be, and how many we
+  # can fit in the space available
+  $empty_width = ($x2 - $x1) - (2 * $self->{'legend_space'});
+  $max_label_width = $self->{'max_legend_label'} * $w
+    + (4 * $self->{'text_space'}) + $self->{'legend_example_size'};
+  $cols = int ($empty_width / $max_label_width);
+  unless ($cols) {
+    $cols = 1;
+  }
+  $col_width = $empty_width / $cols;
+
+  # figure out how many rows we need, remember how tall they are
+  $rows = int ($self->{'num_datasets'} / $cols);
+  unless (($self->{'num_datasets'} % $cols) == 0) {
+    $rows++;
+  }
+  unless ($rows) {
+    $rows = 1;
+  }
+  $row_height = $h + $self->{'text_space'};
+
+  # box the legend off
+  $y1 = $self->{'curr_y_max'} - $self->{'text_space'}
+          - ($rows * $row_height) - (2 * $self->{'legend_space'});
+  $y2 = $self->{'curr_y_max'};
+  $self->{'gd_obj'}->rectangle($x1, $y1, $x2, $y2, 
+                               $self->_color_role_to_index('misc'));
+  $x1 += $self->{'legend_space'} + $self->{'text_space'};
+  $x2 -= $self->{'legend_space'};
+  $y1 += $self->{'legend_space'} + $self->{'text_space'};
+  $y2 -= $self->{'legend_space'} + $self->{'text_space'};
+
+  # draw in the actual legend
+  for $r (0..$rows-1) {
+    for $c (0..$cols-1) {
+      $index = ($r * $cols) + $c;  # find the index in the label array
+      if ($labels[$index]) {
+	# get the color
+        $color = $self->_color_role_to_index('dataset'.$index); 
+
+        # get the x-y coordinate for the start of the example line
+	$x = $x1 + ($col_width * $c);
+        $y = $y1 + ($row_height * $r) + $h/2;
+	
+	# now draw the example line
+        $self->{'gd_obj'}->line($x, $y, 
+                                $x + $self->{'legend_example_size'}, $y,
+                                $color);
+
+        # reset the brush for points
+        $brush = $self->_prepare_brush($color, 'point',
+				$self->{'pointStyle' . $index});
+        $self->{'gd_obj'}->setBrush($brush);
+        # draw the point
+        $x3 = int($x + $self->{'legend_example_size'}/2);
+        $self->{'gd_obj'}->line($x3, $y, $x3, $y, gdBrushed);
+
+        # adjust the x-y coordinates for the start of the label
+	$x += $self->{'legend_example_size'} + (2 * $self->{'text_space'});
+        $y = $y1 + ($row_height * $r);
+
+	# now draw the label
+	$self->{'gd_obj'}->string($font, $x, $y, $labels[$index], $color);
+      }
+    }
+  }
+
+  # mark off the space used
+  $self->{'curr_y_max'} -= ($rows * $row_height) + $self->{'text_space'}
+			      + (2 * $self->{'legend_space'}); 
+
+  # now return
+  return 1;
+}
+
+
+## put the legend on the right of the chart
+sub _draw_right_legend {
+  my $self = shift;
+  my @labels = @{$self->{'legend_labels'}};
+  my ($x1, $x2, $x3, $y1, $y2, $width, $color, $misccolor, $w, $h, $brush);
+  my $font = $self->{'legend_font'};
+ 
+  # make sure we're using a real font
+  unless ((ref ($font)) eq 'GD::Font') {
+    croak "The subtitle font you specified isn\'t a GD Font object";
+  }
+
+  # get the size of the font
+  ($h, $w) = ($font->height, $font->width);
+
+  # get the miscellaneous color
+  $misccolor = $self->_color_role_to_index('misc');
+
+  # find out how wide the largest label is
+  $width = (2 * $self->{'text_space'})
+    + ($self->{'max_legend_label'} * $w)
+    + $self->{'legend_example_size'}
+    + (2 * $self->{'legend_space'});
+
+  # get some starting x-y values
+  $x1 = $self->{'curr_x_max'} - $width;
+  $x2 = $self->{'curr_x_max'};
+  $y1 = $self->{'curr_y_min'} + $self->{'graph_border'} ;
+  $y2 = $self->{'curr_y_min'} + $self->{'graph_border'} + $self->{'text_space'}
+          + ($self->{'num_datasets'} * ($h + $self->{'text_space'}))
+	  + (2 * $self->{'legend_space'});
+
+  # box the legend off
+  $self->{'gd_obj'}->rectangle ($x1, $y1, $x2, $y2, $misccolor);
+
+  # leave that nice space inside the legend box
+  $x1 += $self->{'legend_space'};
+  $y1 += $self->{'legend_space'} + $self->{'text_space'};
+
+  # now draw the actual legend
+  for (0..$#labels) {
+    # get the color
+    my $c = $self->{'num_datasets'}-$_-1;
+    # color of the datasets in the legend
+   # if ($self->{'dataref'}[1][0] < 0) {
+        $color = $self->_color_role_to_index('dataset'.$_);
+   # }
+   # else {	
+   #     $color = $self->_color_role_to_index('dataset'.$c);
+   #}
+
+    # find the x-y coords
+    $x2 = $x1;
+    $x3 = $x2 + $self->{'legend_example_size'};
+    $y2 = $y1 + ($_ * ($self->{'text_space'} + $h)) + $h/2;
+
+    # do the line first
+    $self->{'gd_obj'}->line ($x2, $y2, $x3, $y2, $color);
+
+    # reset the brush for points
+    $brush = $self->_prepare_brush($color, 'point',
+				$self->{'pointStyle' . $_});
+    $self->{'gd_obj'}->setBrush($brush);
+    # draw the point
+    $self->{'gd_obj'}->line(int(($x3+$x2)/2), $y2,
+				int(($x3+$x2)/2), $y2, gdBrushed);
+
+    # now the label
+    $x2 = $x3 + (2 * $self->{'text_space'});
+    $y2 -= $h/2;
+    # order of the datasets in the legend
+   # if ($self->{'dataref'}[1][0] <0) {
+        $self->{'gd_obj'}->string ($font, $x2, $y2, $labels[$_], $color);
+   # }
+   # else {
+   #     $self->{'gd_obj'}->string ($font, $x2, $y2, $labels[$c], $color);
+   # }
+  }
+
+  # mark off the used space
+  $self->{'curr_x_max'} -= $width;
+
+  # and return
+  return 1;
+}
+
+
+## put the legend on top of the chart
+sub _draw_top_legend {
+  my $self = shift;
+  my @labels = @{$self->{'legend_labels'}};
+  my ($x1, $y1, $x2, $x3, $y2, $empty_width, $max_label_width, $cols, $rows, $color, $brush);
+  my ($col_width, $row_height, $r, $c, $index, $x, $y, $w, $h, $axes_space);
+  my $font = $self->{'legend_font'};
+
+  # make sure we're using a real font
+  unless ((ref ($font)) eq 'GD::Font') {
+    croak "The subtitle font you specified isn\'t a GD Font object";
+  }
+
+  # get the size of the font
+  ($h, $w) = ($font->height, $font->width);
+
+  # find the base x values
+  $axes_space = ($self->{'y_tick_label_length'} * $self->{'tick_label_font'}->width)
+	        + $self->{'tick_len'} + (3 * $self->{'text_space'});
+  $x1 = $self->{'curr_x_min'} + $self->{'graph_border'};
+  $x2 = $self->{'curr_x_max'} - $self->{'graph_border'};
+
+  if ($self->{'y_axes'} =~ /^right$/i) {
+     $x2 -= $axes_space;
+  }
+  elsif ($self->{'y_axes'} =~ /^both$/i) {
+     $x2 -= $axes_space;
+     $x1 += $axes_space;
+  }
+  else {
+     $x1 += $axes_space;
+  }
+
+  # figure out how wide the columns can be, and how many will fit
+  $empty_width = ($x2 - $x1) - (2 * $self->{'legend_space'});
+  $max_label_width = (4 * $self->{'text_space'})
+    + ($self->{'max_legend_label'} * $w)
+    + $self->{'legend_example_size'};
+  $cols = int ($empty_width / $max_label_width);
+  unless ($cols) {
+    $cols = 1;
+  }
+  $col_width = $empty_width / $cols;
+
+  # figure out how many rows we need and remember how tall they are
+  $rows = int ($self->{'num_datasets'} / $cols);
+  unless (($self->{'num_datasets'} % $cols) == 0) {
+    $rows++;
+  }
+  unless ($rows) {
+    $rows = 1;
+  }
+  $row_height = $h + $self->{'text_space'};
+
+  # box the legend off
+  $y1 = $self->{'curr_y_min'};
+  $y2 = $self->{'curr_y_min'} + $self->{'text_space'}
+          + ($rows * $row_height) + (2 * $self->{'legend_space'});
+  $self->{'gd_obj'}->rectangle($x1, $y1, $x2, $y2, 
+                               $self->_color_role_to_index('misc'));
+
+  # leave some space inside the legend
+  $x1 += $self->{'legend_space'} + $self->{'text_space'};
+  $x2 -= $self->{'legend_space'};
+  $y1 += $self->{'legend_space'} + $self->{'text_space'};
+  $y2 -= $self->{'legend_space'} + $self->{'text_space'};
+
+  # draw in the actual legend
+  for $r (0..$rows-1) {
+    for $c (0..$cols-1) {
+      $index = ($r * $cols) + $c;  # find the index in the label array
+      if ($labels[$index]) {
+	# get the color
+        $color = $self->_color_role_to_index('dataset'.$index); 
+        
+	# find the x-y coords
+	$x = $x1 + ($col_width * $c);
+        $y = $y1 + ($row_height * $r) + $h/2;
+
+	# draw the line first
+        $self->{'gd_obj'}->line($x, $y, 
+                                $x + $self->{'legend_example_size'}, $y,
+                                $color);
+
+        # reset the brush for points
+        $brush = $self->_prepare_brush($color, 'point',
+				$self->{'pointStyle' . $index});
+        $self->{'gd_obj'}->setBrush($brush);
+        # draw the point
+        $x3 = int($x + $self->{'legend_example_size'}/2);
+        $self->{'gd_obj'}->line($x3, $y, $x3, $y, gdBrushed);
+
+        # now the label
+	$x += $self->{'legend_example_size'} + (2 * $self->{'text_space'});
+	$y -= $h/2;
+	$self->{'gd_obj'}->string($font, $x, $y, $labels[$index], $color);
+      }
+    }
+  }
+      
+  # mark off the space used
+  $self->{'curr_y_min'} += ($rows * $row_height) + $self->{'text_space'}
+			      + 2 * $self->{'legend_space'}; 
+
+  # now return
+  return 1;
+}
+
+
+## put the legend on the left of the chart
+sub _draw_left_legend {
+  my $self = shift;
+  my @labels = @{$self->{'legend_labels'}};
+  my ($x1, $x2, $x3, $y1, $y2, $width, $color, $misccolor, $w, $h, $brush);
+  my $font = $self->{'legend_font'};
+ 
+  # make sure we're using a real font
+  unless ((ref ($font)) eq 'GD::Font') {
+    croak "The subtitle font you specified isn\'t a GD Font object";
+  }
+
+  # get the size of the font
+  ($h, $w) = ($font->height, $font->width);
+
+  # get the miscellaneous color
+  $misccolor = $self->_color_role_to_index('misc');
+
+  # find out how wide the largest label is
+  $width = (2 * $self->{'text_space'})
+    + ($self->{'max_legend_label'} * $w)
+    + $self->{'legend_example_size'}
+    + (2 * $self->{'legend_space'});
+
+  # get some base x-y coordinates
+  $x1 = $self->{'curr_x_min'};
+  $x2 = $self->{'curr_x_min'} + $width;
+  $y1 = $self->{'curr_y_min'} + $self->{'graph_border'} ;
+  $y2 = $self->{'curr_y_min'} + $self->{'graph_border'} + $self->{'text_space'}
+          + ($self->{'num_datasets'} * ($h + $self->{'text_space'}))
+	  + (2 * $self->{'legend_space'});
+
+  # box the legend off
+  $self->{'gd_obj'}->rectangle ($x1, $y1, $x2, $y2, $misccolor);
+
+  # leave that nice space inside the legend box
+  $x1 += $self->{'legend_space'};
+  $y1 += $self->{'legend_space'} + $self->{'text_space'};
+
+  # now draw the actual legend
+  for (0..$#labels) {
+    # get the color
+    my $c = $self->{'num_datasets'}-$_-1;
+    # color of the datasets in the legend
+   # if ($self->{'dataref'}[1][0] <0) {
+        $color = $self->_color_role_to_index('dataset'.$_);
+   # }
+   # else {
+   #     $color = $self->_color_role_to_index('dataset'.$c);
+   # }
+
+    # find the x-y coords
+    $x2 = $x1;
+    $x3 = $x2 + $self->{'legend_example_size'};
+    $y2 = $y1 + ($_ * ($self->{'text_space'} + $h)) + $h/2;
+
+    # do the line first
+    $self->{'gd_obj'}->line ($x2, $y2, $x3, $y2, $color);
+
+    # reset the brush for points
+    $brush = $self->_prepare_brush($color, 'point',
+				$self->{'pointStyle' . $_});
+    $self->{'gd_obj'}->setBrush($brush);
+    # draw the point
+    $self->{'gd_obj'}->line(int(($x3+$x2)/2), $y2,
+				int(($x3+$x2)/2), $y2, gdBrushed);
+    
+    # now the label
+    $x2 = $x3 + (2 * $self->{'text_space'});
+    $y2 -= $h/2;
+    # order of the datasets in the legend
+   # if ($self->{'dataref'}[1][0] <0) {
+        $self->{'gd_obj'}->string ($font, $x2, $y2, $labels[$_], $color);
+   # }
+   # else {
+   #     $self->{'gd_obj'}->string ($font, $x2, $y2, $labels[$c], $color);
+   # }
+  }
+
+  # mark off the used space
+  $self->{'curr_x_min'} += $width;
+
+  # and return
+  return 1;
+}
+
+
+## draw the label for the x-axis
+sub _draw_x_label {  
+  my $self = shift;
+  my $label = $self->{'x_label'};
+  my $font = $self->{'label_font'};
+  my $color;
+  my ($h, $w, $x, $y);
+
+  #get the right color
+  if (defined $self->{'colors'}->{'x_label'}) {
+    $color = $self->_color_role_to_index('x_label');
+
+  }
+  else {
+    $color = $self->_color_role_to_index('text');
+  }
+  
+  # make sure it's a real GD Font object
+  unless ((ref ($font)) eq 'GD::Font') {
+    croak "The x-axis label font you specified isn\'t a GD Font object";
+  }
+
+  # get the size of the font
+  ($h, $w) = ($font->height, $font->width);
+
+  # make sure it goes in the right place
+  $x = ($self->{'curr_x_max'} - $self->{'curr_x_min'}) / 2
+         + $self->{'curr_x_min'} - (length($label) * $w) / 2;
+  $y = $self->{'curr_y_max'} - ($self->{'text_space'} + $h);
+
+  # now write it
+  $self->{'gd_obj'}->string ($font, $x, $y, $label, $color);
+
+  # mark the space written to as used
+  $self->{'curr_y_max'} -= $h + 2 * $self->{'text_space'};
+
+  # and return
+  return 1;
+}
+
+
+## draw the label for the y-axis
+sub _draw_y_label {
+  my $self = shift;
+  my $side = shift;
+  my $font = $self->{'label_font'};
+  my ($label, $h, $w, $x, $y, $color);
+
+  # get the label
+  if ($side eq 'left') {
+    $label = $self->{'y_label'};
+    $color = $self->_color_role_to_index('y_label');
+  }
+  elsif ($side eq 'right') {
+    $label = $self->{'y_label2'};
+    $color = $self->_color_role_to_index('y_label2');
+  }
+
+  # make sure it's a real GD Font object
+  unless ((ref ($font)) eq 'GD::Font') {
+    croak "The x-axis label font you specified isn\'t a GD Font object";
+  }
+
+  # get the size of the font
+  ($h, $w) = ($font->height, $font->width);
+
+  # make sure it goes in the right place
+  if ($side eq 'left') {
+    $x = $self->{'curr_x_min'} + $self->{'text_space'};
+  }
+  elsif ($side eq 'right') {
+    $x = $self->{'curr_x_max'} - $self->{'text_space'} - $h;
+  }
+  $y = ($self->{'curr_y_max'} - $self->{'curr_y_min'}) / 2
+         + $self->{'curr_y_min'} + (length($label) * $w) / 2;
+
+  # write it
+  $self->{'gd_obj'}->stringUp($font, $x, $y, $label, $color);
+
+  # mark the space written to as used
+  if ($side eq 'left') {
+    $self->{'curr_x_min'} += $h + 2 * $self->{'text_space'};
+  }
+  elsif ($side eq 'right') {
+    $self->{'curr_x_max'} -= $h + 2 * $self->{'text_space'};
+  }
+
+  # now return
+  return 1;
+}
+
+
+## draw the ticks and tick labels
+sub _draw_ticks {
+  my $self = shift;
+
+  #if the user wants an xy_plot, calculate the x-ticks too
+  if ( $self->{'xy_plot'} =~ /^true$/i && ($self->isa('Chart::Lines') || $self->isa('Chart::Points')
+       || $self->isa('Chart::LinesPoints') || $self->isa('Chart::Split') || $self->isa('Chart::ErrorBars')) ) {
+     $self->_draw_x_number_ticks;
+  }
+  else { # draw the x ticks with strings
+     $self->_draw_x_ticks;
+  }
+
+  # now the y ticks
+  $self->_draw_y_ticks($self->{'y_axes'});
+
+  # then return
+  return 1;
+}
+
+sub _draw_x_number_ticks {
+ my $self = shift;
+ my $data = $self->{'dataref'};
+ my $font = $self->{'tick_label_font'};
+ my $textcolor = $self->_color_role_to_index('text');
+ my $misccolor = $self->_color_role_to_index('misc');
+ my ($h, $w, $x1, $y1, ,$y2, $x2, $delta, $width, $label);
+ my @labels = @{$self->{'x_tick_labels'}};
+
+ $self->{'grid_data'}->{'x'} = [];
+
+ #make sure we have a real font
+ unless ((ref $font) eq 'GD::Font') {
+  croak "The tick label font you specified isn't a GD font object";
+ }
+
+ #get height and width of the font
+ ($h, $w) = ($font->height, $font->width);
+
+ #store actual borders, for a possible later repair
+ $self->{'temp_x_min'} = $self->{'curr_x_min'};
+ $self->{'temp_x_max'} = $self->{'curr_x_max'};
+ $self->{'temp_y_max'} = $self->{'curr_y_max'};
+ $self->{'temp_y_min'} = $self->{'curr_y_min'};
+ 
+ #get the right x-value and width
+  #The one and only way to get the RIGHT x value and the width
+  if ($self->{'y_axes'} =~ /^right$/i) {
+    $x1 = $self->{'curr_x_min'}  ;
+    $width = $self->{'curr_x_max'} - $x1- ($w * $self->{'y_tick_label_length'})
+             - 3 * $self->{'text_space'} - $self->{'tick_len'};
+  }
+  elsif ($self->{'y_axes'} =~ /^both$/i) {
+    $x1 = $self->{'curr_x_min'} + ($w * $self->{'y_tick_label_length'})
+         + 3 * $self->{'text_space'} + $self->{'tick_len'};
+    $width = $self->{'curr_x_max'} - $x1- ($w * $self->{'y_tick_label_length'})
+            - (3 * $self->{'text_space'}) - $self->{'tick_len'};
+  }
+  else {
+    $x1 = $self->{'curr_x_min'} + ($w * $self->{'y_tick_label_length'})
+         + 3 * $self->{'text_space'} + $self->{'tick_len'};
+    $width = $self->{'curr_x_max'} - $x1;
+  }
+
+ #get the delta value
+ $delta = $width / ($self->{'x_number_ticks'}-1 ) ;
+
+ #draw the labels
+ $y2 =$y1;
+
+ if ($self->{'x_ticks'} =~ /^normal/i ) {  #just normal ticks
+   #get the point for updating later
+   $y1 = $self->{'curr_y_max'} - 2*$self->{'text_space'} -$h - $self->{'tick_len'};
+   #get the start point
+   $y2 = $y1  + $self->{'tick_len'} + $self->{'text_space'};
+   for (0..$#labels){
+     $label = $self->{f_x_tick}->($self->{'x_tick_labels'}[$_]);
+     $x2 = $x1 + ($delta * $_) - (0.5 *$w* length( $label)) ;
+     $self->{'gd_obj'}->string($font, $x2, $y2 , $label , $textcolor);
+   }
+ }
+ elsif ($self->{'x_ticks'} =~ /^staggered/i ) {  #staggered ticks
+   #get the point for updating later
+   $y1 = $self->{'curr_y_max'} - 3*$self->{'text_space'} - 2*$h - $self->{'tick_len'};
+
+   for (0..$#labels) {
+   $label = $self->{f_x_tick}->($self->{'x_tick_labels'}[$_]);
+     $x2 = $x1 + ($delta * $_) - ($w* length( $label)/2);
+     unless ($_%2) {
+      $y2 = $y1  + $self->{'text_space'} + $self->{'tick_len'};
+       $self->{'gd_obj'}->string($font, $x2, $y2 , $label, $textcolor);
+     }
+     else {
+     $y2 = $y1  + $h + 2*$self->{'text_space'} + $self->{'tick_len'};
+       $self->{'gd_obj'}->string($font, $x2, $y2 , $label, $textcolor);
+     }
+   }
+ }
+ elsif ($self->{'x_ticks'} =~ /^vertical/i ) {  #vertical ticks
+   #get the point for updating later
+   $y1 = $self->{'curr_y_max'} - 2*$self->{'text_space'} -$w* $self->{'x_tick_label_length'} - $self->{'tick_len'};
+    for (0..$#labels){
+     $label = $self->{f_x_tick}->($self->{'x_tick_labels'}[$_]);
+
+     #get the start point
+     $y2 = $y1  + $self->{'tick_len'} + $w* length($label) + $self->{'text_space'};
+     $x2 = $x1 + ($delta * $_) - ($h /2);
+     $self->{'gd_obj'}->stringUp($font, $x2, $y2 , $label , $textcolor);
+   }
+
+ }
+
+ else {
+  carp "I don't understand the type of x-ticks you specified";
+ }
+ #update the curr y max value
+ $self->{'curr_y_max'} = $y1;
+
+ #draw the ticks
+ $y1 =$self->{'curr_y_max'};
+ $y2 =$self->{'curr_y_max'} + $self->{'tick_len'};
+ for(0..$#labels ) {
+   $x2 = $x1 + ($delta * $_);
+   $self->{'gd_obj'}->line($x2, $y1, $x2, $y2, $misccolor);
+     if (($self->{'grid_lines'} =~ /^true$/i) or ($self->{'x_grid_lines'} =~ /^true$/i)) {
+        $self->{'grid_data'}->{'x'}->[$_] = $x2;
+     }
+ }
+
+  return 1;
+}
+  
+
+## draw the x-ticks and their labels
+sub _draw_x_ticks {
+  my $self = shift;
+  my $data = $self->{'dataref'};
+  my $font = $self->{'tick_label_font'};
+  my $textcolor = $self->_color_role_to_index('text');
+  my $misccolor = $self->_color_role_to_index('misc');
+  my $label;
+  my ($h, $w);
+  my ($x1, $x2, $y1, $y2);
+  my ($width, $delta);
+  my ($stag);
+
+  $self->{'grid_data'}->{'x'} = [];
+
+  # make sure we got a real font
+  unless ((ref $font) eq 'GD::Font') {
+    croak "The tick label font you specified isn\'t a GD Font object";
+  }
+
+  # get the height and width of the font
+  ($h, $w) = ($font->height, $font->width);
+  
+  # maybe, we need the actual x and y values later for drawing the x-ticks again
+  # in the draw function in the lines modul. So copy them.
+  $self->{'temp_x_min'} = $self->{'curr_x_min'};
+  $self->{'temp_x_max'} = $self->{'curr_x_max'};
+  $self->{'temp_y_min'} = $self->{'curr_y_min'};
+  $self->{'temp_y_max'} = $self->{'curr_y_max'};
+    
+  # allow for the amount of space the y-ticks will push the
+  # axes over to the right
+## _draw_y_ticks allows 3 * text_space, not 1 * ;  this caused mismatch between
+## the ticks (and grid lines) and the data.
+#   $x1 = $self->{'curr_x_min'} + ($w * $self->{'y_tick_label_length'})
+#          + $self->{'text_space'} + $self->{'tick_len'};
+## And, what about the right-tick space??  Only affects Composite, I guess....
+
+  #The one and only way to get the RIGHT x value and the width
+  if ($self->{'y_axes'} =~ /^right$/i) {
+    $x1 = $self->{'curr_x_min'}  ;
+    $width = $self->{'curr_x_max'} - $x1- ($w * $self->{'y_tick_label_length'})
+             - 3 * $self->{'text_space'} - $self->{'tick_len'};
+	     
+  }
+  elsif ($self->{'y_axes'} =~ /^both$/i) {
+    $x1 = $self->{'curr_x_min'} + ($w * $self->{'y_tick_label_length'})
+         + 3 * $self->{'text_space'} + $self->{'tick_len'};
+    $width = $self->{'curr_x_max'} - $x1- ($w * $self->{'y_tick_label_length'})
+            - 3 * $self->{'text_space'} - $self->{'tick_len'};
+  }
+  else {
+    $x1 = $self->{'curr_x_min'} + ($w * $self->{'y_tick_label_length'})
+         + 3 * $self->{'text_space'} + $self->{'tick_len'};
+    $width = $self->{'curr_x_max'} - $x1;
+   
+  }
+
+  #the same for the y value, but not so tricky
+  $y1 = $self->{'curr_y_max'} - $h - $self->{'text_space'};
+
+  # get the delta value, figure out how to draw the labels
+  $delta = $width / ($self->{'num_datapoints'}> 0 ? $self->{'num_datapoints'} : 1);
+  if ( ! defined($self->{'skip_x_ticks'}) ) {
+     $self->{'skip_x_ticks'} = 1;
+  } elsif ( $self->{'skip_x_ticks'} == 0 ) {
+     $self->{'skip_x_ticks'} = 1;
+  }
+  if ($delta <= ($self->{'x_tick_label_length'} * $w) /  $self->{'skip_x_ticks'}) {
+    if ($self->{'x_ticks'} =~ /^normal$/i) {
+      $self->{'x_ticks'} = 'staggered';
+    }
+  }
+
+  # now draw the labels 
+  if ($self->{'x_ticks'} =~ /^normal$/i) { # normal ticks
+     if ($self->{'skip_x_ticks'} >1) { # draw only every nth tick and label
+      for (0..int (($self->{'num_datapoints'} - 1) / $self->{'skip_x_ticks'})) {
+        if ( defined($data->[0][$_*$self->{'skip_x_ticks'}]) ) {
+           $label = $self->{f_x_tick}->($data->[0][$_*$self->{'skip_x_ticks'}]);
+           $x2 = $x1 + ($delta / 2) + ($delta * ($_ * $self->{'skip_x_ticks'})) 
+	         - ($w*length($label) )/ 2;
+           $self->{'gd_obj'}->string($font, $x2, $y1, $label, $textcolor);
+        }
+      }     
+    }
+    elsif ($self->{'custom_x_ticks'}) { # draw only the ticks they wanted
+     for (@{$self->{'custom_x_ticks'}}) {
+         if ( defined($_) ) {
+             $label = $self->{f_x_tick}->($data->[0][$_]);
+             $x2 = $x1 + ($delta/2) + ($delta*$_) - ($w*length($label)) / 2;
+             $self->{'gd_obj'}->string($font, $x2, $y1, $label, $textcolor);
+         }
+     }
+    }
+    else {
+      for (0..$self->{'num_datapoints'}-1) {
+        if ( defined($_) ) {
+          $label = $self->{f_x_tick}->($data->[0][$_]);
+          $x2 = $x1 + ($delta/2) + ($delta*$_) - ($w*length($label)) / 2;
+          $self->{'gd_obj'}->string($font, $x2, $y1, $label, $textcolor);
+        }
+      }
+    }
+  }
+
+  elsif ($self->{'x_ticks'} =~ /^staggered$/i) { # staggered ticks
+    if ($self->{'skip_x_ticks'}>1) {
+      $stag = 0;
+      for (0..int(($self->{'num_datapoints'}-1)/$self->{'skip_x_ticks'})) {
+        if ( defined($data->[0][$_*$self->{'skip_x_ticks'}]) ) {
+           $x2 = $x1 + ($delta / 2) + ($delta * ($_ * $self->{'skip_x_ticks'})) 
+	        - ($w*length($self->{f_x_tick}->($data->[0][$_*$self->{'skip_x_ticks'}]))) / 2;
+           if (($stag % 2) == 1) {
+             $y1 -= $self->{'text_space'} + $h;
+           }
+           $self->{'gd_obj'}->string($font, $x2, $y1, 
+	                          $self->{f_x_tick}->($data->[0][$_*$self->{'skip_x_ticks'}]), 
+				  $textcolor);
+           if (($stag % 2) == 1) {
+             $y1 += $self->{'text_space'} + $h;
+           }
+	   $stag++;
+         }
+      }
+    }
+    elsif ($self->{'custom_x_ticks'}) {
+      $stag = 0;
+      for (sort (@{$self->{'custom_x_ticks'}})) { # sort to make it look good
+        if ( defined($_) ) {
+           $x2 = $x1 + ($delta/2) + ($delta*$_) - ($w*length($self->{f_x_tick}->($data->[0][$_]))) / 2;
+           if (($stag % 2) == 1) {
+             $y1 -= $self->{'text_space'} + $h;
+           }
+           $self->{'gd_obj'}->string($font, $x2, $y1, $self->{f_x_tick}->($data->[0][$_]), $textcolor);
+           if (($stag % 2) == 1) {
+             $y1 += $self->{'text_space'} + $h;
+           }
+	   $stag++;
+         }
+      }
+    }
+    else {
+      for (0..$self->{'num_datapoints'}-1) {
+        if ( defined($self->{f_x_tick}->($data->[0][$_]) ) ) {
+           $x2 = $x1 + ($delta/2) + ($delta*$_) - ($w*length($self->{f_x_tick}->($data->[0][$_]))) / 2;
+           if (($_ % 2) == 1) {
+             $y1 -= $self->{'text_space'} + $h;
+           }
+           $self->{'gd_obj'}->string($font, $x2, $y1, $self->{f_x_tick}->($data->[0][$_]), $textcolor);
+           if (($_ % 2) == 1) {
+             $y1 += $self->{'text_space'} + $h;
+           }
+        }
+      }
+    }
+  }
+  elsif ($self->{'x_ticks'} =~ /^vertical$/i) { # vertical ticks
+    $y1 = $self->{'curr_y_max'} - $self->{'text_space'};
+    if ($self->{'skip_x_ticks'} > 1) {
+      for (0..int(($self->{'num_datapoints'}-1)/$self->{'skip_x_ticks'})) {
+        if ( defined($_) ) {
+          $x2 = $x1 + ($delta/2) + ($delta*($_*$self->{'skip_x_ticks'})) - $h/2;
+          $y2 = $y1 - (($self->{'x_tick_label_length'} 
+	              - length($self->{f_x_tick}->($data->[0][$_*$self->{'skip_x_ticks'}]))) * $w);
+          $self->{'gd_obj'}->stringUp($font, $x2, $y2, 
+                                    $self->{f_x_tick}->($data->[0][$_*$self->{'skip_x_ticks'}]), 
+				    $textcolor);
+        }
+      }
+    }
+    elsif ($self->{'custom_x_ticks'}) {
+      for (@{$self->{'custom_x_ticks'}}) {
+        if ( defined($_) ) {
+           $x2 = $x1 + ($delta/2) + ($delta*$_) - $h/2;
+           $y2 = $y1 - (($self->{'x_tick_label_length'} - length($self->{f_x_tick}->($data->[0][$_])))
+                      * $w);
+           $self->{'gd_obj'}->stringUp($font, $x2, $y2, 
+                                    $self->{f_x_tick}->($data->[0][$_]), $textcolor);
+         }
+      }
+    }
+    else {
+      for (0..$self->{'num_datapoints'}-1) {
+        if ( defined($_) ) {
+           $x2 = $x1 + ($delta/2) + ($delta*$_) - $h/2;
+           $y2 = $y1 - (($self->{'x_tick_label_length'} - length($self->{f_x_tick}->($data->[0][$_])))
+                      * $w);
+           $self->{'gd_obj'}->stringUp($font, $x2, $y2, 
+                                    $self->{f_x_tick}->($data->[0][$_]), $textcolor);
+         }
+      }
+    }
+  }
+  else { # error time
+    carp "I don't understand the type of x-ticks you specified";
+  }
+
+  # update the current y-max value
+  if ($self->{'x_ticks'} =~ /^normal$/i) {
+    $self->{'curr_y_max'} -= $h + (2 * $self->{'text_space'});
+  }
+  elsif ($self->{'x_ticks'} =~ /^staggered$/i) {
+    $self->{'curr_y_max'} -= (2 * $h) + (3 * $self->{'text_space'});
+  }
+  elsif ($self->{'x_ticks'} =~ /^vertical$/i) {
+    $self->{'curr_y_max'} -= ($w * $self->{'x_tick_label_length'})
+                               + (2 * $self->{'text_space'});
+  }
+
+  # now plot the ticks
+  $y1 = $self->{'curr_y_max'};
+  $y2 = $self->{'curr_y_max'} - $self->{'tick_len'};
+  if ($self->{'skip_x_ticks'} > 1) {
+    for (0..int(($self->{'num_datapoints'}-1)/$self->{'skip_x_ticks'})) {
+      $x2 = $x1 + ($delta/2) + ($delta*($_*$self->{'skip_x_ticks'}));
+      $self->{'gd_obj'}->line($x2, $y1, $x2, $y2, $misccolor);
+      if ($self->{'grid_lines'} =~ /^true$/i 
+	or $self->{'x_grid_lines'} =~ /^true$/i) {
+	$self->{'grid_data'}->{'x'}->[$_] = $x2;
+      }
+    }
+  }
+  elsif ($self->{'custom_x_ticks'}) {
+    for (@{$self->{'custom_x_ticks'}}) {
+      $x2 = $x1 + ($delta/2) + ($delta*$_);
+      $self->{'gd_obj'}->line($x2, $y1, $x2, $y2, $misccolor);
+      if ($self->{'grid_lines'} =~ /^true$/i
+	or $self->{'x_grid_lines'} =~ /^true$/i) {
+	$self->{'grid_data'}->{'x'}->[$_] = $x2;
+      }
+    }
+  }
+  else {
+    for (0..$self->{'num_datapoints'}-1) {
+      $x2 = $x1 + ($delta/2) + ($delta*$_);
+      $self->{'gd_obj'}->line($x2, $y1, $x2, $y2, $misccolor);
+      if ($self->{'grid_lines'} =~ /^true$/i
+        or $self->{'x_grid_lines'} =~ /^true$/i) {
+	$self->{'grid_data'}->{'x'}->[$_] = $x2;
+      }
+    }
+  }
+
+  # update the current y-max value
+  $self->{'curr_y_max'} -= $self->{'tick_len'};
+}
+
+
+##  draw the y-ticks and their labels
+sub _draw_y_ticks {
+  my $self = shift;
+  my $side = shift || 'left';
+  my $data = $self->{'dataref'};
+  my $font = $self->{'tick_label_font'};
+  my $textcolor = $self->_color_role_to_index('text');
+  my $misccolor = $self->_color_role_to_index('misc');
+  my @labels = @{$self->{'y_tick_labels'}};
+  my ($w, $h);
+  my ($x1, $x2, $y1, $y2);
+  my ($height, $delta, $label);
+  my ($s, $f);
+  
+  $self->{grid_data}->{'y'} = [];
+  $self->{grid_data}->{'y2'} = [];
+
+  # make sure we got a real font
+  unless ((ref $font) eq 'GD::Font') {
+    croak "The tick label font you specified isn\'t a GD Font object";
+  }
+
+  # find out how big the font is
+  ($w, $h) = ($font->width, $font->height);
+
+  # figure out which ticks not to draw
+  if ($self->{'min_val'} >= 0) { 
+    $s = 1;
+    $f = $#labels; 
+  }
+  elsif ($self->{'max_val'} <= 0) {  
+    $s = 0;
+    $f = $#labels;                        # -1 entfernt
+  }
+  else {    
+    $s = 0;
+    $f = $#labels;
+  }
+
+  # now draw them
+  if ($side eq 'right') { # put 'em on the right side of the chart
+    # get the base x-y values, and the delta value
+    $x1 = $self->{'curr_x_max'} - $self->{'tick_len'}
+            - (3 * $self->{'text_space'})
+	    - ($w * $self->{'y_tick_label_length'});
+    $y1 = $self->{'curr_y_max'};
+    $height = $self->{'curr_y_max'} - $self->{'curr_y_min'};
+    $self->{'y_ticks'} = 2 if $self->{'y_ticks'} < 2;
+    $delta = $height / ($self->{'y_ticks'} - 1);
+
+    # update the curr_x_max value
+    $self->{'curr_x_max'} = $x1;
+
+    # now draw the ticks
+    $x2 = $x1 + $self->{'tick_len'};
+    for ($s..$f) {
+      $y2 = $y1 - ($delta * $_);
+      $self->{'gd_obj'}->line($x1, $y2, $x2, $y2, $misccolor);
+      if ($self->{'grid_lines'} =~ /^true$/i
+	or $self->{'y2_grid_lines'} =~ /^true$/i) {
+        $self->{'grid_data'}->{'y2'}->[$_] = $y2;
+      }
+    }
+  
+    # update the current x-min value
+    $x1 += $self->{'tick_len'} + (2 * $self->{'text_space'});
+    $y1 -= $h/2;
+
+    # now draw the labels
+    for (0..$#labels) {
+      $y2 = $y1 - ($delta * $_);
+      $self->{'gd_obj'}->string($font, $x1, $y2, $self->{'y_tick_labels'}[$_], $textcolor);
+    }
+  }
+  elsif ($side eq 'both') { # put the ticks on the both sides
+    ## left side first
+
+    # get the base x-y values
+    $x1 = $self->{'curr_x_min'} + $self->{'text_space'};
+    $y1 = $self->{'curr_y_max'} - $h/2;
+
+    # now draw the labels
+    $height = $self->{'curr_y_max'} - $self->{'curr_y_min'};
+    $delta = $height / ($self->{'y_ticks'} - 1);
+    for (0..$#labels) {
+      $label = $self->{'y_tick_labels'}[$_];
+      $y2 = $y1 - ($delta * $_);
+      $x2 = $x1 + ($w * $self->{'y_tick_label_length'}) 
+              - ($w * length($label));
+      $self->{'gd_obj'}->string($font, $x2, $y2, $label, $textcolor);
+    }
+
+    # and update the current x-min value
+    $self->{'curr_x_min'} += (3 * $self->{'text_space'}) 
+                             + ($w * $self->{'y_tick_label_length'});
+  
+    # now draw the ticks (skipping the one at zero);
+    $x1 = $self->{'curr_x_min'};
+    $x2 = $self->{'curr_x_min'} + $self->{'tick_len'};
+    $y1 += $h/2;
+    for ($s..$f) {
+      $y2 = $y1 - ($delta * $_);
+      $self->{'gd_obj'}->line($x1, $y2, $x2, $y2, $misccolor);
+      if ($self->{grid_lines} =~ /^true$/i
+	or $self->{'y_grid_lines'} =~ /^true$/i) {
+        $self->{'grid_data'}->{'y'}->[$_] = $y2;
+      }
+    }
+  
+    # update the current x-min value
+    $self->{'curr_x_min'} += $self->{'tick_len'};
+
+    ## now the right side
+    # get the base x-y values, and the delta value
+    $x1 = $self->{'curr_x_max'} - $self->{'tick_len'}
+            - (3 * $self->{'text_space'})
+	    - ($w * $self->{'y_tick_label_length'});
+    $y1 = $self->{'curr_y_max'};
+    $height = $self->{'curr_y_max'} - $self->{'curr_y_min'};
+    $delta = $height / ($self->{'y_ticks'} - 1);
+
+    # update the curr_x_max value
+    $self->{'curr_x_max'} = $x1;
+
+    # now draw the ticks (skipping the one at zero);
+    $x2 = $x1 + $self->{'tick_len'};
+    for ($s..$f) {
+      $y2 = $y1 - ($delta * $_);
+      $self->{'gd_obj'}->line($x1, $y2, $x2, $y2, $misccolor);
+      if ($self->{grid_lines} =~ /^true$/i
+	or $self->{'y2_grid_lines'} =~ /^true$/i) {
+        $self->{'grid_data'}->{'y2'}->[$_] = $y2;
+      }
+    }
+  
+    # update the current x-min value
+    $x1 += $self->{'tick_len'} + (2 * $self->{'text_space'});
+    $y1 -= $h/2;
+
+    # now draw the labels
+    for (0..$#labels) {
+      $y2 = $y1 - ($delta * $_);
+      $self->{'gd_obj'}->string($font, $x1, $y2, $self->{'y_tick_labels'}[$_], $textcolor);
+    }   
+  }
+  else { # just the left side
+    # get the base x-y values
+    $x1 = $self->{'curr_x_min'} + $self->{'text_space'};
+    $y1 = $self->{'curr_y_max'} - $h/2;
+
+    # now draw the labels
+    $height = $self->{'curr_y_max'} - $self->{'curr_y_min'};
+    $self->{'y_ticks'} = 2 if $self->{'y_ticks'} < 2;
+    $delta = $height / ($self->{'y_ticks'} - 1);
+    for (0..$#labels) {
+      $label = $self->{'y_tick_labels'}[$_];
+      $y2 = $y1 - ($delta * $_);
+      $x2 = $x1 + ($w * $self->{'y_tick_label_length'}) 
+              - ($w * length($label));
+      $self->{'gd_obj'}->string($font, $x2, $y2, $label, $textcolor);
+    }
+
+    # and update the current x-min value
+    $self->{'curr_x_min'} += (3 * $self->{'text_space'}) 
+                             + ($w * $self->{'y_tick_label_length'});
+  
+    # now draw the ticks
+    $x1 = $self->{'curr_x_min'};
+    $x2 = $self->{'curr_x_min'} + $self->{'tick_len'};
+    $y1 += $h/2;
+    for ($s..$f) {
+      $y2 = $y1 - ($delta * $_);
+      $self->{'gd_obj'}->line($x1, $y2, $x2, $y2, $misccolor);
+      if ($self->{'grid_lines'} =~ /^true$/i 
+	or $self->{'y_grid_lines'} =~ /^true$/i) {
+        $self->{'grid_data'}->{'y'}->[$_] = $y2;
+      }
+    }
+  
+    # update the current x-min value
+    $self->{'curr_x_min'} += $self->{'tick_len'};
+  }
+
+  # and return
+  return 1;
+}
+
+
+##  put a grey background on the plot of the data itself
+sub _grey_background {
+  my $self = shift;
+
+  # draw it
+  $self->{'gd_obj'}->filledRectangle ($self->{'curr_x_min'},
+                                      $self->{'curr_y_min'},
+                                       $self->{'curr_x_max'},
+				      $self->{'curr_y_max'},
+				      $self->_color_role_to_index('grey_background'));
+  # now return
+  return 1;
+}
+
+# draw grid_lines 
+sub _draw_grid_lines {
+  my $self = shift;
+  $self->_draw_x_grid_lines();
+  $self->_draw_y_grid_lines();
+  $self->_draw_y2_grid_lines();
+  return 1;
+}
+
+sub _draw_x_grid_lines {
+  my $self = shift;
+  my $grid_role = shift || 'x_grid_lines';
+  my $gridcolor = $self->_color_role_to_index($grid_role);
+  my ($x, $y, $i);
+
+  foreach $x (@{ $self->{grid_data}->{'x'} }) {
+    if ( defined $x) {
+       $self->{gd_obj}->line(($x, $self->{'curr_y_min'} + 1), $x, ($self->{'curr_y_max'} - 1), $gridcolor);
+    }
+  }
+  return 1;
+}
+
+sub _draw_y_grid_lines {
+  my $self = shift;
+  my $grid_role = shift || 'y_grid_lines';
+  my $gridcolor = $self->_color_role_to_index($grid_role);
+  my ($x, $y, $i);
+
+  #Look if I'm an HorizontalBars object
+  if ($self->isa('Chart::HorizontalBars')) {
+      for ($i = 0; $i < ($#{ $self->{grid_data}->{'y'} } ) + 1; $i++) {
+        $y = $self->{grid_data}->{'y'}->[$i];
+        $self->{gd_obj}->line(($self->{'curr_x_min'} + 1), $y,  ($self->{'curr_x_max'} - 1), $y, $gridcolor);
+      }
+  } else {
+     # loop for y values is a little different. This is to discard the first
+     # and last values we were given - the top/bottom of the chart area.
+     for ($i = 1; $i < ($#{ $self->{grid_data}->{'y'} } ) + 1  ; $i++) {  ###
+        $y = $self->{grid_data}->{'y'}->[$i];
+        $self->{gd_obj}->line(($self->{'curr_x_min'} + 1), $y,  ($self->{'curr_x_max'} - 1), $y, $gridcolor);
+     }
+  }
+  return 1;
+}
+
+sub _draw_y2_grid_lines {
+  my $self = shift;
+  my $grid_role = shift || 'y2_grid_lines';
+  my $gridcolor = $self->_color_role_to_index($grid_role);
+  my ($x, $y, $i);
+
+  #Look if I'm an HorizontalBars object
+  if ($self->isa('Chart::HorizontalBars')) {
+      for ($i = 0; $i < ($#{ $self->{grid_data}->{'y'} } ) +1 ; $i++) {
+        $y = $self->{grid_data}->{'y'}->[$i];
+        $self->{gd_obj}->line(($self->{'curr_x_min'} + 1), $y,  ($self->{'curr_x_max'} - 1), $y, $gridcolor);
+      }
+  }
+  else {
+  # loop for y2 values is a little different. This is to discard the first 
+  # and last values we were given - the top/bottom of the chart area.
+   for ($i = 1; $i < $#{ $self->{grid_data}->{'y2'} }; $i++) {
+     $y = $self->{grid_data}->{'y2'}->[$i];
+     $self->{gd_obj}->line(($self->{'curr_x_min'} + 1), $y,  ($self->{'curr_x_max'} - 1), $y, $gridcolor);
+   }
+  }
+  return 1;
+}
+
+##
+##  set the gdBrush object to trick GD into drawing fat lines & points
+##  of interesting shapes
+##
+##  Needed by "Lines", "Points" and "LinesPoints"
+##
+##  All hacked up by Richard Dice <rdice at pobox.com> Sunday 16 May 1999
+##
+sub _prepare_brush {
+
+    my $self      = shift;
+    my $color     = shift;
+    my $type      = shift;
+    my $typeStyle = shift;
+
+    # decide what $type should be in the event that a param isn't
+    # passed -- this is necessary to preserve backward compatibility
+    # with apps that use this module prior to putting _prepare_brush
+    # in with Base.pm
+    if ( (! length($type) ) ||
+         ( ! grep { $type eq $_ } ('line', 'point') ) ) {
+
+        $typeStyle = $type;
+        $type = 'line' if ref $self eq 'Chart::Lines';
+        $type = 'point' if ref $self eq 'Chart::Points';
+        # Chart::LinesPoints is expected to pass a $type param
+
+    }
+
+    my ($radius, @rgb, $brush, $white, $newcolor);
+
+    # get the rgb values for the desired color
+    @rgb = $self->{'gd_obj'}->rgb($color);
+
+    # get the appropriate brush size
+    if ($type eq 'line') {
+        $radius = $self->{'brush_size'}/2;
+    } elsif ($type eq 'point') {
+        $radius = $self->{'pt_size'}/2;
+    }
+
+    # create the new image
+    $brush = GD::Image->new ($radius*2, $radius*2);
+
+    # get the colors, make the background transparent
+    $white    = $brush->colorAllocate (255,255,255);
+    $newcolor = $brush->colorAllocate (@rgb);
+    $brush->transparent ($white);
+
+    # draw the circle
+    if ( $type eq 'line') {
+        $brush->arc ($radius-1, $radius-1, $radius, $radius, 0, 360, $newcolor);
+        $brush->fill ($radius-1, $radius-1, $newcolor);
+
+        # RLD
+        #
+        # Does $brush->fill really have to be here?  Dunno... this
+        # seems to be a relic from earlier code
+        #
+        # Note that 'line's don't benefit from a $typeStyle... yet.
+        # It shouldn't be too tough to hack this in by taking advantage
+        # of GD's gdStyled facility
+
+    }
+
+    if ( $type eq 'point' ) {
+$^W = 0;
+        $typeStyle = 'default'
+            unless grep { $typeStyle eq $_ } ('circle', 'donut',
+                                              'triangle', 'upsidedownTriangle',
+                                              'square', 'hollowSquare',
+                                              'fatPlus');
+$^W = 1;
+
+        my ($xc, $yc) = ($radius-1, $radius-1);
+
+        # Note that 'default' will produce the same effect
+        # as a 'circle' typeStyle
+        if ( grep { $typeStyle eq $_ } ('default', 'circle', 'donut') ) {
+
+            $brush->arc($xc, $yc, $radius, $radius, 0, 360, $newcolor);
+            $brush->fill ($xc, $yc, $newcolor);
+
+            # draw a white (and therefore transparent) circle in the middle
+            # of the existing circle to make the "donut", if appropriate
+
+            if ( $typeStyle eq 'donut' ) {
+                $brush->arc($xc, $yc, int($radius/2), int($radius/2),
+                            0, 360, $white);
+                $brush->fill ($xc, $yc, $white);
+            }
+        }
+
+        if ( grep { $typeStyle eq $_ } ('triangle', 'upsidedownTriangle' ) ){
+
+            my $poly = new GD::Polygon;
+            my $sign = ( $typeStyle eq 'triangle' ) ? 1 : (-1);
+            my $z = int (0.8 * $radius); # scaling factor
+
+            # co-ords are chosen to make an equilateral triangle
+
+            $poly->addPt($xc,
+                         $yc - ($z * $sign));
+            $poly->addPt($xc + int((sqrt(3) * $z) / 2),
+                         $yc + (int($z/2) * $sign));
+            $poly->addPt($xc - int((sqrt(3) * $z) / 2),
+                         $yc + (int($z/2) * $sign));
+
+            $brush->filledPolygon($poly, $newcolor);
+        }
+
+        if ( $typeStyle eq 'fatPlus' ) {
+
+            my $poly = new GD::Polygon;
+
+            my $z = int(0.3 * $radius);
+
+            $poly->addPt($xc +     $z, $yc + $z);
+            $poly->addPt($xc + 2 * $z, $yc + $z);
+            $poly->addPt($xc + 2 * $z, $yc - $z);
+
+            $poly->addPt($xc + $z,     $yc - $z);
+            $poly->addPt($xc + $z,     $yc - 2 * $z);
+            $poly->addPt($xc - $z,     $yc - 2 * $z);
+
+            $poly->addPt($xc -     $z, $yc - $z);
+            $poly->addPt($xc - 2 * $z, $yc - $z);
+            $poly->addPt($xc - 2 * $z, $yc + $z);
+
+            $poly->addPt($xc - $z,     $yc + $z);
+            $poly->addPt($xc - $z,     $yc + 2 * $z);
+            $poly->addPt($xc + $z,     $yc + 2 * $z);
+            $brush->filledPolygon($poly, $newcolor);
+        }
+
+        if ( grep { $typeStyle eq $_ } ('square', 'hollowSquare') ) {
+
+            my $poly = new GD::Polygon;
+            my $z = int (0.5 * $radius);
+
+            $brush->filledRectangle($xc - $z, $yc - $z,
+                                    $xc + $z, $yc + $z,
+                                    $newcolor);
+
+            if ( $typeStyle eq 'hollowSquare' ) {
+
+                $z = int($z/2);
+
+                $brush->filledRectangle($xc - $z, $yc - $z,
+                                        $xc + $z, $yc + $z,
+                                        $white);
+            }
+        }
+    }
+
+    # set the new image as the main object's brush
+    return $brush;
+}
+
+#
+# default tick conversion function
+# This function is pointed to be $self->{f_x_tick} resp. $self->{f_y_tick}
+# if the user does not provide another function
+#
+sub _default_f_tick {
+    my $label     = shift;
+    
+    return $label;
+}
+
+
+
+
+## be a good module and return positive
+1;
+

Added: packages/libchart-perl/branches/upstream/current/Chart/Composite.pm
===================================================================
--- packages/libchart-perl/branches/upstream/current/Chart/Composite.pm	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/Chart/Composite.pm	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,1302 @@
+#====================================================================
+#  Chart::Composite
+#
+#  written by david bonner
+#  dbonner at cs.bu.edu
+#
+#  maintained by the Chart Group
+#  Chart at wettzell.ifag.de
+#
+#
+#---------------------------------------------------------------------
+# History:
+#----------
+# $RCSfile: Composite.pm,v $ $Revision: 1.4 $ $Date: 2003/02/14 13:25:30 $
+# $Author: dassing $
+# $Log: Composite.pm,v $
+# Revision 1.4  2003/02/14 13:25:30  dassing
+# Circumvent division of zeros
+#
+#====================================================================
+
+package Chart::Composite;
+
+use Chart::Base '2.4.1';
+use GD;
+use Carp;
+use strict;
+
+ at Chart::Composite::ISA = qw(Chart::Base);
+$Chart::Composite::VERSION = '2.4.1';
+
+#>>>>>>>>>>>>>>>>>>>>>>>>>>#
+#  public methods go here  #
+#<<<<<<<<<<<<<<<<<<<<<<<<<<#
+
+## have to override set, so we can pass the options to the 
+## sub-objects later
+sub set {
+  my $self = shift;
+  my %opts = @_;
+
+  # basic error checking on the options, just warn 'em
+  unless ($#_ % 2) {
+    carp "Whoops, some option to be set didn't have a value.\n",
+         "You might want to look at that.\n";
+  }
+
+  # store the options they gave us
+  unless ($self->{'opts'}) {
+    $self->{'opts'} = {};
+  }
+
+  # now set 'em
+  for (keys %opts) {
+    $self->{$_} = $opts{$_};
+    $self->{'opts'}{$_} = $opts{$_};
+  }
+
+  # now return
+  return;
+}
+
+
+##  get the information to turn the chart into an imagemap
+##  had to override it to reassemble the @data array correctly
+sub imagemap_dump {
+  my $self = shift;
+  my ($i, $j);
+  my @map;
+  my $dataset_count = 0;
+ 
+  # croak if they didn't ask me to remember the data, or if they're asking
+  # for the data before I generate it
+  unless (($self->{'imagemap'} =~ /^true$/i) && $self->{'imagemap_data'}) {
+    croak "You need to set the imagemap option to true, and then call the png method, before you can get the imagemap data";
+  }
+
+  #make a copy of the imagemap data
+  #this is the data of the first component
+  for $i (1..$#{$self->{'sub_0'}->{'imagemap_data'}}) {
+    for $j (0..$#{$self->{'sub_0'}->{'imagemap_data'}->[$i]}-1) {
+       $map[$i][$j] = \@{$self->{'sub_0'}->{'imagemap_data'}->[$i][$j]} ;
+    }
+    $dataset_count++;
+  }
+  #and add the data of the second component
+  for $i (1..$#{$self->{'sub_1'}->{'imagemap_data'}}) {
+    for $j (0..$#{$self->{'sub_1'}->{'imagemap_data'}->[$i]}-1) {
+      $map[$i+$dataset_count][$j] = \@{$self->{'sub_1'}->{'imagemap_data'}->[$i][$j]} ;
+    }
+  }
+  
+
+  # return their copy
+  return \@map;
+
+}
+
+sub __print_array {
+   my @a = @_;
+   my $i;
+   
+   my $li = $#a;
+   
+   $li++;
+   print STDERR "Anzahl der Elemente = $li\n"; $li--;
+   
+   for ($i=0; $i<=$li; $i++) {
+      print STDERR "\t$i\t$a[$i]\n";
+   }
+}
+   
+#>>>>>>>>>>>>>>>>>>>>>>>>>>>#
+#  private methods go here  #
+#<<<<<<<<<<<<<<<<<<<<<<<<<<<#
+
+##  make sure the data isn't really weird
+##  and collect some basic info about it
+sub _check_data {
+  my $self = shift;
+  my $length = 0;
+
+  # first things first, make sure we got the composite_info
+  unless (($self->{'composite_info'}) && ($#{$self->{'composite_info'}} == 1)) {
+    croak "Chart::Composite needs to be told what kind of components to use";
+  }
+
+  # make sure we don't end up dividing by zero if they ask for
+  # just one y_tick
+  if ($self->{'y_ticks'} == 1) {
+    $self->{'y_ticks'} = 2;
+    carp "The number of y_ticks displayed must be at least 2";
+  }
+
+  # remember the number of datasets
+  $self->{'num_datasets'} = $#{$self->{'dataref'}};
+
+  # remember the number of points in the largest dataset
+  $self->{'num_datapoints'} = 0;
+  for (0..$self->{'num_datasets'}) {
+    if (scalar(@{$self->{'dataref'}[$_]}) > $self->{'num_datapoints'}) {
+      $self->{'num_datapoints'} = scalar(@{$self->{'dataref'}[$_]});
+    }
+  }
+
+  # find the longest x-tick label, and remember how long it is
+  for (@{$self->{'dataref'}[0]}) {
+    if (length ($_) > $length) {
+      $length = length ($_);
+    }
+  }
+  $self->{'x_tick_label_length'} = $length;
+
+  # now split the data into sub-objects
+  $self->_split_data;
+
+  return;
+}
+
+
+## create sub-objects for each type, store the appropriate
+## data sets in each one, and stick the correct values into
+## them (ie. 'gd_obj');
+sub _split_data {
+  my $self = shift;
+  my @types = ($self->{'composite_info'}[0][0],$self->{'composite_info'}[1][0]);
+  my ($ref, $i, $j);
+
+## Already checked for number of components in _check_data, above.
+#   # we can only do two at a time
+#   if ($self->{'composite_info'}[2]) {
+#     croak "Sorry, Chart::Composite can only do two chart types at a time";
+#   }
+
+  # load the individual modules
+  require "Chart/".$types[0].".pm";
+  require "Chart/".$types[1].".pm"; 
+
+  # create the sub-objects
+  $self->{'sub_0'} = ("Chart::".$types[0])->new();
+  $self->{'sub_1'} = ("Chart::".$types[1])->new();
+
+  # set the options (set the min_val, max_val, brush_size, y_ticks,
+  # 
+  # options intelligently so that the sub-objects don't get
+  # confused)
+  $self->{'sub_0'}->set (%{$self->{'opts'}});
+  $self->{'sub_1'}->set (%{$self->{'opts'}});
+  if (defined ($self->{'opts'}{'min_val1'})) {
+    $self->{'sub_0'}->set ('min_val' => $self->{'opts'}{'min_val1'});
+  }
+  if (defined ($self->{'opts'}{'max_val1'})) {
+    $self->{'sub_0'}->set ('max_val' => $self->{'opts'}{'max_val1'});
+  }
+  if (defined ($self->{'opts'}{'min_val2'})) {
+    $self->{'sub_1'}->set ('min_val' => $self->{'opts'}{'min_val2'});
+  }
+  if (defined ($self->{'opts'}{'max_val2'})) {
+    $self->{'sub_1'}->set ('max_val' => $self->{'opts'}{'max_val2'});
+  }
+  if ($self->{'opts'}{'y_ticks1'}) {
+    $self->{'sub_0'}->set ('y_ticks' => $self->{'opts'}{'y_ticks1'});
+  } 
+  if ($self->{'opts'}{'y_ticks2'}) {
+    $self->{'sub_1'}->set ('y_ticks' => $self->{'opts'}{'y_ticks2'});
+  }
+  if ($self->{'opts'}{'brush_size1'}) {
+    $self->{'sub_0'}->set ('brush_size' => $self->{'opts'}{'brush_size1'});
+  } 
+  if ($self->{'opts'}{'brush_size2'}) {
+    $self->{'sub_1'}->set ('brush_size' => $self->{'opts'}{'brush_size2'});
+  }
+  
+  #  f_y_tick for left and right axis
+  if (defined ($self->{'opts'}{'f_y_tick1'})) {
+    $self->{'sub_0'}->set ('f_y_tick' => $self->{'opts'}{'f_y_tick1'});
+  }
+  if (defined ($self->{'opts'}{'f_y_tick2'})) {
+    $self->{'sub_1'}->set ('f_y_tick' => $self->{'opts'}{'f_y_tick2'});
+  }
+
+  # replace the gd_obj fields
+  $self->{'sub_0'}->{'gd_obj'} = $self->{'gd_obj'};
+  $self->{'sub_1'}->{'gd_obj'} = $self->{'gd_obj'};
+
+  # let the sub-objects know they're sub-objects
+  $self->{'sub_0'}->{'component'} = 'true';
+  $self->{'sub_1'}->{'component'} = 'true';
+
+  # give each sub-object its data
+  $self->{'component_datasets'} = [];
+  for $i (0..1) {
+    $ref = [];
+    $self->{'component_datasets'}[$i] = $self->{'composite_info'}[$i][1];
+    push @{$ref}, $self->{'dataref'}[0];
+    for $j (@{$self->{'composite_info'}[$i][1]}) {
+      $self->_color_role_to_index('dataset'.($j-1)); # allocate color index
+      push @{$ref}, $self->{'dataref'}[$j];
+    }
+    $self->{'sub_'.$i}->_copy_data ($ref);
+  }
+
+  # and let them check it
+  $self->{'sub_0'}->_check_data;
+  $self->{'sub_1'}->_check_data;
+
+  # realign the y-axes if they want
+  if ($self->{'same_y_axes'} =~ /^true$/i) {
+    if ($self->{'sub_0'}{'min_val'} < $self->{'sub_1'}{'min_val'}) {
+      $self->{'sub_1'}{'min_val'} = $self->{'sub_0'}{'min_val'};
+    }
+    else {
+      $self->{'sub_0'}{'min_val'} = $self->{'sub_1'}{'min_val'};
+    }
+
+    if ($self->{'sub_0'}{'max_val'} > $self->{'sub_1'}{'max_val'}) {
+      $self->{'sub_1'}{'max_val'} = $self->{'sub_0'}{'max_val'};
+    }
+    else {
+      $self->{'sub_0'}{'max_val'} = $self->{'sub_1'}{'max_val'};
+    }
+
+    $self->{'sub_0'}->_check_data;
+    $self->{'sub_1'}->_check_data;
+  }
+	
+  # find out how big the y-tick labels will be from sub_0 and sub_1
+  $self->{'y_tick_label_length1'} = $self->{'sub_0'}->{'y_tick_label_length'};
+  $self->{'y_tick_label_length2'} = $self->{'sub_1'}->{'y_tick_label_length'};
+
+  # now return
+  return;
+}
+
+sub _draw_legend {
+  my $self = shift;
+  my ($length);
+ 
+  # check to see if they have as many labels as datasets,
+  # warn them if not
+  if (($#{$self->{'legend_labels'}} >= 0) &&
+       ((scalar(@{$self->{'legend_labels'}})) != $self->{'num_datasets'})) {
+    carp "The number of legend labels and datasets doesn\'t match";
+  }
+ 
+  # init a field to store the length of the longest legend label
+  unless ($self->{'max_legend_label'}) {
+    $self->{'max_legend_label'} = 0;
+  }
+ 
+  # fill in the legend labels, find the longest one
+  for (1..$self->{'num_datasets'}) {
+    unless ($self->{'legend_labels'}[$_-1]) {
+      $self->{'legend_labels'}[$_-1] = "Dataset $_";
+    }
+    $length = length($self->{'legend_labels'}[$_-1]);
+    if ($length > $self->{'max_legend_label'}) {
+      $self->{'max_legend_label'} = $length;
+    }
+  }
+ 
+  # different legend types
+  if ($self->{'legend'} eq 'bottom') {
+    $self->_draw_bottom_legend;
+  }
+  elsif ($self->{'legend'} eq 'right') {
+    $self->_draw_right_legend;
+  }
+  elsif ($self->{'legend'} eq 'left') {
+    $self->_draw_left_legend;
+  }
+  elsif ($self->{'legend'} eq 'top') {
+    $self->_draw_top_legend;
+  } elsif ($self->{'legend'} eq 'none') {
+    $self->_draw_none_legend;
+  } else {
+    carp "I can't put a legend there\n";
+  }
+ 
+  # and return
+  return 1;
+}
+
+## put the legend on the top of the data plot
+sub _draw_top_legend {
+  my $self = shift;
+  my @labels = @{$self->{'legend_labels'}};
+  my ($x1, $y1, $x2, $y2, $empty_width, $max_label_width, $cols, $rows, $color);
+  my ($col_width, $row_height, $i, $j, $r, $c, $index, $x, $y, $sub, $w, $h);
+  my ($yh,$yi); #  for boxing legends
+  my $font = $self->{'legend_font'};
+  my (%colors, @datasets);
+  my $max_legend_example=0;
+  $yh=0;
+
+  # copy the current boundaries into the sub-objects
+  $self->_sub_update;
+  
+  # init the legend_example_height
+  $self->_legend_example_height_init;
+
+## Make datasetI numbers match indexes of @{ $self->{'dataref'} }[1.....].
+#   # modify the dataset color table entries to avoid duplicating
+#   # dataset colors (this limits the number of possible data sets
+#   # for each component to 8)
+#   for (0..7) {
+#     $self->{'sub_1'}{'color_table'}{'dataset'.$_} 
+#       = $self->{'color_table'}{'dataset'.($_+8)};
+#   }
+  # modify the dataset color table entries to avoid duplicating
+  # dataset colors.
+  my ($n0, $n1) = map { scalar @{ $self->{'composite_info'}[$_][1] } } 0..1;
+  for (0..$n1-1) {
+    $self->{'sub_1'}{'color_table'}{'dataset'.$_} 
+      = $self->{'color_table'}{'dataset'.($_+$n0)};
+  }
+
+  # make sure we use the right colors for the legend
+  @datasets = @{$self->{'composite_info'}[0][1]};
+  $i = 0;
+  for (0..$#datasets) {
+    $colors{$datasets[$_]-1} = $self->{'color_table'}{'dataset'.($i)};
+    $i++;
+  }
+  @datasets = @{$self->{'composite_info'}[1][1]};
+  $i = 0;
+  for (0..$#datasets) {
+    $colors{$datasets[$_]-1} = $self->{'color_table'}{'dataset'.($i+$n0)};
+    $i++;
+  }
+
+  # make sure we're using a real font
+  unless ((ref ($font)) eq 'GD::Font') {
+    croak "The subtitle font you specified isn\'t a GD Font object";
+  }
+
+  # get the size of the font
+  ($h, $w) = ($font->height, $font->width);
+
+  # get some base x coordinates
+  $x1 = $self->{'curr_x_min'} + $self->{'graph_border'}
+          + $self->{'y_tick_label_length1'} * $self->{'tick_label_font'}->width
+	  + $self->{'tick_len'} + (3 * $self->{'text_space'});
+  $x2 = $self->{'curr_x_max'} - $self->{'graph_border'}
+          - $self->{'y_tick_label_length2'} * $self->{'tick_label_font'}->width
+	  - $self->{'tick_len'} - (3 * $self->{'text_space'});
+  if ($self->{'y_label'}) {
+    $x1 += $self->{'label_font'}->height + 2 * $self->{'text_space'};
+  }
+  if ($self->{'y_label2'}) {
+    $x2 -= $self->{'label_font'}->height + 2 * $self->{'text_space'};
+  }
+
+  # figure out how wide the widest label is, then figure out how many
+  # columns we can fit into the allotted space
+  $empty_width = $x2 - $x1 - (2 * $self->{'legend_space'});
+  $max_label_width = $self->{'max_legend_label'} 
+    * $self->{'legend_font'}->width + 4 * $self->{'text_space'}
+    + $self->{'legend_example_size'};
+  $cols = int ($empty_width / $max_label_width);
+  unless ($cols) {
+    $cols = 1;
+  }
+  $col_width = $empty_width / $cols;
+
+  # figure out how many rows we need and how tall they are
+  $rows = int ($self->{'num_datasets'} / $cols);
+  unless (($self->{'num_datasets'} % $cols) == 0) {
+    $rows++;
+  }
+  unless ($rows) {
+    $rows = 1;
+  }
+  $row_height = $h + $self->{'text_space'};
+
+  # box the legend off
+  $y1 = $self->{'curr_y_min'};
+  $y2 = $self->{'curr_y_min'} + $self->{'text_space'}
+          + ($rows * $row_height) + (2 * $self->{'legend_space'});
+  $self->{'gd_obj'}->rectangle($x1, $y1, $x2, $y2, 
+                               $self->_color_role_to_index('misc'));
+			       
+  $max_legend_example = $y2-$y1;
+  # leave some space inside the legend
+  $x1 += $self->{'legend_space'} + $self->{'text_space'};
+  $x2 -= $self->{'legend_space'};
+  $y1 += $self->{'legend_space'} + $self->{'text_space'};
+  $y2 -= $self->{'legend_space'} + $self->{'text_space'};
+
+  # draw in the actual legend
+  $r = 0; # current row
+  $c = 0; # current column
+  $yi= 0; # current dataset
+   
+  for $i (0..1) {
+    for $j (0..$#{$self->{'component_datasets'}[$i]}) {
+      # get the color
+      $color = $self->{'sub_'.$i}->{'color_table'}{'dataset'.$j};
+      $index = $self->{'component_datasets'}[$i][$j] - 1; # index in label list
+
+      # find the x-y coordinates for the beginning of the example line
+      $x = $x1 + ($col_width * $c);
+      $y = $y1 + ($row_height * $r) + $h/2;
+
+	  #  draw the example line if legend_example_height==1 or ==0
+	  if ($rows==1) {
+	  if ($self->{'legend_example_height'.$yi}<$max_legend_example) {
+	    $yh = $self->{'legend_example_height'.$yi};
+	    }
+	  else {
+	    $yh = $max_legend_example;
+	    }
+	   }
+	   else {
+	   if ($self->{'legend_example_height'.$yi}<$row_height) {
+	    $yh = $self->{'legend_example_height'.$yi};
+	    }
+	   else {
+	     $yh = $row_height;
+	     }
+	   } 
+	   $yi++;
+	if ($yh <= 1) {
+      $self->{'gd_obj'}->line ($x, $y,
+                               $x + $self->{'legend_example_size'}, $y,
+			       $color);
+	} else {
+	  #  draw the example bar if legend_example_height > 1
+	  $yh = int($yh / 2);
+      $self->{'gd_obj'}->filledRectangle ($x, $y-$yh,
+                               $x + $self->{'legend_example_size'}, $y+$yh,
+			       $color);
+	}
+
+      # find the x-y coordinates for the beginning of the label
+      $x += $self->{'legend_example_size'} + 2 * $self->{'text_space'};
+      $y -= $h/2;
+      
+      # now draw the label
+      $self->{'gd_obj'}->string($font, $x, $y, 
+                                $labels[$index], $color);
+
+      # keep track of which row/column we're using
+      $r = ($r + 1) % $rows;
+      if ($r == 0) {
+	$c++;
+      }
+    }
+  }
+  
+      
+  # mark of the space used
+  $self->{'curr_y_min'} += ($rows * $row_height)
+  			      + $self->{'text_space'}
+			      + 2 * $self->{'legend_space'}; 
+
+  return;
+}
+
+
+## put the legend on the right of the chart
+sub _draw_right_legend {
+  my $self = shift;
+  my @labels = @{$self->{'legend_labels'}};
+  my ($x1, $x2, $x3, $y1, $y2, $width, $color, $misccolor, $w, $h);
+  my ($yh)=0; # for boxing legend
+  my $font = $self->{'legend_font'};
+  my (%colors, @datasets, $i); 
+  my $max_legend_example = 0;
+  
+  
+  # copy the current boundaries and colors into the sub-objects
+  $self->_sub_update;
+  
+  # init the legend exapmle height
+  $self->_legend_example_height_init;
+  
+#   # modify the dataset color table entries to avoid duplicating
+#   # dataset colors (this limits the number of possible data sets
+#   # for each component to 8)
+#   for (0..7) {
+#     $self->{'sub_1'}{'color_table'}{'dataset'.$_}
+#       = $self->{'color_table'}{'dataset'.($_+8)};
+#   }
+  # modify the dataset color table entries to avoid duplicating
+  # dataset colors.
+  my ($n0, $n1) = map { scalar @{ $self->{'composite_info'}[$_][1] } } 0..1;
+  
+  for (0..$n1-1) {
+    $self->{'sub_1'}{'color_table'}{'dataset'.$_} 
+      = $self->{'color_table'}{'dataset'.($_+$n0)};
+  }
+  
+  
+  
+  # make sure we use the right colors for the legend
+  @datasets = @{$self->{'composite_info'}[0][1]};
+  $i = 0;
+  for (0..$#datasets) {
+   $colors{$datasets[$_]-1} = $self->{'color_table'}{'dataset'.($_)};
+    $i++;
+  }
+   
+  @datasets = @{$self->{'composite_info'}[1][1]};
+  $i = 0;
+  for (0..$#datasets) {
+    $colors{$datasets[$_]-1} = $self->{'color_table'}{'dataset'.($i+$n0)};
+    $i++;
+  }
+      
+  # make sure we're using a real font
+  unless ((ref ($font)) eq 'GD::Font') {
+    croak "The subtitle font you specified isn\'t a GD Font object";
+  }
+
+  # get the size of the font
+  ($h, $w) = ($font->height, $font->width);
+ 
+  # get the miscellaneous color
+  $misccolor = $self->_color_role_to_index('misc');
+
+  # find out how wide the largest label is
+  $width = (2 * $self->{'text_space'})
+    + ($self->{'max_legend_label'} * $w)
+    + $self->{'legend_example_size'}
+    + (2 * $self->{'legend_space'});
+
+  # box the thing off
+  $x1 = $self->{'curr_x_max'} - $width;
+  $x2 = $self->{'curr_x_max'};
+  $y1 = $self->{'curr_y_min'} + $self->{'graph_border'} ;
+  $y2 = $self->{'curr_y_min'} + $self->{'graph_border'} + $self->{'text_space'}
+          + ($self->{'num_datasets'} * ($h + $self->{'text_space'}))
+          + (2 * $self->{'legend_space'});
+  $self->{'gd_obj'}->rectangle ($x1, $y1, $x2, $y2, $misccolor);
+
+  # leave that nice space inside the legend box
+  $x1 += $self->{'legend_space'};
+  $y1 += $self->{'legend_space'} + $self->{'text_space'};
+
+  # now draw the actual legend
+  for (0..$#labels) { 
+    # get the color
+    $color = $colors{$_};
+    
+    # find the max_legend_example
+    $max_legend_example = $self->{'legend_space'}+$h; 
+   
+    # find the x-y coords
+    $x2 = $x1;
+    $x3 = $x2 + $self->{'legend_example_size'};
+    $y2 = $y1 + ($_ * ($self->{'text_space'} + $h)) + $h/2;
+
+	# draw the example line if legend_example_height==1 or ==0
+	if ($self->{'legend_example_height'.$_}<$max_legend_example) {
+	   $yh = $self->{'legend_example_height'.$_};
+	   }
+	else {
+	   $yh = $max_legend_example;
+	   }   
+	if ($yh <= 1) {
+      $self->{'gd_obj'}->line ($x2, $y2, $x3, $y2, $color);
+	} else {
+	  $yh = int($yh / 2);
+	  $self->{'gd_obj'}->filledRectangle ($x2, $y2-$yh, $x3, $y2+$yh, $color);
+	}
+
+    # now the label
+    $x2 = $x3 + (2 * $self->{'text_space'});
+    $y2 -= $h/2;
+    $self->{'gd_obj'}->string ($font, $x2, $y2, $labels[$_], $color);
+   
+  }
+
+  # mark off the used space
+  $self->{'curr_x_max'} -= $width;
+
+  # and return
+  return;
+}
+
+##  draw the legend at the left of the data plot
+sub _draw_left_legend {
+  my $self = shift;
+  my @labels = @{$self->{'legend_labels'}};
+  my ($x1, $x2, $x3, $y1, $y2, $width, $color, $misccolor, $w, $h);
+  my $yh; # for boxing legend
+  my $font = $self->{'legend_font'};
+  my (%colors, @datasets, $i);
+  my $max_legend_example=0;
+ 
+  # copy the current boundaries and colors into the sub-objects
+  $self->_sub_update;
+  
+  # init the legend_example height
+  $self->_legend_example_height_init;
+#   # modify the dataset color table entries to avoid duplicating
+#   # dataset colors (this limits the number of possible data sets
+#   # for each component to 8)
+#   for (0..7) {
+#     $self->{'sub_1'}{'color_table'}{'dataset'.$_}
+#       = $self->{'color_table'}{'dataset'.($_+8)};
+#   }
+  # modify the dataset color table entries to avoid duplicating
+  # dataset colors.
+  my ($n0, $n1) = map { scalar @{ $self->{'composite_info'}[$_][1] } } 0..1;
+  for (0..$n1-1) {
+    $self->{'sub_1'}{'color_table'}{'dataset'.$_} 
+      = $self->{'color_table'}{'dataset'.($_+$n0)};
+  }
+
+  # make sure we use the right colors for the legend
+  @datasets = @{$self->{'composite_info'}[0][1]};
+  $i = 0;
+  for (0..$#datasets) {
+    $colors{$datasets[$_]-1} = $self->{'color_table'}{'dataset'.($i)};
+    $i++;
+  }
+  @datasets = @{$self->{'composite_info'}[1][1]};
+  $i = 0;
+  for (0..$#datasets) {
+    $colors{$datasets[$_]-1} = $self->{'color_table'}{'dataset'.($i+$n0)};
+    $i++;
+  }
+ 
+  # make sure we're using a real font
+  unless ((ref ($font)) eq 'GD::Font') {
+    croak "The subtitle font you specified isn\'t a GD Font object";
+  }
+ 
+  # get the size of the font
+  ($h, $w) = ($font->height, $font->width);
+ 
+  # get the miscellaneous color
+  $misccolor = $self->_color_role_to_index('misc');
+ 
+  # find out how wide the largest label is
+  $width = (2 * $self->{'text_space'})
+    + ($self->{'max_legend_label'} * $w)
+    + $self->{'legend_example_size'}
+    + (2 * $self->{'legend_space'});
+ 
+  # get some base x-y coordinates
+  $x1 = $self->{'curr_x_min'};
+  $x2 = $self->{'curr_x_min'} + $width;
+  $y1 = $self->{'curr_y_min'} + $self->{'graph_border'} ;
+  $y2 = $self->{'curr_y_min'} + $self->{'graph_border'} + $self->{'text_space'
+}
+          + ($self->{'num_datasets'} * ($h + $self->{'text_space'}))
+          + (2 * $self->{'legend_space'});
+ 
+  # box the legend off
+  $self->{'gd_obj'}->rectangle ($x1, $y1, $x2, $y2, $misccolor);
+ 
+  # leave that nice space inside the legend box
+  $x1 += $self->{'legend_space'};
+  $y1 += $self->{'legend_space'} + $self->{'text_space'};
+ 
+  # now draw the actual legend
+  for (0..$#labels) {
+    # get the color
+    $color = $colors{$_};
+   
+    # find the max_legend_example    
+    $max_legend_example = $self->{'legend_space'} + $h;
+    
+    # find the x-y coords
+    $x2 = $x1;
+    $x3 = $x2 + $self->{'legend_example_size'};
+    $y2 = $y1 + ($_ * ($self->{'text_space'} + $h)) + $h/2;
+ 
+	# draw the example line if legend_example_height==1 or ==0
+	if ($self->{'legend_example_height'.$_}<$max_legend_example) {
+	   $yh = $self->{'legend_example_height'.$_};
+	   }
+	else {
+	   $yh = $max_legend_example;
+	   }   
+	if ($yh <= 1) {
+      $self->{'gd_obj'}->line ($x2, $y2, $x3, $y2, $color);
+	} else {
+	  # draw the example bar if legend_example_height > 1
+	  $yh = int($yh / 2);
+      $self->{'gd_obj'}->filledRectangle ($x2, $y2-$yh, $x3, $y2+$yh, $color);
+	}
+ 
+    # now the label
+    $x2 = $x3 + (2 * $self->{'text_space'});
+    $y2 -= $h/2;
+    $self->{'gd_obj'}->string ($font, $x2, $y2, $labels[$_], $color);
+  }
+ 
+  # mark off the used space
+  $self->{'curr_x_min'} += $width;
+ 
+  # and return
+  return 1;
+}
+
+
+##  draw the legend on the bottom of the data plot
+sub _draw_bottom_legend {
+  my $self = shift;
+  my @labels = @{$self->{'legend_labels'}};
+  my ($x1, $y1, $x2, $y2, $empty_width, $max_label_width, $cols, $rows, $color);
+  my ($col_width, $row_height, $i, $j, $r, $c, $index, $x, $y, $sub, $w, $h);
+  my ($yh,$yi); # for boxing legend
+  my $font = $self->{'legend_font'};
+  my (%colors, @datasets);
+  my $max_legend_example=0;
+  $yh=0;
+
+  # copy the current boundaries and colors into the sub-objects
+  $self->_sub_update;
+  # init the legend example height
+  $self->_legend_example_height_init;
+  
+#   # modify the dataset color table entries to avoid duplicating
+#   # dataset colors (this limits the number of possible data sets
+#   # for each component to 8)
+#   for (0..7) {
+#     $self->{'sub_1'}{'color_table'}{'dataset'.$_} 
+#       = $self->{'color_table'}{'dataset'.($_+8)};
+#   }
+  # modify the dataset color table entries to avoid duplicating
+  # dataset colors.
+  my ($n0, $n1) = map { scalar @{ $self->{'composite_info'}[$_][1] } } 0..1;
+  for (0..$n1-1) {
+    $self->{'sub_1'}{'color_table'}{'dataset'.$_} 
+      = $self->{'color_table'}{'dataset'.($_+$n0)};
+  }
+
+  @datasets = @{$self->{'composite_info'}[0][1]};
+  $i = 0;
+  for (0..$#datasets) {
+    $colors{$datasets[$_]-1} = $self->{'color_table'}{'dataset'.($i)};
+    $i++;
+  }
+  @datasets = @{$self->{'composite_info'}[1][1]};
+  $i = 0;
+  for (0..$#datasets) {
+    $colors{$datasets[$_]-1} = $self->{'color_table'}{'dataset'.($i+$n0)};
+    $i++;
+  }
+
+  # make sure we're using a real font
+  unless ((ref ($font)) eq 'GD::Font') {
+    croak "The subtitle font you specified isn\'t a GD Font object";
+  }
+
+  # get the size of the font
+  ($h, $w) = ($font->height, $font->width);
+  
+
+  # figure out how many columns we can fit
+  $x1 = $self->{'curr_x_min'} + $self->{'graph_border'}
+          + $self->{'y_tick_label_length1'} * $self->{'tick_label_font'}->width
+	  + $self->{'tick_len'} + (3 * $self->{'text_space'});
+  $x2 = $self->{'curr_x_max'} - $self->{'graph_border'}
+          - $self->{'y_tick_label_length2'} * $self->{'tick_label_font'}->width
+	  - $self->{'tick_len'} - (3 * $self->{'text_space'});
+  if ($self->{'y_label'}) {
+    $x1 += $self->{'label_font'}->height + 2 * $self->{'text_space'};
+  }
+  if ($self->{'y_label2'}) {
+    $x2 -= $self->{'label_font'}->height + 2 * $self->{'text_space'};
+  }
+  $empty_width = $x2 - $x1 - (2 * $self->{'legend_space'});
+  $max_label_width = $self->{'max_legend_label'} 
+    * $self->{'legend_font'}->width + 4 * $self->{'text_space'}
+    + $self->{'legend_example_size'};
+  $cols = int ($empty_width / $max_label_width);
+  unless ($cols) {
+    $cols = 1;
+  }
+  $col_width = $empty_width / $cols;
+
+  # figure out how many rows we need
+  $rows = int ($self->{'num_datasets'} / $cols);
+  unless (($self->{'num_datasets'} % $cols) == 0) {
+    $rows++;
+    }
+  unless ($rows) {
+    $rows = 1;
+  }
+  $row_height = $h + $self->{'text_space'};
+
+  # box it off
+  $y1 = $self->{'curr_y_max'} - $self->{'text_space'}
+          - ($rows * $row_height) - (2 * $self->{'legend_space'});
+  $y2 = $self->{'curr_y_max'};
+  $self->{'gd_obj'}->rectangle($x1, $y1, $x2, $y2, 
+                               $self->_color_role_to_index('misc'));
+			       
+  # get the max_legend_example_height			       
+  $max_legend_example = $y2-$y1;
+ 		       
+  $x1 += $self->{'legend_space'} + $self->{'text_space'};
+  $x2 -= $self->{'legend_space'};
+  $y1 += $self->{'legend_space'} + $self->{'text_space'};
+  $y2 -= $self->{'legend_space'} + $self->{'text_space'};
+
+  # draw in the actual legend
+  $r = 0;
+  $c = 0;
+  $yi= 0; # current dataset
+    for $i (0..1) {
+      for $j (0..$#{$self->{'component_datasets'}[$i]}) {
+      $color = $self->{'sub_'.$i}->{'color_table'}{'dataset'.$j};
+      $index = $self->{'component_datasets'}[$i][$j] - 1;
+
+      $x = $x1 + ($col_width * $c);
+      $y = $y1 + ($row_height * $r) + $h/2;
+	  
+	  #  draw the example line if legend_example_height==1 or ==0
+	  if ($rows == 1) {
+	  if ($self->{'legend_example_height'.$yi} < $max_legend_example) {
+	    $yh = $self->{'legend_example_height'.$yi};
+	    }
+	  else {
+	    $yh = $max_legend_example;
+	    }
+	  }
+	  else {
+	  if ($self->{'legend_example_height'.$yi} < $row_height) {
+	     $yh = $self->{'legend_example_height'.$yi};
+	     }
+	  else {
+	     $yh = $row_height;
+	     }
+         }    
+	 $yi++;
+	 if ($yh <= 1) {
+          $self->{'gd_obj'}->line ($x, $y,
+		                         $x + $self->{'legend_example_size'}, $y,
+								 $color);
+	  } 
+	  else {
+	    # draw the example bar if legend_example_height > 1
+	    $yh = int($yh / 2);
+        $self->{'gd_obj'}->filledRectangle ($x, $y-$yh,
+				            $x + $self->{'legend_example_size'}, $y+$yh,
+							   $color);
+  	  }
+ 
+      $x += $self->{'legend_example_size'} + 2 * $self->{'text_space'};
+      $y -= $h/2;
+      $self->{'gd_obj'}->string($font, $x, $y, 
+                                $labels[$index], $color);
+
+      # keep track of which row/column we're using
+      $r = ($r + 1) % $rows;
+      if ($r == 0) {
+	$c++;
+      }
+    }
+  }   
+  # mark of the space used
+  $self->{'curr_y_max'} -= ($rows * $row_height)
+  			      + $self->{'text_space'}
+			      + 2 * $self->{'legend_space'}; 
+
+  return;
+}
+
+# no legend to draw.. just update the color tables for subs
+sub _draw_none_legend {
+  my $self = shift;
+
+  $self->_sub_update();
+
+#   for (0..7) {
+#     $self->{'sub_1'}{'color_table'}{'dataset'.$_} 
+#        = $self->{'color_table'}{'dataset'.($_+8)};
+#    }
+  # modify the dataset color table entries to avoid duplicating
+  # dataset colors.
+  my ($n0, $n1) = map { scalar @{ $self->{'composite_info'}[$_][1] } } 0..1;
+  for (0..$n1-1) {
+    $self->{'sub_1'}{'color_table'}{'dataset'.$_} 
+      = $self->{'color_table'}{'dataset'.($_+$n0)};
+  }
+}
+
+
+## draw the ticks and tick labels
+sub _draw_ticks {
+  my $self = shift;
+
+  # draw the x ticks
+  $self->_draw_x_ticks;
+
+  # update the boundaries in the sub-objects
+  $self->_boundary_update ($self, $self->{'sub_0'});
+  $self->_boundary_update ($self, $self->{'sub_1'}); 
+
+  # now the y ticks
+  $self->_draw_y_ticks;
+
+  # then return
+  return;
+}
+
+
+## draw the x-ticks and their labels
+sub _draw_x_ticks {
+  my $self = shift;
+  my $data = $self->{'dataref'};
+  my $font = $self->{'tick_label_font'};
+  my $textcolor = $self->_color_role_to_index('text');
+  my $misccolor = $self->_color_role_to_index('misc');
+  my ($h, $w);
+  my ($x1, $x2, $y1, $y2);
+  my ($width, $delta);
+  my ($stag);
+
+  $self->{'grid_data'}->{'x'} = [];
+
+  # make sure we got a real font
+  unless ((ref $font) eq 'GD::Font') {
+    croak "The tick label font you specified isn\'t a GD Font object";
+  }
+
+  # get the height and width of the font
+  ($h, $w) = ($font->height, $font->width);
+
+  # allow for the amount of space the y-ticks will push the
+  # axes over to the right and to the left
+## _draw_y_ticks allows 3 * text_space, not 2 * ;  this caused mismatch between
+## the ticks (and grid lines) and the data.
+#   $x1 = $self->{'curr_x_min'} + ($w * $self->{'y_tick_label_length1'})
+#          + (2 * $self->{'text_space'}) + $self->{'tick_len'};
+#   $x2 = $self->{'curr_x_max'} - ($w * $self->{'y_tick_label_length2'})
+#          - (2 * $self->{'text_space'}) - $self->{'tick_len'};
+  $x1 = $self->{'curr_x_min'} + ($w * $self->{'y_tick_label_length1'})
+        + (3 * $self->{'text_space'}) + $self->{'tick_len'};
+  $x2 = $self->{'curr_x_max'} - ($w * $self->{'y_tick_label_length2'})
+        - (3 * $self->{'text_space'}) - $self->{'tick_len'};
+  $y1 = $self->{'curr_y_max'} - $h - $self->{'text_space'};
+
+  # get the delta value, figure out how to draw the labels
+  $width = $x2 - $x1;
+  $delta = $width / ( $self->{'num_datapoints'} > 0 ? $self->{'num_datapoints'} : 1 );
+  if ($delta <= ($self->{'x_tick_label_length'} * $w)) {
+    unless ($self->{'x_ticks'} =~ /^vertical$/i) {
+      $self->{'x_ticks'} = 'staggered';
+    }
+  }
+
+  # now draw the labels
+  if ($self->{'x_ticks'} =~ /^normal$/i) { # normal ticks
+    if ($self->{'skip_x_ticks'}) {
+      for (0..int(($self->{'num_datapoints'}-1)/$self->{'skip_x_ticks'})) 
+      {
+        $x2 = $x1 + ($delta/2) + ($delta*($_*$self->{'skip_x_ticks'})) 
+	      - ($w*length( $self->{'f_x_tick'}->($data->[0][$_* $self->{'skip_x_ticks'}]))) / 2;
+        $self->{'gd_obj'}->string($font, $x2, $y1, 
+	                          $self->{'f_x_tick'}->($data->[0][$_*$self->{'skip_x_ticks'}]),
+				  $textcolor);
+      }
+    }
+    elsif ($self->{'custom_x_ticks'}) {
+      for (@{$self->{'custom_x_ticks'}}) {
+        $x2 = $x1 + ($delta/2) + ($delta*$_) - ($w*length( $self->{'f_x_tick'}->($data->[0][$_]))) / 2;
+        $self->{'gd_obj'}->string($font, $x2, $y1,
+                                  $self->{'f_x_tick'}->($data->[0][$_]), $textcolor);
+      }
+    }
+    else 
+    {
+      for (0..$self->{'num_datapoints'}-1) 
+      {
+        $x2 = $x1 + ($delta/2) + ($delta*$_) - ($w*length($self->{'f_x_tick'}->($data->[0][$_]))) / 2;
+        $self->{'gd_obj'}->string($font, $x2, $y1, $self->{'f_x_tick'}->($data->[0][$_]), $textcolor);
+      }
+    }
+  }
+  elsif ($self->{'x_ticks'} =~ /^staggered$/i) { # staggered ticks
+    if ($self->{'skip_x_ticks'}) {
+      $stag = 0;
+      for (0..int(($self->{'num_datapoints'}-1)/$self->{'skip_x_ticks'})) {
+        $x2 = $x1 + ($delta/2) + ($delta*($_*$self->{'skip_x_ticks'})) 
+	        - ($w*length( $self->{'f_x_tick'}->($data->[0][$_*$self->{'skip_x_ticks'}]))) / 2;
+        if (($stag % 2) == 1) {
+          $y1 -= $self->{'text_space'} + $h;
+        }
+        $self->{'gd_obj'}->string($font, $x2, $y1, 
+                                  $self->{'f_x_tick'}->($data->[0][$_*$self->{'skip_x_ticks'}]),
+                                  $textcolor);
+        if (($stag % 2) == 1) {
+          $y1 += $self->{'text_space'} + $h;
+        }
+	$stag++;
+      }
+    }
+    elsif ($self->{'custom_x_ticks'}) {
+      $stag = 0;
+      for (sort (@{$self->{'custom_x_ticks'}})) {
+        $x2 = $x1 + ($delta/2) + ($delta*$_) - ($w*length( $self->{'f_x_tick'}->($data->[0][$_]))) / 2;
+        if (($stag % 2) == 1) {
+          $y1 -= $self->{'text_space'} + $h;
+        }
+        $self->{'gd_obj'}->string($font, $x2, $y1,  $self->{'f_x_tick'}->($data->[0][$_]), $textcolor);
+        if (($stag % 2) == 1) {
+          $y1 += $self->{'text_space'} + $h;
+        }
+	$stag++;
+      }
+    }
+    else {
+      for (0..$self->{'num_datapoints'}-1) {
+        $x2 = $x1 + ($delta/2) + ($delta*$_) - ($w*length( $self->{'f_x_tick'}->($data->[0][$_]))) / 2;
+        if (($_ % 2) == 1) {
+          $y1 -= $self->{'text_space'} + $h;
+        }
+        $self->{'gd_obj'}->string($font, $x2, $y1,  $self->{'f_x_tick'}->($data->[0][$_]), $textcolor);
+        if (($_ % 2) == 1) {
+          $y1 += $self->{'text_space'} + $h;
+        }
+      }
+    }
+  }
+  elsif ($self->{'x_ticks'} =~ /^vertical$/i) { # vertical ticks
+    $y1 = $self->{'curr_y_max'} - $self->{'text_space'};
+    if ( defined($self->{'skip_x_ticks'}) && $self->{'skip_x_ticks'} > 1) {
+      for (0..int(($self->{'num_datapoints'}-1)/$self->{'skip_x_ticks'})) {
+        $x2 = $x1 + ($delta/2) + ($delta*($_*$self->{'skip_x_ticks'})) - $h/2;
+        $y2 = $y1 - (($self->{'x_tick_label_length'} 
+	              - length( $self->{'f_x_tick'}->($data->[0][$_*$self->{'skip_x_ticks'}]))) * $w);
+        $self->{'gd_obj'}->stringUp($font, $x2, $y2, 
+                                    $self->{'f_x_tick'}->($data->[0][$_*$self->{'skip_x_ticks'}]),
+				    $textcolor);
+      }
+    }
+    elsif ($self->{'custom_x_ticks'}) {
+      for (@{$self->{'custom_x_ticks'}}) {
+        $x2 = $x1 + ($delta/2) + ($delta*$_) - $h/2;
+        $y2 = $y1 - (($self->{'x_tick_label_length'} - length( $self->{'f_x_tick'}->($data->[0][$_])))
+                      * $w);
+        $self->{'gd_obj'}->stringUp($font, $x2, $y2, 
+                                    $self->{'f_x_tick'}->($data->[0][$_]), $textcolor);
+      }
+    }
+    else {
+      for (0..$self->{'num_datapoints'}-1) {
+        $x2 = $x1 + ($delta/2) + ($delta*$_) - $h/2;
+        $y2 = $y1 - (($self->{'x_tick_label_length'} - length( $self->{'f_x_tick'}->($data->[0][$_])))
+                      * $w);
+        $self->{'gd_obj'}->stringUp($font, $x2, $y2, 
+	                             $self->{'f_x_tick'}->($data->[0][$_]), $textcolor);
+      }
+    }
+  }
+  else { # error time
+    carp "I don't understand the type of x-ticks you specified";
+  }
+
+  # update the current y-max value
+  if ($self->{'x_ticks'} =~ /^normal$/i) {
+     $self->{'curr_y_max'} -= $h + (2 * $self->{'text_space'});
+  } 
+  elsif ($self->{'x_ticks'} =~ /^staggered$/i) {
+    $self->{'curr_y_max'} -= (2 * $h) + (3 * $self->{'text_space'});
+  }
+  elsif ($self->{'x_ticks'} =~ /^vertical$/i) {
+    $self->{'curr_y_max'} -= ($w * $self->{'x_tick_label_length'})
+                               + (2 * $self->{'text_space'});
+  }
+
+  # now plot the ticks
+  $y1 = $self->{'curr_y_max'};
+  $y2 = $self->{'curr_y_max'} - $self->{'tick_len'};
+  if ($self->{'skip_x_ticks'}) {
+    for (0..int(($self->{'num_datapoints'}-1)/$self->{'skip_x_ticks'})) {
+      $x2 = $x1 + ($delta/2) + ($delta*($_*$self->{'skip_x_ticks'}));
+      $self->{'gd_obj'}->line($x2, $y1, $x2, $y2, $misccolor);
+      if ($self->{'grid_lines'} =~ /^true$/i
+        or $self->{'x_grid_lines'} =~ /^true$/i) {
+        $self->{'grid_data'}->{'x'}->[$_] = $x2;
+      }
+    }
+  }
+  elsif ($self->{'custom_x_ticks'}) {
+    for (@{$self->{'custom_x_ticks'}}) {
+      $x2 = $x1 + ($delta/2) + ($delta*$_);
+      $self->{'gd_obj'}->line($x2, $y1, $x2, $y2, $misccolor);
+      if ($self->{'grid_lines'} =~ /^true$/i
+        or $self->{'x_grid_lines'} =~ /^true$/i) {
+        $self->{'grid_data'}->{'x'}->[$_] = $x2;
+      }
+    }
+  }
+  else {
+    for (0..$self->{'num_datapoints'}-1) {
+      $x2 = $x1 + ($delta/2) + ($delta*$_);
+      $self->{'gd_obj'}->line($x2, $y1, $x2, $y2, $misccolor);
+      if ($self->{'grid_lines'} =~ /^true$/i
+        or $self->{'x_grid_lines'} =~ /^true$/i) {
+        $self->{'grid_data'}->{'x'}->[$_] = $x2;
+      }
+    }
+  }
+
+  # update the current y-max value
+  $self->{'curr_y_max'} -= $self->{'tick_len'};
+
+  # and return
+  return;
+}
+
+
+## draw the y-ticks and their labels
+sub _draw_y_ticks {
+  my $self = shift;
+
+  # let the first guy do his
+  $self->{'sub_0'}->_draw_y_ticks ('left');
+
+  # and update the other two objects
+  $self->_boundary_update ($self->{'sub_0'}, $self);
+  $self->_boundary_update ($self->{'sub_0'}, $self->{'sub_1'});
+
+  # now draw the other ones
+  $self->{'sub_1'}->_draw_y_ticks ('right');
+
+  # and update the other two objects
+  $self->_boundary_update ($self->{'sub_1'}, $self);
+  $self->_boundary_update ($self->{'sub_1'}, $self->{'sub_0'});
+
+  # then return
+  return;
+}
+
+
+## finally get around to plotting the data
+sub _draw_data {
+  my $self = shift;
+
+  # do a grey background if they want it
+  if ($self->{'grey_background'} =~ /^true$/i) {
+    $self->_grey_background;
+    $self->{'sub_0'}->{'grey_background'} = 'false';
+    $self->{'sub_1'}->{'grey_background'} = 'false';
+  }
+
+  # draw grid again if necessary (if grey background ruined it..)
+  unless ($self->{grey_background} !~ /^true$/i) {
+    $self->_draw_grid_lines if ($self->{grid_lines} =~ /^true$/i);
+    $self->_draw_x_grid_lines if ($self->{x_grid_lines} =~ /^true$/i);
+    $self->_draw_y_grid_lines if ($self->{y_grid_lines} =~ /^true$/i);
+    $self->_draw_y2_grid_lines if ($self->{y2_grid_lines} =~ /^true$/i);
+  }
+
+
+  # do a final bounds update
+  $self->_boundary_update ($self, $self->{'sub_0'});
+  $self->_boundary_update ($self, $self->{'sub_1'});
+  
+
+  # init the imagemap data field if they wanted it
+  if ($self->{'imagemap'} =~ /^true$/i) {
+    $self->{'imagemap_data'} = [];
+  }
+
+  # now let the component modules go to work
+  
+  $self->{'sub_0'}->_draw_data;
+  $self->{'sub_1'}->_draw_data;
+      
+  return;
+}
+
+
+## update all the necessary information in the sub-objects
+sub _sub_update {
+  my $self = shift;
+  my $sub0 = $self->{'sub_0'};
+  my $sub1 = $self->{'sub_1'};
+
+  # update the boundaries
+  $self->_boundary_update ($self, $sub0);
+  $self->_boundary_update ($self, $sub1);
+
+  # copy the color tables
+  $sub0->{'color_table'} = { %{$self->{'color_table'}} };
+  $sub1->{'color_table'} = { %{$self->{'color_table'}} };
+
+  # now return
+  return;
+}
+
+
+## copy the current gd_obj boundaries from one object to another
+sub _boundary_update {
+  my $self = shift;
+  my $from = shift;
+  my $to = shift;
+
+  $to->{'curr_x_min'} = $from->{'curr_x_min'};
+  $to->{'curr_x_max'} = $from->{'curr_x_max'};
+  $to->{'curr_y_min'} = $from->{'curr_y_min'};
+  $to->{'curr_y_max'} = $from->{'curr_y_max'};
+
+  return;
+}
+
+sub _draw_y_grid_lines {
+	my ($self) = shift;
+	$self->{'sub_0'}->_draw_y_grid_lines();
+	return;
+}
+
+sub _draw_y2_grid_lines {
+	my ($self) = shift;
+	$self->{'sub_1'}->_draw_y2_grid_lines();
+	return;
+}
+
+
+# init the legend_example_height_values
+sub _legend_example_height_init {
+  my $self = shift;
+  my $a = $self->{'num_datasets'};
+  my ($b, $e) =(0,0);
+  my $bis='..';
+  
+      
+  if ($self->{'legend_example_height'} =~ /^false$/i ) {
+  
+    for my $i (0..$a) {
+    $self->{'legend_example_height'.$i} = 1;
+    }
+  }
+ 
+  if ($self->{'legend_example_height'} =~ /^true$/i ) { 
+ 
+   for my $i (0..$a) {
+   
+   if (defined($self->{'legend_example_height'.$i})) { }
+   else { ($self->{'legend_example_height'.$i}) = 1;}   
+  
+   }
+
+   for  $b (0..$a) {
+    for  $e (0..$a) {
+      my $anh = sprintf($b.$bis.$e);
+       if (defined($self->{'legend_example_height'.$anh})) {
+        if ($b>$e) {croak "Please reverse the datasetnumber in legend_example_height\n";}
+       	  for (my $n=$b;$n<=$e;$n++) {
+	    $self->{'legend_example_height'.$n} = $self->{'legend_example_height'.$anh};
+	 }
+        }
+       }
+    }
+   }
+ 
+  
+  
+}     
+
+## be a good module and return 1
+1;

Added: packages/libchart-perl/branches/upstream/current/Chart/Direction.pm
===================================================================
--- packages/libchart-perl/branches/upstream/current/Chart/Direction.pm	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/Chart/Direction.pm	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,1306 @@
+#====================================================================
+#  Chart::Direction
+#
+#  written by Chart-Group
+#
+#  maintained by the Chart Group
+#  Chart at wettzell.ifag.de
+#
+#---------------------------------------------------------------------
+# History:
+#----------
+# $RCSfile: Direction.pm,v $ $Revision: 1.2 $ $Date: 2003/02/14 13:30:42 $
+# $Author: dassing $
+# $Log: Direction.pm,v $
+# Revision 1.2  2003/02/14 13:30:42  dassing
+# Circumvent division of zeros
+#
+#====================================================================
+
+package Chart::Direction;
+
+use Chart::Base '2.4.1';
+use GD;
+use Carp;
+use strict;
+use POSIX;
+
+ at Chart::Direction::ISA = qw(Chart::Base);
+$Chart::Direction::VERSION = '2.4.1';
+
+#>>>>>>>>>>>>>>>>>>>>>>>>>>#
+#  public methods go here  #
+#<<<<<<<<<<<<<<<<<<<<<<<<<<#
+
+
+
+#>>>>>>>>>>>>>>>>>>>>>>>>>>>#
+#  private methods go here  #
+#<<<<<<<<<<<<<<<<<<<<<<<<<<<#
+
+#we don't need a legend for this type.
+#sub _draw_legend {
+
+#    return 1;
+#}
+
+# we use the find_y_scale methode to det the labels of the circles and the amount of them
+sub _find_y_scale
+{
+    my $self = shift;
+
+    # Predeclare vars.
+    my ($d_min, $d_max);		# Dataset min & max.
+    my ($p_min, $p_max);		# Plot min & max.
+    my ($tickInterval, $tickCount, $skip);
+    my @tickLabels;				# List of labels for each tick.
+    my $maxtickLabelLen = 0;	# The length of the longest tick label.
+
+    # Find the datatset minimum and maximum.
+    ($d_min, $d_max) = $self->_find_y_range();
+
+    # Force the inclusion of zero if the user has requested it.
+    if( $self->{'include_zero'} =~ m!^true$!i )
+    {
+	if( ($d_min * $d_max) > 0 )	# If both are non zero and of the same sign.
+	{
+	    if( $d_min > 0 )	# If the whole scale is positive.
+	    {
+		$d_min = 0;
+	    }
+	    else				# The scale is entirely negative.
+            {
+                $d_max = 0;
+            }
+        }
+    }
+
+    # Allow the dataset range to be overidden by the user.
+    # f_min/max are booleans which indicate that the min & max should not be modified.
+    my $f_min = defined $self->{'min_val'};
+    $d_min = $self->{'min_val'} if $f_min;
+
+    my $f_max = defined $self->{'max_val'};
+    $d_max = $self->{'max_val'} if $f_max;
+
+    # Assert against the min is larger than the max.
+    if( $d_min > $d_max )
+    {
+        croak "The the specified 'min_val' & 'max_val' values are reversed (min > max: $d_min>$d_max)";
+    }
+
+    # Calculate the width of the dataset. (posibly modified by the user)
+    my $d_width = $d_max - $d_min;
+
+    # If the width of the range is zero, forcibly widen it
+    # (to avoid division by zero errors elsewhere in the code).
+    if( 0 == $d_width )
+    {
+        $d_min--;
+	$d_max++;
+        $d_width = 2;
+    }
+
+    # Descale the range by converting the dataset width into
+    # a floating point exponent & mantisa pair.
+    my( $rangeExponent, $rangeMantisa ) = $self->_sepFP( $d_width );
+    my $rangeMuliplier = 10 ** $rangeExponent;
+
+    # Find what tick
+    # to use & how many ticks to plot,
+    # round the plot min & max to suatable round numbers.
+    ($tickInterval, $tickCount, $p_min, $p_max)
+		= $self->_calcTickInterval(
+                                $d_min/$rangeMuliplier, 
+                                $d_max/$rangeMuliplier,
+			        $f_min, $f_max,
+			        $self->{'min_circles'}+1, $self->{'max_circles'}+1);
+    # Restore the tickInterval etc to the correct scale
+    $_ *= $rangeMuliplier foreach($tickInterval, $p_min, $p_max);
+
+    #get the precision for the labels
+    my $precision = $self->{'precision'};
+
+    # Now sort out an array of tick labels.
+	     
+    if ($self->{'polar'} =~ /^false$/i) 
+    {
+        for( my $labelNum = $p_min; $labelNum<=$p_max; $labelNum+=$tickInterval ) 
+	{
+	    my $labelText;
+    
+	    if ( defined $self->{f_y_tick} )
+	    {
+                # Is _default_f_tick function used?
+                if ( $self->{f_y_tick} == \&Chart::Base::_default_f_tick ) 
+                {
+		    $labelText = sprintf("%.".$precision."f", $labelNum);
+                } 
+                else 
+                {
+                    # print \&_default_f_tick;
+		    $labelText = $self->{f_y_tick}->($labelNum);
+                }
+	    }
+	    else
+	    {
+	        $labelText = sprintf("%.".$precision."f", $labelNum);
+	    }
+	    push @tickLabels, $labelText;
+	    $maxtickLabelLen = length $labelText if $maxtickLabelLen < length $labelText;
+	}
+    }
+    else 
+    {
+        # polar == true
+        for( my $labelNum = $p_max; $labelNum>=$p_min; $labelNum-=$tickInterval )
+	{
+	    my $labelText;
+
+	    if ( defined $self->{f_y_tick} )
+	    {
+                # Is _default_f_tick function used?
+                if ( $self->{f_y_tick} == \&Chart::Base::_default_f_tick ) 
+                {
+		    $labelText = sprintf("%.".$precision."f", $labelNum);
+                } 
+                else 
+                {
+                    # print \&_default_f_tick;
+		    $labelText = $self->{f_y_tick}->($labelNum);
+                }
+	    }
+	    else
+	    {
+		$labelText = sprintf("%.".$precision."f", $labelNum);
+	    }
+	    push @tickLabels, $labelText;
+	    $maxtickLabelLen = length $labelText if $maxtickLabelLen < length $labelText;
+        }
+   }
+	    
+	    
+    # Store the calculated data.
+    $self->{'min_val'} = $p_min;
+    $self->{'max_val'} = $p_max;
+    $self->{'y_ticks'} = $tickCount;
+    $self->{'y_tick_labels'} = \@tickLabels;
+    $self->{'y_tick_label_length'} = $maxtickLabelLen;
+
+    # and return.
+    return 1;
+}
+
+# Calculates the tick  in normalised units.
+sub _calcTickInterval
+{       my $self = shift;
+	my(
+		$min, $max,		# The dataset min & max.
+		$minF, $maxF,	# Indicates if those min/max are fixed.
+		$minTicks, $maxTicks,	# The minimum & maximum number of ticks.
+	) = @_;
+
+	# Verify the supplied 'min_y_ticks' & 'max_y_ticks' are sensible.
+	if( $minTicks < 2 )
+	{
+		print STDERR "Chart::Base : Incorrect value for 'min_circles', too small.\n";
+		$minTicks = 2;
+	}
+
+	if( $maxTicks < 5*$minTicks  )
+	{
+		print STDERR "Chart::Base : Incorrect value for 'max_circles', too small.\n";
+		$maxTicks = 5*$minTicks;
+	}
+
+	my $width = $max - $min;
+	my @divisorList;
+
+	for( my $baseMul = 1; ; $baseMul *= 10 )
+	{
+		TRY: foreach my $tryMul (1, 2, 5)
+		{
+			# Calc a fresh, smaller tick interval.
+			my $divisor = $baseMul * $tryMul;
+
+			# Count the number of ticks.
+			my ($tickCount, $pMin, $pMax) = $self->_countTicks($min, $max, 1/$divisor);
+
+			# Look a the number of ticks.
+			if( $maxTicks < $tickCount )
+			{
+				# If it is to high, Backtrack.
+				$divisor = pop @divisorList;
+                                # just for security:
+                                if ( !defined($divisor) || $divisor == 0 ) { $divisor = 1; }
+				($tickCount, $pMin, $pMax) = $self->_countTicks($min, $max, 1/$divisor);
+				print "\nChart::Base : Caution: Tick limit of $maxTicks exceeded. Backing of to an interval of ".1/$divisor." which plots $tickCount ticks\n";
+				return(1/$divisor, $tickCount, $pMin, $pMax);
+			}
+			elsif( $minTicks > $tickCount )
+			{
+				# If it is to low, try again.
+				next TRY;
+			}
+			else
+			{
+				# Store the divisor for possible later backtracking.
+				push @divisorList, $divisor;
+
+				# if the min or max is fixed, check they will fit in the interval.
+				next TRY if( $minF && ( int ($min*$divisor) != ($min*$divisor) ) );
+				next TRY if( $maxF && ( int ($max*$divisor) != ($max*$divisor) ) );
+
+				# If everything passes the tests, return.
+				return(1/$divisor, $tickCount, $pMin, $pMax)
+			}
+		}
+	}
+	die "can't happen!";
+}
+
+#this is where we draw the circles and the axes
+sub _draw_y_ticks {
+  my $self = shift;
+  my $data = $self->{'dataref'};
+  my $misccolor = $self->_color_role_to_index('misc');
+  my $textcolor = $self->_color_role_to_index('text');
+  my $background = $self->_color_role_to_index('background');
+  my @labels = @{$self->{'y_tick_labels'}};
+  my ($width, $height, $centerX, $centerY, $diameter);
+  my ($pi, $font, $fontW, $fontH, $labelX, $labelY, $label_offset);
+  my ($dia_delta, $dia, $x, $y, @label_degrees, $arc, $angle_interval);
+
+  # set up initial constant values
+  $pi = 3.14159265358979323846;
+  $font = $self->{'legend_font'};
+  $fontW = $self->{'legend_font'}->width;
+  $fontH = $self->{'legend_font'}->height;
+  $angle_interval = $self->{'angle_interval'};
+
+  if ($self->{'grey_background'} =~ /^true$/i) {
+      $background = $self->_color_role_to_index('grey_background');
+  }
+  # init the imagemap data field if they wanted it
+  if ($self->{'imagemap'} =~ /^true$/i) {
+    $self->{'imagemap_data'} = [];
+  }
+
+  # find width and height
+  $width = $self->{'curr_x_max'} - $self->{'curr_x_min'};
+  $height = $self->{'curr_y_max'} - $self->{'curr_y_min'};
+
+  # find center point, from which the pie will be drawn around
+  $centerX = int($width/2  + $self->{'curr_x_min'});
+  $centerY = int($height/2 + $self->{'curr_y_min'});
+
+  # always draw a circle, which means the diameter will be the smaller
+  # of the width and height. let enougth space for the label.
+  if ($width < $height) {
+   $diameter = $width -110;
+  }
+  else {
+    $diameter = $height -80 ;
+  }
+
+  #the difference between the diameter of two following circles;
+  $dia_delta = ceil($diameter / ($self->{'y_ticks'}-1));
+
+  #store the calculated data
+  $self->{'centerX'} = $centerX;
+  $self->{'centerY'} = $centerY;
+  $self->{'diameter'} = $diameter;
+
+  #draw the axes and its labels
+  # set up an array of labels for the axes
+  if ($angle_interval == 0) {
+     @label_degrees = ( );
+  }
+  elsif ($angle_interval <= 5 && $angle_interval > 0) {
+     @label_degrees = qw(180 175 170 165 160 155 150 145 140 135 130 125 120 115
+     110 105 100 95 90 85 80 75 70 65 60 55 50 45 40 35 30 25 20 15 10 5 0 355 350
+     345 340 335 330 325 320 315 310 305 300 295 290 285 280 275 270 265 260 255
+     250 245 240 235 230 225 220 215 210 205 200 195 190 185);
+     $angle_interval = 5;
+  }
+  elsif ($angle_interval <= 10 && $angle_interval > 5) {
+     @label_degrees = qw(180 170 160 150 140 130 120 110 100 90 80 70 60 50 40
+     30 20 10 0 350 340 330 320 310 300 290 280 270 260 250 240 230 220 210 200 190);
+     $angle_interval = 10;
+  }
+  elsif ($angle_interval <= 15 && $angle_interval > 10) {
+     @label_degrees = qw(180 165 150 135 120 105 90 75 60 45 30 15 0 345 330 315 300
+     285 270 255 240 225 210 195);
+     $angle_interval = 15;
+  }
+  elsif ($angle_interval <=20 && $angle_interval > 15) {
+     @label_degrees = qw(180 160 140 120 100 80 60 40 20 0 340 320 300 280 260 240
+     220 200);
+     $angle_interval = 20;
+  }
+  elsif ($angle_interval <= 30 && $angle_interval > 20) {
+     @label_degrees = qw(180 150 120 90 60 30 0 330 300 270 240 210);
+     $angle_interval = 30;
+  }
+  elsif ($angle_interval <= 45 && $angle_interval > 30) {
+     @label_degrees = qw(180 135 90 45 0 315 270 225);
+     $angle_interval = 45;
+  }
+  elsif ($angle_interval <= 90 && $angle_interval > 45) {
+     @label_degrees = qw(180 90 0 270);
+     $angle_interval = 90;
+  }
+  else {
+     carp "The angle_interval must be between 0 and 90!\nCorrected value: 30";
+     @label_degrees = qw(180 150 120 90 60 30 0 330 300 270 240 210);
+     $angle_interval = 30;
+  }
+  $arc = 0;
+  foreach (@label_degrees)    {
+      #calculated the coordinates of the end point of the line
+      $x = sin ($arc)*($diameter/2+10) + $centerX;
+      $y = cos  ($arc)*($diameter/2+10) + $centerY;
+      #some ugly correcture
+      if ($_ == '270') { $y++;}
+      #draw the line
+      $self->{'gd_obj'}->line($centerX, $centerY, $x, $y, $misccolor);
+      #calculate the string point
+      $x = sin ($arc)*($diameter/2+30) + $centerX-8;
+      $y = cos  ($arc)*($diameter/2+28) + $centerY-6;
+      #draw the labels
+      $self->{'gd_obj'}->string($font, $x, $y, $_.'°', $textcolor);
+      $arc += (($angle_interval)/360) *2*$pi;
+  }
+      
+  #draw the circles
+  $dia = 0;
+  foreach (@labels) {
+      $self->{'gd_obj'}->arc($centerX,$centerY,
+                    $dia, $dia,
+                    0, 360,
+                    $misccolor);
+      $dia += $dia_delta;
+  }
+  
+  $self->{'gd_obj'}->filledRectangle($centerX-length($labels[0])/2*$fontW-2,
+                                     $centerY+2,
+                                     $centerX+2+$diameter/2,
+                                     $centerY+$fontH+2,
+                                     $background);
+  #draw the labels of the circles
+  $dia = 0;
+  foreach (@labels) {
+       $self->{'gd_obj'}->string($font, $centerX+$dia/2-length($_)/2*$fontW,
+                                 $centerY+2, $_, $textcolor);
+       $dia += $dia_delta;
+  }
+       
+  
+
+  return;
+}
+
+#We don't need x ticks, it's all done in _draw_y_ticks
+sub _draw_x_ticks {
+  my $self = shift;
+
+  return;
+}
+
+
+## finally get around to plotting the data
+sub _draw_data {
+  my $self = shift;
+  my $data = $self->{'dataref'};
+  my $misccolor = $self->_color_role_to_index('misc');
+  my $textcolor = $self->_color_role_to_index('text');
+  my $background = $self->_color_role_to_index('background');
+  my ($width, $height, $centerX, $centerY, $diameter);
+  my ($mod, $map, $i, $j, $brush, $color, $x, $y, $winkel, $first_x, $first_y );
+  my ($arrow_x, $arrow_y, $m);
+  $color = 1;
+
+  my $pi = 3.14159265358979323846;
+  my $len = 10;
+  my $alpha = 1;
+  my $last_x = undef;
+  my $last_y = undef;
+  my $diff;
+  my $n=0;
+  
+  
+  
+  
+  
+  if ($self->{'pairs'} =~ /^true$/i) {
+     my $a = $self->{'num_datasets'}/2;
+     my $b = ceil($a);
+     my $c = $b-$a;
+    
+     if ($c == 0) {
+     croak "Wrong number of datasets for 'pairs'";
+     }
+    }
+  
+ 
+  # init the imagemap data field if they wanted it
+  if ($self->{'imagemap'} =~ /^true$/i) {
+    $self->{'imagemap_data'} = [];
+  }
+
+  # find width and height
+  $width = $self->{'curr_x_max'} - $self->{'curr_x_min'};
+  $height = $self->{'curr_y_max'} - $self->{'curr_y_min'};
+  
+  # get the base values
+  
+  if ($self->{'polar'} =~ /^false$/i) {
+    $mod = $self->{'min_val'};
+  }
+  else {
+     $mod = $self->{'max_val'};
+  }        
+  $centerX = $self->{'centerX'};
+  $centerY = $self->{'centerY'};
+  $diameter = $self->{'diameter'};
+  $diff = $self->{'max_val'} - $self->{'min_val'};
+  $diff = 1 if $diff < 1;
+  $map = $diameter/2/$diff;
+  
+  
+  $brush = $self->_prepare_brush ($color, 'point');
+  $self->{'gd_obj'}->setBrush ($brush);
+
+ 
+  # draw every line for this dataset
+  
+  if ($self->{'pairs'} =~ /^false$/i) { 
+  
+    for  $j (1..$self->{'num_datasets'}) {
+       $color = $self->_color_role_to_index('dataset'.($j-1));
+     
+      for $i (0..$self->{'num_datapoints'}-1) {
+           
+      # don't try to draw anything if there's no data
+      if (defined ($data->[$j][$i]) && $data->[$j][$i] <= $self->{'max_val'}
+          &&  $data->[$j][$i] >= $self->{'min_val'}) {
+	  
+        #calculate the point
+	$winkel = (180 - ($data->[0][$i] % 360)) /360 * 2* $pi;
+
+        if ($self->{'polar'} =~ /^false$/i) 
+        {
+            $x = ceil($centerX + sin ($winkel) * ($data->[$j][$i] - $mod) * $map);
+            $y = ceil($centerY + cos ($winkel) * ($data->[$j][$i] - $mod) * $map);
+      	}
+	else 
+        {
+	    $x = ceil($centerX + sin ($winkel) * ($mod - $data->[$j][$i]) * $map);
+            $y = ceil($centerY + cos ($winkel) * ($mod - $data->[$j][$i]) * $map);
+	}
+
+	# set the x and y values back
+	if ($i ==0) 
+        {
+	    $first_x = $x;
+	    $first_y = $y;
+	    $last_x = $x;
+            $last_y = $y;
+	}
+	    
+	
+        if ($self->{'point'} =~ /^true$/i) 
+        {
+          $brush = $self->_prepare_brush ($color, 'point');
+          $self->{'gd_obj'}->setBrush ($brush);
+          #draw the point
+          $self->{'gd_obj'}->line($x+1, $y, $x, $y, gdBrushed);
+        }
+        if ($self->{'line'} =~ /^true$/i) 
+        {
+          $brush = $self->_prepare_brush ($color, 'line');
+          $self->{'gd_obj'}->setBrush ($brush);
+          #draw the line
+          if (defined $last_x) 
+          {
+	     $self->{'gd_obj'}->line($x, $y, $last_x, $last_y, gdBrushed);
+          }
+        }
+	
+	
+        if ($self->{'arrow'} =~ /^true$/i) {
+          $brush = $self->_prepare_brush ($color, 'line');
+          $self->{'gd_obj'}->setBrush ($brush);
+          #draw the arrow
+          if ($data->[$j][$i] > $self->{'min_val'}) {
+            $self->{'gd_obj'}->line($x, $y, $centerX, $centerY, gdBrushed);
+
+            $arrow_x =  $x - cos($winkel-$alpha )*$len;
+            $arrow_y = $y + sin($winkel-$alpha)*$len;
+            $self->{'gd_obj'}->line($x, $y, $arrow_x, $arrow_y, gdBrushed);
+
+            $arrow_x = $x + sin($pi/2-$winkel-$alpha )*$len;
+            $arrow_y = $y - cos($pi/2-$winkel-$alpha)*$len;
+            $self->{'gd_obj'}->line($x, $y, $arrow_x, $arrow_y, gdBrushed);
+
+            
+          }
+        }
+
+        $last_x = $x;
+        $last_y = $y;
+        
+        
+	# store the imagemap data if they asked for it
+	if ($self->{'imagemap'} =~ /^true$/i) {
+	  $self->{'imagemap_data'}->[$j][$i] = [$x, $y ];
+ 	}
+      } else {
+	if ($self->{'imagemap'} =~ /^true$/i) {
+	  $self->{'imagemap_data'}->[$j][$i] = [ undef(), undef() ];
+
+        }
+      }
+    }
+    
+    # draw the last line to the first point    
+    if ($self->{'line'} =~ /^true$/i) {
+      $self->{'gd_obj'}->line($x, $y, $first_x, $first_y, gdBrushed);
+      }
+      
+    }
+  }
+  
+ 
+  if ($self->{'pairs'} =~ /^true$/i) { 
+     
+     for  ($j = 1; $j <= $self->{'num_datasets'}; $j+=2) {
+       if ($j ==1) {
+         $color = $self->_color_role_to_index('dataset'.($j-1));
+	 }
+       else {
+         $color = $self->_color_role_to_index('dataset'.($j/2-0.5));
+        }
+	
+#####	$color = $self->_color_role_to_index('dataset'.(1));  #####################
+	
+       for $i (0..$self->{'num_datapoints'}-1) {
+          
+      # don't try to draw anything if there's no data
+      if (defined ($data->[$j][$i]) && $data->[$j][$i] <= $self->{'max_val'}
+          &&  $data->[$j][$i] >= $self->{'min_val'}) {
+	  
+        # calculate the point
+	$winkel = (180 - ($data->[$n][$i] % 360)) /360 * 2* $pi;
+
+        if ($self->{'polar'} =~ /^false$/i) {
+              $x = ceil($centerX + sin ($winkel) * ($data->[$j][$i] - $mod) * $map);
+              $y = ceil($centerY + cos ($winkel) * ($data->[$j][$i] - $mod) * $map);
+	}
+	else {
+	      $x = ceil($centerX + sin ($winkel) * ($mod - $data->[$j][$i]) * $map);
+              $y = ceil($centerY + cos ($winkel) * ($mod - $data->[$j][$i]) * $map);     
+	}
+
+	# set the x and y values back
+	if ($i ==0) {
+	    $first_x = $x;
+	    $first_y = $y;
+	    $last_x = $x;
+            $last_y = $y;
+	    }
+	    
+	
+        if ($self->{'point'} =~ /^true$/i) {
+          $brush = $self->_prepare_brush ($color, 'point');
+          $self->{'gd_obj'}->setBrush ($brush);
+          #draw the point
+          $self->{'gd_obj'}->line($x+1, $y, $x, $y, gdBrushed);
+        }
+        if ($self->{'line'} =~ /^true$/i) {
+          $brush = $self->_prepare_brush ($color, 'line');
+          $self->{'gd_obj'}->setBrush ($brush);
+          #draw the line
+          if (defined $last_x) {
+	     $self->{'gd_obj'}->line($x, $y, $last_x, $last_y, gdBrushed);
+          }
+          else {}
+	  
+         }
+	
+	
+        if ($self->{'arrow'} =~ /^true$/i) {
+          $brush = $self->_prepare_brush ($color, 'line');
+          $self->{'gd_obj'}->setBrush ($brush);
+          #draw the arrow
+          if ($data->[$j][$i] > $self->{'min_val'}) {
+            $self->{'gd_obj'}->line($x, $y, $centerX, $centerY, gdBrushed);
+
+            $arrow_x =  $x - cos($winkel-$alpha )*$len;
+            $arrow_y = $y + sin($winkel-$alpha)*$len;
+            $self->{'gd_obj'}->line($x, $y, $arrow_x, $arrow_y, gdBrushed);
+
+            $arrow_x = $x + sin($pi/2-$winkel-$alpha )*$len;
+            $arrow_y = $y - cos($pi/2-$winkel-$alpha)*$len;
+            $self->{'gd_obj'}->line($x, $y, $arrow_x, $arrow_y, gdBrushed);
+
+            
+          }
+        }
+
+        $last_x = $x;
+        $last_y = $y;
+        
+        
+	# store the imagemap data if they asked for it
+	if ($self->{'imagemap'} =~ /^true$/i) {
+	  $self->{'imagemap_data'}->[$j][$i] = [$x, $y ];
+ 	}
+      } else {
+	if ($self->{'imagemap'} =~ /^true$/i) {
+	  $self->{'imagemap_data'}->[$j][$i] = [ undef(), undef() ];
+
+        }
+      }
+    }
+    
+    # draw the last line to the first point    
+    if ($self->{'line'} =~ /^true$/i) {
+      $self->{'gd_obj'}->line($x, $y, $first_x, $first_y, gdBrushed);
+      }
+      $n+=2;
+     }
+     
+   }
+ 
+ # now outline it  
+   $self->{'gd_obj'}->rectangle ($self->{'curr_x_min'} ,
+                                 $self->{'curr_y_min'},
+                                 $self->{'curr_x_max'},
+                                 $self->{'curr_y_max'},
+                                 $misccolor);
+
+  return;
+
+}
+
+
+##  set the gdBrush object to trick GD into drawing fat lines
+sub _prepare_brush {
+  my $self = shift;
+  my $color = shift;
+  my $type = shift;
+  my ($radius, @rgb, $brush, $white, $newcolor);
+   
+  @rgb = $self->{'gd_obj'}->rgb($color);
+
+  # get the appropriate brush size
+  if ($type eq 'line') {
+    $radius = $self->{'brush_size'}/2;
+  }
+  elsif ($type eq 'point') {
+    $radius = $self->{'pt_size'}/2;
+  }
+
+  # create the new image
+  $brush = GD::Image->new ($radius*2, $radius*2);
+
+  # get the colors, make the background transparent
+  $white = $brush->colorAllocate (255,255,255);
+  $newcolor = $brush->colorAllocate (@rgb);
+  $brush->transparent ($white);
+
+  # draw the circle
+  $brush->arc ($radius-1, $radius-1, $radius, $radius, 0, 360, $newcolor);
+
+  # fill it if we're using lines
+  $brush->fill ($radius-1, $radius-1, $newcolor);
+  
+  #}
+
+  # set the new image as the main object's brush
+  return $brush;
+}
+
+
+
+sub _draw_legend {
+  my $self = shift;
+  my ($length);
+
+  # check to see if legend type is none..
+  if ($self->{'legend'} =~ /^none$/) {
+    return 1;
+  }
+  # check to see if they have as many labels as datasets,
+  # warn them if not
+  if (($#{$self->{'legend_labels'}} >= 0) && 
+       ((scalar(@{$self->{'legend_labels'}})) != $self->{'num_datasets'})) {
+    carp "The number of legend labels and datasets doesn\'t match";
+  }
+
+  # init a field to store the length of the longest legend label
+  unless ($self->{'max_legend_label'}) {
+    $self->{'max_legend_label'} = 0;
+  }
+
+  # fill in the legend labels, find the longest one
+  
+  if ($self->{'pairs'} =~ /^false$/i) {
+  for (1..$self->{'num_datasets'}) {
+    unless ($self->{'legend_labels'}[$_-1]) {
+      $self->{'legend_labels'}[$_-1] = "Dataset $_";
+    }
+    $length = length($self->{'legend_labels'}[$_-1]);
+    if ($length > $self->{'max_legend_label'}) {
+      $self->{'max_legend_label'} = $length;
+    }
+  }
+  }
+  
+  if ($self->{'pairs'} =~ /^true$/i) {
+  
+   for (1..ceil($self->{'num_datasets'}/2)) {
+    unless ($self->{'legend_labels'}[$_-1]) {
+      $self->{'legend_labels'}[$_-1] = "Dataset $_";
+    }
+    $length = length($self->{'legend_labels'}[$_-1]);
+    if ($length > $self->{'max_legend_label'}) {
+      $self->{'max_legend_label'} = $length;
+    }
+  }
+ }
+      
+  # different legend types
+  if ($self->{'legend'} eq 'bottom') {
+    $self->_draw_bottom_legend;
+  }
+  elsif ($self->{'legend'} eq 'right') {
+    $self->_draw_right_legend;
+  }
+  elsif ($self->{'legend'} eq 'left') {
+    $self->_draw_left_legend;
+  }
+  elsif ($self->{'legend'} eq 'top') {
+    $self->_draw_top_legend;
+  } else {
+    carp "I can't put a legend there (at ".$self->{'legend'}.")\n";
+  }
+
+  # and return
+  return 1;
+}
+
+## put the legend on the bottom of the chart
+sub _draw_bottom_legend {
+  my $self = shift;
+  my @labels = @{$self->{'legend_labels'}};
+  my ($x1, $y1, $x2, $x3, $y2, $empty_width, $max_label_width, $cols, $rows, $color, $brush);
+  my ($col_width, $row_height, $r, $c, $index, $x, $y, $w, $h, $axes_space);
+  my $font = $self->{'legend_font'};
+
+
+  # make sure we're using a real font
+  unless ((ref ($font)) eq 'GD::Font') {
+    croak "The subtitle font you specified isn\'t a GD Font object";
+  }
+
+  # get the size of the font
+  ($h, $w) = ($font->height, $font->width);
+
+  # find the base x values
+  $axes_space = ($self->{'y_tick_label_length'} * $self->{'tick_label_font'}->width)
+	        + $self->{'tick_len'} + (3 * $self->{'text_space'});
+  $x1 = $self->{'curr_x_min'} + $self->{'graph_border'};
+  $x2 = $self->{'curr_x_max'} - $self->{'graph_border'};
+
+  if ($self->{'y_axes'} =~ /^right$/i) {
+     $x2 -= $axes_space;
+  }
+  elsif ($self->{'y_axes'} =~ /^both$/i) {
+     $x2 -= $axes_space;
+   #  $x1 += $axes_space;
+  }
+  else {
+   #  $x1 += $axes_space;
+     
+  }
+
+
+  if ($self->{'y_label'}) {
+    $x1 += $self->{'label_font'}->height + 2 * $self->{'text_space'};
+  }
+  if ($self->{'y_label2'}) {
+    $x2 -= $self->{'label_font'}->height + 2 * $self->{'text_space'};
+  }
+
+  # figure out how wide the columns need to be, and how many we
+  # can fit in the space available
+  $empty_width = ($x2 - $x1) - (2 * $self->{'legend_space'});
+  $max_label_width = $self->{'max_legend_label'} * $w
+    + (4 * $self->{'text_space'}) + $self->{'legend_example_size'};
+  $cols = int ($empty_width / $max_label_width);
+  unless ($cols) {
+    $cols = 1;
+  }
+  $col_width = $empty_width / $cols;
+
+  # figure out how many rows we need, remember how tall they are
+  $rows = int ($self->{'num_datasets'} / $cols);
+  unless (($self->{'num_datasets'} % $cols) == 0) {
+    $rows++;
+  }
+  unless ($rows) {
+    $rows = 1;
+  }
+  $row_height = $h + $self->{'text_space'};
+
+  # box the legend off
+  $y1 = $self->{'curr_y_max'} - $self->{'text_space'}
+          - ($rows * $row_height) - (2 * $self->{'legend_space'});
+  $y2 = $self->{'curr_y_max'};
+ 
+  
+  $self->{'gd_obj'}->rectangle($x1, $y1, $x2, $y2, 
+                               $self->_color_role_to_index('misc'));
+ 
+  $x1 += $self->{'legend_space'} + $self->{'text_space'};
+  $x2 -= $self->{'legend_space'};
+  $y1 += $self->{'legend_space'} + $self->{'text_space'};
+  $y2 -= $self->{'legend_space'} + $self->{'text_space'};
+
+  # draw in the actual legend
+  for $r (0..$rows-1) {
+    for $c (0..$cols-1) {
+      $index = ($r * $cols) + $c;  # find the index in the label array
+      if ($labels[$index]) {
+	# get the color
+        $color = $self->_color_role_to_index('dataset'.$index); 
+
+        # get the x-y coordinate for the start of the example line
+	$x = $x1 + ($col_width * $c);
+        $y = $y1 + ($row_height * $r) + $h/2;
+	
+	# now draw the example line
+        $self->{'gd_obj'}->line($x, $y, 
+                                $x + $self->{'legend_example_size'}, $y,
+                                $color);
+
+        # reset the brush for points
+        $brush = $self->_prepare_brush($color, 'point',
+				$self->{'pointStyle' . $index});
+        $self->{'gd_obj'}->setBrush($brush);
+        # draw the point
+        $x3 = int($x + $self->{'legend_example_size'}/2);
+        $self->{'gd_obj'}->line($x3, $y, $x3, $y, gdBrushed);
+
+        # adjust the x-y coordinates for the start of the label
+	$x += $self->{'legend_example_size'} + (2 * $self->{'text_space'});
+        $y = $y1 + ($row_height * $r);
+
+	# now draw the label
+	$self->{'gd_obj'}->string($font, $x, $y, $labels[$index], $color);
+      }
+    }
+  }
+
+  # mark off the space used
+  $self->{'curr_y_max'} -= ($rows * $row_height) + $self->{'text_space'}
+			      + (2 * $self->{'legend_space'}); 
+
+  # now return
+  return 1;
+}
+
+## put the legend on top of the chart
+sub _draw_top_legend {
+  my $self = shift;
+  my @labels = @{$self->{'legend_labels'}};
+  my ($x1, $y1, $x2, $x3, $y2, $empty_width, $max_label_width, $cols, $rows, $color, $brush);
+  my ($col_width, $row_height, $r, $c, $index, $x, $y, $w, $h, $axes_space);
+  my $font = $self->{'legend_font'};
+
+  # make sure we're using a real font
+  unless ((ref ($font)) eq 'GD::Font') {
+    croak "The subtitle font you specified isn\'t a GD Font object";
+  }
+
+  # get the size of the font
+  ($h, $w) = ($font->height, $font->width);
+
+  # find the base x values
+  $axes_space = ($self->{'y_tick_label_length'} * $self->{'tick_label_font'}->width)
+	        + $self->{'tick_len'} + (3 * $self->{'text_space'});
+  $x1 = $self->{'curr_x_min'} + $self->{'graph_border'};
+  $x2 = $self->{'curr_x_max'} - $self->{'graph_border'};
+
+  if ($self->{'y_axes'} =~ /^right$/i) {
+     $x2 -= $axes_space;
+  }
+  elsif ($self->{'y_axes'} =~ /^both$/i) {
+     $x2 -= $axes_space;
+    # $x1 += $axes_space;
+  }
+  else {
+    # $x1 += $axes_space;
+  }
+
+  # figure out how wide the columns can be, and how many will fit
+  $empty_width = ($x2 - $x1) - (2 * $self->{'legend_space'});
+  $max_label_width = (4 * $self->{'text_space'})
+    + ($self->{'max_legend_label'} * $w)
+    + $self->{'legend_example_size'};
+  $cols = int ($empty_width / $max_label_width);
+  unless ($cols) {
+    $cols = 1;
+  }
+  $col_width = $empty_width / $cols;
+
+  # figure out how many rows we need and remember how tall they are
+  $rows = int ($self->{'num_datasets'} / $cols);
+  unless (($self->{'num_datasets'} % $cols) == 0) {
+    $rows++;
+  }
+  unless ($rows) {
+    $rows = 1;
+  }
+  $row_height = $h + $self->{'text_space'};
+
+  # box the legend off
+  $y1 = $self->{'curr_y_min'};
+  $y2 = $self->{'curr_y_min'} + $self->{'text_space'}
+          + ($rows * $row_height) + (2 * $self->{'legend_space'});
+  $self->{'gd_obj'}->rectangle($x1, $y1, $x2, $y2, 
+                               $self->_color_role_to_index('misc'));
+
+  # leave some space inside the legend
+  $x1 += $self->{'legend_space'} + $self->{'text_space'};
+  $x2 -= $self->{'legend_space'};
+  $y1 += $self->{'legend_space'} + $self->{'text_space'};
+  $y2 -= $self->{'legend_space'} + $self->{'text_space'};
+
+  # draw in the actual legend
+  for $r (0..$rows-1) {
+    for $c (0..$cols-1) {
+      $index = ($r * $cols) + $c;  # find the index in the label array
+      if ($labels[$index]) {
+	# get the color
+        $color = $self->_color_role_to_index('dataset'.$index); 
+        
+	# find the x-y coords
+	$x = $x1 + ($col_width * $c);
+        $y = $y1 + ($row_height * $r) + $h/2;
+
+	# draw the line first
+        $self->{'gd_obj'}->line($x, $y, 
+                                $x + $self->{'legend_example_size'}, $y,
+                                $color);
+
+        # reset the brush for points
+        $brush = $self->_prepare_brush($color, 'point',
+				$self->{'pointStyle' . $index});
+        $self->{'gd_obj'}->setBrush($brush);
+        # draw the point
+        $x3 = int($x + $self->{'legend_example_size'}/2);
+        $self->{'gd_obj'}->line($x3, $y, $x3, $y, gdBrushed);
+
+        # now the label
+	$x += $self->{'legend_example_size'} + (2 * $self->{'text_space'});
+	$y -= $h/2;
+	$self->{'gd_obj'}->string($font, $x, $y, $labels[$index], $color);
+      }
+    }
+  }
+      
+  # mark off the space used
+  $self->{'curr_y_min'} += ($rows * $row_height) + $self->{'text_space'}
+			      + 2 * $self->{'legend_space'}; 
+
+  # now return
+  return 1;
+}
+
+
+
+sub _draw_left_legend {
+  my $self = shift;
+  my @labels = @{$self->{'legend_labels'}};
+  my ($x1, $x2, $x3, $y1, $y2, $width, $color, $misccolor, $w, $h, $brush);
+  my $font = $self->{'legend_font'};
+ 
+  # make sure we're using a real font
+  unless ((ref ($font)) eq 'GD::Font') {
+    croak "The subtitle font you specified isn\'t a GD Font object";
+  }
+
+  # get the size of the font
+  ($h, $w) = ($font->height, $font->width);
+
+  # get the miscellaneous color
+  $misccolor = $self->_color_role_to_index('misc');
+
+  # find out how wide the largest label is
+  $width = (2 * $self->{'text_space'})
+    + ($self->{'max_legend_label'} * $w)
+    + $self->{'legend_example_size'}
+    + (2 * $self->{'legend_space'});
+
+  # get some base x-y coordinates
+  $x1 = $self->{'curr_x_min'};
+  $x2 = $self->{'curr_x_min'} + $width;
+  $y1 = $self->{'curr_y_min'} + $self->{'graph_border'} ;
+  
+  if ($self->{'pairs'} =~ /^true$/i) {
+  $y2 = $self->{'curr_y_min'} + $self->{'graph_border'} + $self->{'text_space'}
+          + (($self->{'num_datasets'}/2) * ($h + $self->{'text_space'}))
+	  + (4 * $self->{'legend_space'});
+     }
+  else {
+  $y2 = $self->{'curr_y_min'} + $self->{'graph_border'} + $self->{'text_space'}
+        + ($self->{'num_datasets'} * ($h + $self->{'text_space'}))
+	+ (2 * $self->{'legend_space'});
+	}
+	
+  # box the legend off
+  $self->{'gd_obj'}->rectangle ($x1, $y1, $x2, $y2, $misccolor);
+
+  # leave that nice space inside the legend box
+  $x1 += $self->{'legend_space'};
+  $y1 += $self->{'legend_space'} + $self->{'text_space'};
+
+  # now draw the actual legend
+  for (0..$#labels) {
+    # get the color
+    my $c = $self->{'num_datasets'}-$_-1;
+    $color = $self->_color_role_to_index('dataset'.$_);
+    
+    # find the x-y coords
+    $x2 = $x1;
+    $x3 = $x2 + $self->{'legend_example_size'};
+    $y2 = $y1 + ($_ * ($self->{'text_space'} + $h)) + $h/2;
+
+    # do the line first
+    $self->{'gd_obj'}->line ($x2, $y2, $x3, $y2, $color);
+
+    # reset the brush for points
+    $brush = $self->_prepare_brush($color, 'point',
+				$self->{'pointStyle' . $_});
+    $self->{'gd_obj'}->setBrush($brush);
+    # draw the point
+    $self->{'gd_obj'}->line(int(($x3+$x2)/2), $y2,
+				int(($x3+$x2)/2), $y2, gdBrushed);
+    
+    # now the label
+    $x2 = $x3 + (2 * $self->{'text_space'});
+    $y2 -= $h/2;
+    
+    # order of the datasets in the legend
+    $self->{'gd_obj'}->string ($font, $x2, $y2, $labels[$_], $color);
+   }
+
+  # mark off the used space
+  $self->{'curr_x_min'} += $width;
+
+  # and return
+  return 1;
+}
+
+
+
+sub _draw_right_legend {
+  my $self = shift;
+  my @labels = @{$self->{'legend_labels'}};
+  my ($x1, $x2, $x3, $y1, $y2, $width, $color, $misccolor, $w, $h, $brush);
+  my $font = $self->{'legend_font'};
+ 
+  # make sure we're using a real font
+  unless ((ref ($font)) eq 'GD::Font') {
+    croak "The subtitle font you specified isn\'t a GD Font object";
+  }
+
+  # get the size of the font
+  ($h, $w) = ($font->height, $font->width);
+
+  # get the miscellaneous color
+  $misccolor = $self->_color_role_to_index('misc');
+
+  # find out how wide the largest label is
+  $width = (2 * $self->{'text_space'})
+    + ($self->{'max_legend_label'} * $w)
+    + $self->{'legend_example_size'}
+    + (2 * $self->{'legend_space'});
+
+  # get some starting x-y values
+  $x1 = $self->{'curr_x_max'} - $width;
+  $x2 = $self->{'curr_x_max'};
+  $y1 = $self->{'curr_y_min'} + $self->{'graph_border'} ;
+  
+  if ($self->{'pairs'} =~ /^true$/i) {
+  $y2 = $self->{'curr_y_min'} + $self->{'graph_border'} + $self->{'text_space'}
+          + (($self->{'num_datasets'}/2) * ($h + $self->{'text_space'}))
+	  + (4 * $self->{'legend_space'});
+	  }
+  else {
+  $y2 = $self->{'curr_y_min'} + $self->{'graph_border'} + $self->{'text_space'}
+          + ($self->{'num_datasets'} * ($h + $self->{'text_space'}))
+	  + (2 * $self->{'legend_space'});
+	  }
+  # box the legend off
+  $self->{'gd_obj'}->rectangle ($x1, $y1, $x2, $y2, $misccolor);
+
+  # leave that nice space inside the legend box
+  $x1 += $self->{'legend_space'};
+  $y1 += $self->{'legend_space'} + $self->{'text_space'};
+
+  # now draw the actual legend
+  for (0..$#labels) {
+    # get the color
+    $color = $self->_color_role_to_index('dataset'.$_);
+   
+    # find the x-y coords
+    $x2 = $x1;
+    $x3 = $x2 + $self->{'legend_example_size'};
+    $y2 = $y1 + ($_ * ($self->{'text_space'} + $h)) + $h/2;
+
+    # do the line first
+    $self->{'gd_obj'}->line ($x2, $y2, $x3, $y2, $color);
+
+    # reset the brush for points
+    $brush = $self->_prepare_brush($color, 'point',
+				$self->{'pointStyle' . $_});
+    $self->{'gd_obj'}->setBrush($brush);
+    # draw the point
+    $self->{'gd_obj'}->line(int(($x3+$x2)/2), $y2,
+				int(($x3+$x2)/2), $y2, gdBrushed);
+
+    # now the label
+    $x2 = $x3 + (2 * $self->{'text_space'});
+    $y2 -= $h/2;
+    
+    $self->{'gd_obj'}->string ($font, $x2, $y2, $labels[$_], $color);
+   
+  }
+
+  # mark off the used space
+  $self->{'curr_x_max'} -= $width;
+
+  # and return
+  return 1;
+}
+
+
+sub _find_y_range {
+  my $self = shift;
+  my $data = $self->{'dataref'};
+  
+  my $max = undef;
+  my $min = undef;
+  my $k=1;
+  my $dataset = 1;
+  my $datum;
+  
+   
+  if ($self->{'pairs'} =~ /^false$/i) {
+  for  $dataset ( @$data[1..$#$data] ) {
+  # print "dataset @$dataset\n";
+    for  $datum ( @$dataset ) {
+      if ( defined $datum ) {
+#  Prettier, but probably slower:
+#         $max = $datum unless defined $max && $max >= $datum;
+#         $min = $datum unless defined $min && $min <= $datum;
+        if ( defined $max ) {
+          if ( $datum > $max ) { $max = $datum }
+          elsif ( $datum < $min ) { $min = $datum }
+        }
+        else { $min = $max = $datum }
+      }
+    }
+  }
+ }
+ 
+ if ($self->{'pairs'} =~ /^true$/i) {
+# only every second dataset must be checked
+ for  $dataset ( @$data[$k] ) {
+    for  $datum ( @$dataset ) {
+      if ( defined $datum ) {
+#  Prettier, but probably slower:
+#         $max = $datum unless defined $max && $max >= $datum;
+#         $min = $datum unless defined $min && $min <= $datum;
+          if ( defined $max ) {
+            if ( $datum > $max ) { $max = $datum }
+          elsif ( $datum < $min ) { $min = $datum }
+          }
+         else { $min = $max = $datum }
+       }
+    }
+    $k+=2;
+  }
+ }
+
+ ($min, $max);
+}
+
+# dont check the number of points in the added datasets in a polarplot
+
+sub set {
+  my $self = shift;
+  my %opts = @_;
+  
+  # basic error checking on the options, just warn 'em
+  unless ($#_ % 2) {
+    carp "Whoops, some option to be set didn't have a value.\n",
+         "You might want to look at that.\n";
+  }
+ 
+  
+  # set the options
+  for (keys %opts) {
+
+    $self->{$_} = $opts{$_};
+    
+    # if someone wants to change the grid_lines color, we should set all
+    # the colors of the grid_lines
+    if ($_ =~ /^colors$/ ) {
+      my %hash = %{$opts{$_}};
+      foreach my $key (sort keys %hash){
+          if ($key =~ /^grid_lines$/) {
+            $self->{'colors'}{'y_grid_lines'} = $hash{'grid_lines'};
+            $self->{'colors'}{'x_grid_lines'} = $hash{'grid_lines'};
+            $self->{'colors'}{'y2_grid_lines'} = $hash{'grid_lines'};
+         }
+      }
+    }
+  }
+
+  if (($self->{'polar'} =~/^false$/i) && (defined $self->{'croak'})) {
+    carp "New data set to be added has an incorrect number of points";
+  }
+    
+  # now return
+  return 1;
+}
+
+
+
+
+sub add_dataset {
+  my $self = shift;
+  my @data = @_;
+
+  # error check the data (carp, don't croak)
+  if ($self->{'dataref'} && ($#{$self->{'dataref'}->[0]} != $#data)) {
+  #  carp "New data set to be added has an incorrect number of points";
+     $self->{'croak'} = 'true';
+  }
+
+  # copy it into the dataref
+  push @{$self->{'dataref'}}, [ @data ];
+  
+  # now return
+  return 1;
+}
+
+
+
+## be a good module and return 1
+1;


Property changes on: packages/libchart-perl/branches/upstream/current/Chart/Direction.pm
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/Chart/ErrorBars.pm
===================================================================
--- packages/libchart-perl/branches/upstream/current/Chart/ErrorBars.pm	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/Chart/ErrorBars.pm	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,392 @@
+#====================================================================
+#  Chart::ErrorBars
+#
+#  written by Chart-Group
+#
+#  maintained by the Chart Group
+#  Chart at wettzell.ifag.de
+#
+#---------------------------------------------------------------------
+# History:
+#----------
+# $RCSfile: ErrorBars.pm,v $ $Revision: 1.2 $ $Date: 2003/02/14 13:32:48 $
+# $Author: dassing $
+# $Log: ErrorBars.pm,v $
+# Revision 1.2  2003/02/14 13:32:48  dassing
+# First setup
+#
+#====================================================================
+
+package Chart::ErrorBars;
+
+use Chart::Base '2.4.1';
+use GD;
+use Carp;
+use strict;
+
+ at Chart::ErrorBars::ISA = qw(Chart::Base);
+$Chart::ErrorBars::VERSION = '2.4.1';
+
+#>>>>>>>>>>>>>>>>>>>>>>>>>>#
+#  public methods go here  #
+#<<<<<<<<<<<<<<<<<<<<<<<<<<#
+
+
+
+#>>>>>>>>>>>>>>>>>>>>>>>>>>>#
+#  private methods go here  #
+#<<<<<<<<<<<<<<<<<<<<<<<<<<<#
+
+## finally get around to plotting the data
+sub _draw_data {
+  my $self = shift;
+  my $data = $self->{'dataref'};
+  my $misccolor = $self->_color_role_to_index('misc');
+  my ($x1, $x2, $x3, $y1, $y2, $y3, $mod, $y_error_up, $y_error_down);
+  my ($width, $height, $delta, $map, $delta_num, $zero_offset, $flag);
+  my ($i, $j, $color, $brush);
+  my $dataset =0;
+  my $diff;
+  
+  # init the imagemap data field if they want it
+  if ($self->{'imagemap'} =~ /^true$/i) {
+    $self->{'imagemap_data'} = [];
+  }
+
+  # find the delta value between data points, as well
+  # as the mapping constant
+  $width = $self->{'curr_x_max'} - $self->{'curr_x_min'};
+  $height = $self->{'curr_y_max'} - $self->{'curr_y_min'};
+  $delta = $width / ( $self->{'num_datapoints'} > 0 ? $self->{'num_datapoints'} : 1);
+  $diff = $self->{'max_val'} - $self->{'min_val'};
+  $diff = 1 if $diff == 0;
+  $map = $height / $diff;
+
+  #for a xy-plot, use this delta and maybe an offset for the zero-axes
+  if ($self->{'xy_plot'} =~ /^true$/i ) {
+    $diff = $self->{'x_max_val'} - $self->{'x_min_val'};
+    $diff = 1 if $diff == 0;
+    $delta_num = $width / $diff;
+
+    if ($self->{'x_min_val'} <= 0 && $self->{'x_max_val'} >= 0) {
+       $zero_offset = abs($self->{'x_min_val'}) * abs($delta_num);
+    }
+    elsif ($self->{'x_min_val'} > 0 || $self->{'x_max_val'} < 0) {
+       $zero_offset =  -$self->{'x_min_val'} * $delta_num;
+    }
+    else {
+       $zero_offset = 0;
+    }
+  }
+  
+  # get the base x-y values
+  if ($self->{'xy_plot'} =~ /^false$/i ) {
+    $x1 = $self->{'curr_x_min'} + ($delta / 2);
+  }
+  else {
+    $x1 = $self->{'curr_x_min'};
+  }
+  if ($self->{'min_val'} >= 0) {
+    $y1 = $self->{'curr_y_max'};
+    $mod = $self->{'min_val'};
+  }
+  elsif ($self->{'max_val'} <= 0) {
+    $y1 = $self->{'curr_y_min'};
+    $mod = $self->{'max_val'};
+  }
+  else {
+    $y1 = $self->{'curr_y_min'} + ($map * $self->{'max_val'});
+    $mod = 0;
+    $self->{'gd_obj'}->line ($self->{'curr_x_min'}, $y1,
+                             $self->{'curr_x_max'}, $y1,
+                             $misccolor);
+  }
+
+  # first of all box it off
+  $self->{'gd_obj'}->rectangle ($self->{'curr_x_min'},
+  				$self->{'curr_y_min'},
+				$self->{'curr_x_max'},
+				$self->{'curr_y_max'},
+				$misccolor);
+  
+  # draw the points
+  for $i (1..$self->{'num_datasets'}) {
+    if ($self->{'same_error'} =~ /^false$/i) {
+     # get the color for this dataset, and set the brush
+     $color = $self->_color_role_to_index('dataset'.($dataset));     # draw every point for this dataset
+     $dataset++ if (($i-1)%3 == 0);
+     for $j (0..$self->{'num_datapoints'}) {
+      #get the brush for points
+      $brush = $self->_prepare_brush ($color, 'point');
+      $self->{'gd_obj'}->setBrush ($brush);
+      
+      # only draw if the current set is really a dataset and no errorset
+      if ( ($i-1)%3 == 0) {
+       # don't try to draw anything if there's no data
+       if (defined ($data->[$i][$j])  ) {
+          if ($self->{'xy_plot'} =~ /^true$/i ) {
+           $x2 = $x1 + $delta_num * $data->[0][$j] + $zero_offset+1;
+           $x3 = $x2 ;
+          }
+          else {
+           $x2 = $x1 + ($delta * $j)+1;
+           $x3 = $x2;
+          }
+	  $y2 = $y1 - (($data->[$i][$j] - $mod) * $map);
+	  $y3 = $y2;
+          $y_error_up = $y2-abs($data->[$i+1][$j]) *$map;
+          $y_error_down= $y2+abs($data->[$i+2][$j]) *$map;
+
+	# draw the point only if it is within the chart borders
+          if ($data->[$i][$j] <= $self->{'max_val'} && $data->[$i][$j] >= $self->{'min_val'}) {
+            $self->{'gd_obj'}->line($x2, $y2, $x3, $y3, gdBrushed);
+            $flag = 'true';
+          }
+
+          #reset the brush for lines
+          $brush = $self->_prepare_brush ($color, 'line');
+          $self->{'gd_obj'}->setBrush ($brush);
+        
+          #draw the error bars
+          if ($flag =~ /^true$/i) {
+
+            # the upper lines
+            $self->{'gd_obj'}->line($x2, $y2, $x3, $y_error_up, gdBrushed);
+            $self->{'gd_obj'}->line($x2-3, $y_error_up, $x3+3, $y_error_up, gdBrushed);
+
+            # the down lines
+            $self->{'gd_obj'}->line($x2, $y2, $x3, $y_error_down, gdBrushed);
+            $self->{'gd_obj'}->line($x2-3, $y_error_down, $x3+3, $y_error_down, gdBrushed);
+            $flag = 'false';
+          }
+	  # store the imagemap data if they asked for it
+	  if ($self->{'imagemap'} =~ /^true$/i) {
+	    $self->{'imagemap_data'}->[$i][$j] = [ $x2, $y2 ];
+	  }
+        }
+      }
+     }
+    }
+    else {
+     # get the color for this dataset, and set the brush
+     $color = $self->_color_role_to_index('dataset'.($dataset));     # draw every point for this dataset
+     $dataset++ if (($i-1)%2 == 0);
+     for $j (0..$self->{'num_datapoints'}) {
+      #get the brush for points
+      $brush = $self->_prepare_brush ($color, 'point');
+      $self->{'gd_obj'}->setBrush ($brush);
+
+      # only draw if the current set is really a dataset and no errorset
+      if ( ($i-1)%2 == 0) {
+       # don't try to draw anything if there's no data
+       if (defined ($data->[$i][$j])  ) {
+          if ($self->{'xy_plot'} =~ /^true$/i ) {
+           $x2 = $x1 + $delta_num * $data->[0][$j] + $zero_offset;
+           $x3 = $x2 ;
+          }
+          else {
+           $x2 = $x1 + ($delta * $j);
+           $x3 = $x2;
+          }
+	  $y2 = $y1 - (($data->[$i][$j] - $mod) * $map);
+	  $y3 = $y2;
+          $y_error_up = $y2-abs($data->[$i+1][$j]) *$map;
+          $y_error_down= $y2+abs($data->[$i+1][$j]) *$map;
+
+	  # draw the point only if it is within the chart borders
+          if ($data->[$i][$j] <= $self->{'max_val'} && $data->[$i][$j] >= $self->{'min_val'}) {
+            $self->{'gd_obj'}->line($x2, $y2, $x3, $y3, gdBrushed);
+            $flag = 'true';
+          }
+
+          #reset the brush for lines
+          $brush = $self->_prepare_brush ($color, 'line');
+          $self->{'gd_obj'}->setBrush ($brush);
+
+          #draw the error bars
+          if ($flag =~ /^true$/i) {
+
+            # the upper lines
+            $self->{'gd_obj'}->line($x2, $y2, $x3, $y_error_up, gdBrushed);
+            $self->{'gd_obj'}->line($x2-3, $y_error_up, $x3+3, $y_error_up, gdBrushed);
+
+            # the down lines
+            $self->{'gd_obj'}->line($x2, $y2, $x3, $y_error_down, gdBrushed);
+            $self->{'gd_obj'}->line($x2-3, $y_error_down, $x3+3, $y_error_down, gdBrushed);
+            $flag = 'false';
+          }
+	  # store the imagemap data if they asked for it
+	  if ($self->{'imagemap'} =~ /^true$/i) {
+	    $self->{'imagemap_data'}->[$i][$j] = [ $x2, $y2 ];
+	  }
+       }
+      }
+     }
+    }
+  }
+
+  return 1;
+}
+
+
+##  set the gdBrush object to trick GD into drawing fat lines
+sub _prepare_brush {
+  my $self = shift;
+  my $color = shift;
+  my $type = shift;
+  my ($radius, @rgb, $brush, $white, $newcolor);
+
+  # get the rgb values for the desired color
+  @rgb = $self->{'gd_obj'}->rgb($color);
+
+  # get the appropriate brush size
+  if ($type eq 'line') {
+    $radius = $self->{'brush_size'}/2;
+  }
+  elsif ($type eq 'point') {
+    $radius = $self->{'pt_size'}/2;
+  }
+
+  # create the new image
+  $brush = GD::Image->new ($radius*2, $radius*2);
+
+  # get the colors, make the background transparent
+  $white = $brush->colorAllocate (255,255,255);
+  $newcolor = $brush->colorAllocate (@rgb);
+  $brush->transparent ($white);
+
+  # draw the circle
+  $brush->arc ($radius-1, $radius-1, $radius, $radius, 0, 360, $newcolor);
+
+  # fill it if we're using lines
+  $brush->fill ($radius-1, $radius-1, $newcolor);
+
+  # set the new image as the main object's brush
+  return $brush;
+}
+
+
+##  let them know what all the pretty colors mean
+sub _draw_legend {
+  my $self = shift;
+  my ($length, $step, $temp, $post_length);
+  my $j = 0;
+
+  # check to see if legend type is none..
+  if ($self->{'legend'} =~ /^none$/) {
+    return 1;
+  }
+  
+  #just for later checking and warning
+  if ($#{$self->{'legend_labels'}} >= 0) {
+    $post_length = scalar(@{$self->{'legend_labels'}});
+  }
+
+  #look if every second or eyery third dataset is a set for data
+  if ( $self->{'same_error'}  =~ /^false$/i) {
+     $step = 3;
+  }
+  else {
+     $step = 2;
+  }
+
+  # init a field to store the length of the longest legend label
+  unless ($self->{'max_legend_label'}) {
+    $self->{'max_legend_label'} = 0;
+  }
+  # fill in the legend labels, find the longest one
+  for (my $i = 1; $i < $self->{'num_datasets'}; $i += $step) {
+     my $label = $j+1;
+    unless ($self->{'legend_labels'}[$j]) {
+      $self->{'legend_labels'}[$j] = "Dataset $label";
+    }
+    $length = length($self->{'legend_labels'}[$j]);
+    if ($length > $self->{'max_legend_label'}) {
+      $self->{'max_legend_label'} = $length;
+    }
+    $j++;
+  }
+  
+  #we just have to label the datasets in the legend
+  #we'll reset it, to draw the sets
+  $temp = $self->{'num_datasets'};
+  $self->{'num_datasets'} = $j;
+
+  # check to see if they have as many labels as datasets,
+  # warn them if not
+  if ( ($post_length > 0) && ($post_length != $j) ) {
+    carp "The number of legend labels and datasets doesn\'t match";
+  }
+  
+  # different legend types
+  if ($self->{'legend'} eq 'bottom') {
+    $self->_draw_bottom_legend;
+  }
+  elsif ($self->{'legend'} eq 'right') {
+    $self->_draw_right_legend;
+  }
+  elsif ($self->{'legend'} eq 'left') {
+    $self->_draw_left_legend;
+  }
+  elsif ($self->{'legend'} eq 'top') {
+    $self->_draw_top_legend;
+  } else {
+    carp "I can't put a legend there (at ".$self->{'legend'}.")\n";
+  }
+
+  #reset the number of dataset to make sure that everything goes right
+  $self->{'num_datasets'} = $temp;
+
+  # and return
+  return 1;
+}
+
+#find the range of the x scale, don't forget the errors!
+sub _find_y_range {
+  my $self = shift;
+  my $data = $self->{'dataref'};
+
+  my $max = undef;
+  my $min = undef;
+  if ($self->{'same_error'} =~ /^false$/i) {
+    for my $i (1..$self->{'num_datasets'}) {
+      if ( ($i-1)%3 == 0) {
+        for my $j (0..$self->{'num_datapoints'}) {
+          if (defined ($data->[$i][$j]) && defined($data->[$i+1][$j]) && defined($data->[$i+2][$j]) ){
+             if (defined $max){
+               if ( ($data->[$i][$j] + abs($data->[$i+1][$j])) > $max ) {
+                 $max =  $data->[$i][$j] + abs($data->[$i+1][$j]);
+               }
+               if ( ($data->[$i][$j] - abs($data->[$i+2][$j])) < $min ) {
+                 $min =  $data->[$i][$j] - abs($data->[$i+2][$j]);
+               }
+             }
+             else {$min = $max = $data->[$i][$j];}
+          }
+        }
+      }
+    }return ($min, $max);
+  }
+  else {
+    for my $i (1..$self->{'num_datasets'}) {
+      if ( ($i-1)%2 == 0) {
+        for my $j (0..$self->{'num_datapoints'}) {
+          if (defined ($data->[$i][$j]) && defined($data->[$i+1][$j]) ){
+             if (defined $max){
+               if ( ($data->[$i][$j] + $data->[$i+1][$j]) > $max ) {
+                 $max =  $data->[$i][$j] + $data->[$i+1][$j];
+               }
+               if ( ($data->[$i][$j] - $data->[$i+1][$j]) < $min ) {
+                 $min =  $data->[$i][$j] - $data->[$i+1][$j];
+               }
+             }
+             else {$min = $max = $data->[$i][$j];}
+          }
+        }
+      }
+    }
+    return ($min, $max);
+  }
+}
+## be a good module and return 1
+1;


Property changes on: packages/libchart-perl/branches/upstream/current/Chart/ErrorBars.pm
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/Chart/HorizontalBars.pm
===================================================================
--- packages/libchart-perl/branches/upstream/current/Chart/HorizontalBars.pm	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/Chart/HorizontalBars.pm	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,624 @@
+#====================================================================
+#  Chart::HorizontalBars
+#
+#  written by Chart-Group
+#
+#  maintained by the Chart Group
+#  Chart at wettzell.ifag.de
+#
+#---------------------------------------------------------------------
+# History:
+#----------
+# $RCSfile: HorizontalBars.pm,v $ $Revision: 1.2 $ $Date: 2003/02/14 14:04:40 $
+# $Author: dassing $
+# $Log: HorizontalBars.pm,v $
+# Revision 1.2  2003/02/14 14:04:40  dassing
+# First setup
+#
+#====================================================================
+
+package Chart::HorizontalBars;
+
+use Chart::Base '2.4.1';
+use GD;
+use Carp;
+use strict;
+
+ at Chart::HorizontalBars::ISA = qw(Chart::Base);
+$Chart::HorizontalBars::VERSION = '2.4.1';
+
+#>>>>>>>>>>>>>>>>>>>>>>>>>>#
+#  public methods go here  #
+#<<<<<<<<<<<<<<<<<<<<<<<<<<#
+
+
+
+#>>>>>>>>>>>>>>>>>>>>>>>>>>>#
+#  private methods go here  #
+#<<<<<<<<<<<<<<<<<<<<<<<<<<<#
+#draw x_ticks and their labels
+sub _draw_x_ticks {
+ my $self = shift;
+ my $data = $self->{'dataref'};
+ my $font = $self->{'tick_label_font'};
+ my $textcolor = $self->_color_role_to_index('text');
+ my $misccolor = $self->_color_role_to_index('misc');
+ my ($h, $w, $x1, $y1, ,$y2, $x2, $delta, $width, $label);
+ my @labels = @{$self->{'y_tick_labels'}};
+
+ $self->{'grid_data'}->{'x'} = [];
+ 
+ #make sure we have a real font
+ unless ((ref $font) eq 'GD::Font') {
+  croak "The tick label font you specified isn't a GD font object";
+ }
+ 
+ #get height and width of the font
+ ($h, $w) = ($font->height, $font->width);
+ 
+ #get the right x-value and width
+ if ( $self->{'y_axes'} =~ /^right$/i ){
+  $x1 = $self->{'curr_x_min'};
+  $width = $self->{'curr_x_max'} - $x1 -$self->{'tick_len'} - $self->{'text_space'}
+           - $w * $self->{'x_tick_label_length'};
+ }
+ elsif ( $self->{'y_axes'} =~ /^both$/i) {
+  $x1 = $self->{'curr_x_min'} + $self->{'text_space'} + $w* $self->{'x_tick_label_length'}
+        + $self->{'tick_len'};
+  $width = $self->{'curr_x_max'} - $x1 - $self->{'tick_len'} - $self->{'text_space'}
+           - $w * $self->{'x_tick_label_length'};
+ }
+ else {
+  $x1 = $self->{'curr_x_min'} + $self->{'text_space'} + $w* $self->{'x_tick_label_length'}
+        + $self->{'tick_len'};
+  $width = $self->{'curr_x_max'} - $x1;
+ }
+
+ #get the delta value
+ $delta = $width / ($self->{'y_ticks'} -1) ;
+
+ #draw the labels
+ $y2 =$y1;
+ 
+ if ($self->{'x_ticks'} =~ /^normal/i ) {  #just normal ticks
+   #get the point for updating later
+   $y1 = $self->{'curr_y_max'} - 2*$self->{'text_space'} -$h - $self->{'tick_len'};
+   #get the start point
+   $y2 = $y1  + $self->{'tick_len'} + $self->{'text_space'};
+   for (0..$#labels){
+     $label = $self->{'y_tick_labels'}[$_];
+     $x2 = $x1 + ($delta * $_) - ($w* length( $label)/2) ;
+     $self->{'gd_obj'}->string($font, $x2, $y2 , $label , $textcolor);
+   }
+ }
+ elsif ($self->{'x_ticks'} =~ /^staggered/i ) {  #staggered ticks
+   #get the point for updating later
+   $y1 = $self->{'curr_y_max'} - 3*$self->{'text_space'} - 2*$h - $self->{'tick_len'};
+
+   for (0..$#labels) {
+   $label = $self->{'y_tick_labels'}[$_];
+     $x2 = $x1 + ($delta * $_) - ($w* length( $label)/2);
+     unless ($_%2) {
+      $y2 = $y1  + $self->{'text_space'} + $self->{'tick_len'};
+       $self->{'gd_obj'}->string($font, $x2, $y2 , $label, $textcolor);
+     }
+     else {
+     $y2 = $y1  + $h + 2*$self->{'text_space'} + $self->{'tick_len'};
+       $self->{'gd_obj'}->string($font, $x2, $y2 , $label, $textcolor);
+     }
+   }
+
+ }
+
+ elsif ($self->{'x_ticks'} =~ /^vertical/i ) {  #vertical ticks
+   #get the point for updating later
+   $y1 = $self->{'curr_y_max'} - 2*$self->{'text_space'} -$w* $self->{'y_tick_label_length'} - $self->{'tick_len'};
+
+
+   for (0..$#labels){
+     $label = $self->{'y_tick_labels'}[$_];
+     #get the start point
+     $y2 = $y1  + $self->{'tick_len'} + $w* length($label) + $self->{'text_space'};
+
+     $x2 = $x1 + ($delta * $_) - ($h /2);
+     $self->{'gd_obj'}->stringUp($font, $x2, $y2 , $label , $textcolor);
+   }
+
+ }
+ 
+ else {
+  carp "I don't understand the type of x-ticks you specified";
+ }
+ #update the curr x and y max value
+ $self->{'curr_y_max'} = $y1;
+ $self->{'curr_x_max'} = $x1 + $width;
+ 
+ #draw the ticks
+ $y1 =$self->{'curr_y_max'};
+ $y2 =$self->{'curr_y_max'} + $self->{'tick_len'};
+ for(0..$#labels ) {
+   $x2 = $x1 + ($delta * $_);
+   $self->{'gd_obj'}->line($x2, $y1, $x2, $y2, $misccolor);
+     if (($self->{'grid_lines'} =~ /^true$/i) or ($self->{'x_grid_lines'} =~ /^true$/i)) {
+        $self->{'grid_data'}->{'x'}->[$_] = $x2;
+     }
+ }
+ 
+ return 1;
+}
+
+
+
+sub _draw_y_ticks {
+  my $self = shift;
+  my $side = shift || 'left';
+  my $data = $self->{'dataref'};
+  my $font = $self->{'tick_label_font'};
+  my $textcolor = $self->_color_role_to_index ('text');
+  my $misccolor = $self->_color_role_to_index ('misc');
+  my ($h, $w, $x1, $x2,  $y1, $y2);
+  my ($width, $height, $delta);
+
+  $self->{'grid_data'}->{'y'} =[];
+  
+  #make sure that is a real font
+  unless ((ref $font) eq 'GD::Font') {
+    croak "The tick label font isn't a GD Font object!";
+  }
+
+  #get the size of the font
+  ($h, $w) = ($font->height, $font->width);
+
+  #figure out, where to draw
+  if ($side =~ /^right$/i) {
+    #get the right startposition
+    $x1 = $self->{'curr_x_max'};
+    $y1 = $self->{'curr_y_max'} - $h/2;
+    
+    #get the delta values
+    $height =  $self->{'curr_y_max'} - $self->{'curr_y_min'} ;
+    $delta = ($height) / ($self->{'num_datapoints'} > 0 ? $self->{'num_datapoints'} : 1);
+    $y1 -= ($delta/2 );
+
+    #look if skipping is desired
+    if (!defined($self->{'skip_y_ticks'})) {
+       $self->{'skip_y_ticks'} =1;
+    }
+    
+    #draw the labels
+    for(0.. int (($self->{'num_datapoints'} - 1) / $self->{'skip_y_ticks'})) {
+       $y2 = $y1 - ($delta) * ($_ * $self->{'skip_y_ticks'});
+       $x2 = $x1 + $self->{'tick_len'} + $self->{'text_space'};
+       $self->{'gd_obj'}->string($font, $x2, $y2,
+                              $self->{f_y_tick}->($data->[0][$_*$self->{'skip_y_ticks'}]), $textcolor);
+    }
+    
+    #draw the ticks
+    $x1 = $self->{'curr_x_max'};
+    $x2 = $self->{'curr_x_max'} + $self->{'tick_len'};
+    $y1 += $h/2;
+    for(0..($self->{'num_datapoints'} -1 / $self->{'skip_y_ticks'})) {
+           $y2 = $y1 - ($delta * $_);
+           $self->{'gd_obj'}->line($x1,$y2,$x2,$y2,$misccolor);
+           if ($self->{'grid_lines'} =~ /^true$/i or $self->{'x_grid_lines'} =~ /^true$/i ) {
+              $self->{'grid_data'}->{'y'}->[$_] = $y2;
+           }
+    }
+    
+  }
+  elsif ($side =~ /^both$/i) {
+    #get the right startposition
+    $x1 = $self->{'curr_x_max'};
+    $y1 = $self->{'curr_y_max'} - $h/2;
+
+    #get the delta values
+    $height =  $self->{'curr_y_max'} - $self->{'curr_y_min'} ;
+    $delta = ($height) / ($self->{'num_datapoints'} > 0 ? $self->{'num_datapoints'} : 1);
+    $y1 -= ($delta/2 );
+
+    #look if skipping is desired
+    if (!defined($self->{'skip_y_ticks'})) {
+       $self->{'skip_y_ticks'} =1;
+    }
+
+    #first draw the right labels
+    for(0.. int (($self->{'num_datapoints'} - 1) / $self->{'skip_y_ticks'})) {
+       $y2 = $y1 - ($delta) * ($_ * $self->{'skip_y_ticks'});
+       $x2 = $x1 + $self->{'tick_len'} + $self->{'text_space'};
+       $self->{'gd_obj'}->string($font, $x2, $y2,
+                              $self->{f_y_tick}->($data->[0][$_*$self->{'skip_y_ticks'}]), $textcolor);
+    }
+
+    #then draw the right ticks
+    $x1 = $self->{'curr_x_max'};
+    $x2 = $self->{'curr_x_max'} + $self->{'tick_len'};
+    $y1 += $h/2;
+    for(0..($self->{'num_datapoints'} -1 / $self->{'skip_y_ticks'})) {
+           $y2 = $y1 - ($delta * $_);
+           $self->{'gd_obj'}->line($x1,$y2,$x2,$y2,$misccolor);
+           if ($self->{'grid_lines'} =~ /^true$/i or $self->{'x_grid_lines'} =~ /^true$/i ) {
+              $self->{'grid_data'}->{'y'}->[$_] = $y2;
+           }
+    }
+
+    #get the right startposition
+    $x1 = $self->{'curr_x_min'} ;
+    $y1 = $self->{'curr_y_max'} -$h/2 ;
+
+    #get the delta values for positioning
+    $height =  $self->{'curr_y_max'} - $self->{'curr_y_min'} ;
+    $delta = ($height) / ($self->{'num_datapoints'} > 0 ? $self->{'num_datapoints'} : 1);
+    $y1 -= ($delta/2 );
+
+    #then draw the left labels
+    for(0.. int (($self->{'num_datapoints'} - 1) / $self->{'skip_y_ticks'})) {
+       $y2 = $y1 - ($delta) * ($_ * $self->{'skip_y_ticks'});
+       $x2 = $x1 - $w * length($self->{f_y_tick}->($data->[0][$_*$self->{'skip_y_ticks'}])) #print the Labels right-sided
+             + $w * $self->{'x_tick_label_length'};
+       $self->{'gd_obj'}->string($font, $x2, $y2,
+                              $self->{f_y_tick}->($data->[0][$_*$self->{'skip_y_ticks'}]), $textcolor);
+    }
+
+    #update the curr_x_min val
+    $self->{'curr_x_min'} = $x1 + $self->{'text_space'} + $w* $self->{'x_tick_label_length'}
+                           + $self->{'tick_len'};
+
+    #finally draw the left ticks
+    $x1 = $self->{'curr_x_min'};
+    $x2 = $self->{'curr_x_min'} - $self->{'tick_len'};
+    $y1 += $h/2;
+    for(0..($self->{'num_datapoints'} -1 / $self->{'skip_y_ticks'})) {
+           $y2 = $y1 - ($delta * $_);
+           $self->{'gd_obj'}->line($x1,$y2,$x2,$y2,$misccolor);
+           if ($self->{'grid_lines'} =~ /^true$/i or $self->{'x_grid_lines'} =~ /^true$/i ) {
+              $self->{'grid_data'}->{'y'}->[$_] = $y2;
+           }
+    }
+  }
+
+  else {
+    #get the right startposition
+    $x1 = $self->{'curr_x_min'} ;
+    $y1 = $self->{'curr_y_max'} -$h/2 ;
+
+    #get the delta values for positioning
+    $height =  $self->{'curr_y_max'} - $self->{'curr_y_min'} ;
+    $delta = ($height) / ($self->{'num_datapoints'} > 0 ? $self->{'num_datapoints'} : 1);
+    $y1 -= ($delta/2 );
+  
+    if (!defined($self->{'skip_y_ticks'})) {
+       $self->{'skip_y_ticks'} =1;
+    }
+
+    #draw the labels
+    for(0.. int (($self->{'num_datapoints'} - 1) / $self->{'skip_y_ticks'})) {
+       $y2 = $y1 - ($delta) * ($_ * $self->{'skip_y_ticks'});
+       $x2 = $x1 - $w * length($self->{f_y_tick}->($data->[0][$_*$self->{'skip_y_ticks'}])) #print the Labels right-sided
+             + $w * $self->{'x_tick_label_length'};
+       $self->{'gd_obj'}->string($font, $x2, $y2,
+                              $self->{f_y_tick}->($data->[0][$_*$self->{'skip_y_ticks'}]), $textcolor);
+    }
+    
+    #update the curr_x_min val
+    $self->{'curr_x_min'} = $x1 + $self->{'text_space'} + $w* $self->{'x_tick_label_length'}
+                           + $self->{'tick_len'};
+  
+    #draw the ticks
+    $x1 = $self->{'curr_x_min'};
+    $x2 = $self->{'curr_x_min'} - $self->{'tick_len'};
+    $y1 += $h/2;
+    for(0..($self->{'num_datapoints'} -1 / $self->{'skip_y_ticks'})) {
+           $y2 = $y1 - ($delta * $_);
+           $self->{'gd_obj'}->line($x1,$y2,$x2,$y2,$misccolor);
+           if ($self->{'grid_lines'} =~ /^true$/i or $self->{'x_grid_lines'} =~ /^true$/i ) {
+              $self->{'grid_data'}->{'y'}->[$_] = $y2;
+           }
+    }
+  }
+  #now return
+  return 1;
+}
+
+#overwrite the find_y_scale function, only to get the right f_x_ticks !!!!!
+sub _find_y_scale
+{
+	my $self = shift;
+
+	# Predeclare vars.
+	my ($d_min, $d_max);		# Dataset min & max.
+	my ($p_min, $p_max);		# Plot min & max.
+	my ($tickInterval, $tickCount);
+	my @tickLabels;				# List of labels for each tick.
+	my $maxtickLabelLen = 0;	# The length of the longest tick label.
+
+	# Find the datatset minimum and maximum.
+	($d_min, $d_max) = $self->_find_y_range();
+
+	# Force the inclusion of zero if the user has requested it.
+	if( $self->{'include_zero'} =~ m!^true$!i )
+	{
+		if( ($d_min * $d_max) > 0 )	# If both are non zero and of the same sign.
+		{
+			if( $d_min > 0 )	# If the whole scale is positive.
+			{
+				$d_min = 0;
+			}
+			else				# The scale is entirely negative.
+			{
+				$d_max = 0;
+			}
+		}
+	}
+
+        if ( $self->{'integer_ticks_only'} =~ /^\d$/ ) {
+           if ( $self->{'integer_ticks_only'} == 1 ) {
+              $self->{'integer_ticks_only'} = 'true';
+           } else {
+              $self->{'integer_ticks_only'} = 'false';
+           }
+        }
+	if( $self->{'integer_ticks_only'} =~ m!^true$!i )
+	{
+                # Allow the dataset range to be overidden by the user.
+	        # f_min/max are booleans which indicate that the min & max should not be modified.
+	        my $f_min = defined $self->{'min_val'};
+	        $d_min = $self->{'min_val'} if $f_min;
+
+	        my $f_max = defined $self->{'max_val'};
+	        $d_max = $self->{'max_val'} if $f_max;
+
+	        # Assert against the min is larger than the max.
+	        if( $d_min > $d_max )
+	        {
+	         croak "The the specified 'min_val' & 'max_val' values are reversed (min > max: $d_min>$d_max)";
+	        }
+		# The user asked for integer ticks, force the limits to integers.
+		# & work out the range directly.
+		$p_min = $self->_round2Tick($d_min, 1, -1);
+		$p_max = $self->_round2Tick($d_max, 1, 1);
+
+		my $skip = $self->{skip_int_ticks};
+
+		$tickInterval = $skip;
+		$tickCount = ($p_max - $p_min ) /$skip +1;
+
+             	# Now sort out an array of tick labels.
+
+		for( my $labelNum = $p_min; $labelNum<=$p_max; $labelNum+=$tickInterval )
+		{
+			my $labelText;
+
+			if( defined $self->{f_x_tick} )
+			{
+                        	# Is _default_f_tick function used?
+                        	if ( $self->{f_x_tick} == \&_default_f_tick) {
+			   	$labelText = sprintf("%d", $labelNum);
+                        	}
+				else {
+					$labelText = $self->{f_x_tick}->($labelNum);
+                        	}
+			}
+
+			else
+			{
+				$labelText = sprintf("%d", $labelNum);
+			}
+
+		#print "labelText = $labelText\n";
+		push @tickLabels, $labelText;
+		$maxtickLabelLen = length $labelText if $maxtickLabelLen < length $labelText;
+		}
+
+	}
+	else
+	{
+	    # Allow the dataset range to be overidden by the user.
+	    # f_min/max are booleans which indicate that the min & max should not be modified.
+	    my $f_min = defined $self->{'min_val'};
+	    $d_min = $self->{'min_val'} if $f_min;
+
+	    my $f_max = defined $self->{'max_val'};
+	    $d_max = $self->{'max_val'} if $f_max;
+
+	    # Assert against the min is larger than the max.
+	    if( $d_min > $d_max )
+	    {
+	     croak "The the specified 'min_val' & 'max_val' values are reversed (min > max: $d_min>$d_max)";
+	     }
+
+	     # Calculate the width of the dataset. (posibly modified by the user)
+	     my $d_width = $d_max - $d_min;
+
+	     # If the width of the range is zero, forcibly widen it
+	     # (to avoid division by zero errors elsewhere in the code).
+	     if( 0 == $d_width )
+	         {
+		$d_min--;
+		$d_max++;
+		$d_width = 2;
+	          }
+
+             # Descale the range by converting the dataset width into
+             # a floating point exponent & mantisa pair.
+             my( $rangeExponent, $rangeMantisa ) = $self->_sepFP( $d_width );
+	     my $rangeMuliplier = 10 ** $rangeExponent;
+
+	     # Find what tick
+	     # to use & how many ticks to plot,
+	     # round the plot min & max to suatable round numbers.
+	     ($tickInterval, $tickCount, $p_min, $p_max)
+		= $self->_calcTickInterval($d_min/$rangeMuliplier, $d_max/$rangeMuliplier,
+				$f_min, $f_max,
+				$self->{'min_y_ticks'}, $self->{'max_y_ticks'});
+	     # Restore the tickInterval etc to the correct scale
+	     $_ *= $rangeMuliplier foreach($tickInterval, $p_min, $p_max);
+
+	     #get teh precision for the labels
+	     my $precision = $self->{'precision'};
+
+	     # Now sort out an array of tick labels.
+	     for( my $labelNum = $p_min; $labelNum<=$p_max; $labelNum+=$tickInterval )
+	     {
+		my $labelText;
+
+		if( defined $self->{f_x_tick} )
+		{
+                        # Is _default_f_tick function used?
+                        if ( $self->{f_x_tick} == \&_default_f_tick) {
+			   $labelText = sprintf("%.".$precision."f", $labelNum);
+                        } else {
+			   $labelText = $self->{f_x_tick}->($labelNum);
+                        }
+		}
+		else
+		{
+			$labelText = sprintf("%.".$precision."f", $labelNum);
+		}
+		#print "labelText = $labelText\n";
+		push @tickLabels, $labelText;
+		$maxtickLabelLen = length $labelText if $maxtickLabelLen < length $labelText;
+	     }
+	}
+
+	# Store the calculated data.
+	$self->{'min_val'} = $p_min;
+	$self->{'max_val'} = $p_max;
+	$self->{'y_ticks'} = $tickCount;
+	$self->{'y_tick_labels'} = \@tickLabels;
+	$self->{'y_tick_label_length'} = $maxtickLabelLen;
+
+	# and return.
+	return 1;
+}
+
+
+## finally get around to plotting the data
+sub _draw_data {
+  my $self = shift;
+  my $data = $self->{'dataref'};
+  my $misccolor = $self->_color_role_to_index('misc');
+  my ($x1, $x2, $x3, $y1, $y2, $y3);
+  my $cut = 0;
+  my ($width, $height, $delta1, $delta2, $map, $mod, $pink);
+  my ($i, $j, $color);
+
+  # init the imagemap data field if they wanted it
+  if ($self->{'imagemap'} =~ /^true$/i) {
+    $self->{'imagemap_data'} = [];
+  }
+
+  # find both delta values ($delta1 for stepping between different
+  # datapoint names, $delta2 for setpping between datasets for that
+  # point) and the mapping constant
+  $width = $self->{'curr_x_max'} - $self->{'curr_x_min'};
+  $height = $self->{'curr_y_max'} - $self->{'curr_y_min'};
+  $delta1 = $height / ($self->{'num_datapoints'} > 0 ? $self->{'num_datapoints'} : 1);
+  $map = $width / ($self->{'max_val'} - $self->{'min_val'});
+  if ($self->{'spaced_bars'} =~ /^true$/i) {
+    $delta2 = $delta1 / ($self->{'num_datasets'} + 2);
+  }
+  else {
+    $delta2 = $delta1 / $self->{'num_datasets'};
+  }
+
+  # get the base x-y values
+  $y1 = $self->{'curr_y_max'} - $delta2;
+  if ($self->{'min_val'} >= 0) {
+    $x1 = $self->{'curr_x_min'} ;
+    $mod = $self->{'min_val'};
+  }
+  elsif ($self->{'max_val'} <= 0) {
+    $x1 = $self->{'curr_x_max'};
+    $mod = $self->{'max_val'};
+  }
+  else {
+   $x1 = $self->{'curr_x_min'} + abs($map * $self->{'min_val'});
+   $mod = 0;
+   $self->{'gd_obj'}->line ($x1, $self->{'curr_y_min'},
+                            $x1, $self->{'curr_y_max'},
+                           $misccolor);
+  }
+  
+  # draw the bars
+  for $i (1..$self->{'num_datasets'}) {
+    # get the color for this dataset
+    $color = $self->_color_role_to_index('dataset'.($i-1));
+    
+    # draw every bar for this dataset
+    for $j (0..$self->{'num_datapoints'}) {
+      # don't try to draw anything if there's no data
+      if (defined ($data->[$i][$j])) {
+	# find the bounds of the rectangle
+        if ($self->{'spaced_bars'} =~ /^true$/i) {
+           $y2 = $y1 - ($j * $delta1) - ($self->{'num_datasets'} * $delta2) + (($i-1) * $delta2);
+	}
+	else {
+           $y2 = $y1 - ($j * $delta1) - ($self->{'num_datasets'} * $delta2) + (($i) * $delta2);
+	}
+	$x2 = $x1;
+	$y3 = $y2 + $delta2;
+
+        #cut the bars off, if needed
+        if ($data->[$i][$j] > $self->{'max_val'}) {
+           $x3 = $x1 + (($self->{'max_val'} - $mod ) * $map) -1;
+           $cut = 1;
+        }
+        elsif  ($data->[$i][$j] < $self->{'min_val'}) {
+           $x3 = $x1 + (($self->{'min_val'} - $mod ) * $map) +1;
+           $cut = 1;
+        }
+        else {
+           $x3 = $x1 + (($data->[$i][$j] - $mod) * $map);
+           $cut = 0;
+        }
+        
+	# draw the bar
+	## y2 and y3 are reversed in some cases because GD's fill
+	## algorithm is lame
+	if ($data->[$i][$j] < 0) {
+          $self->{'gd_obj'}->filledRectangle ($x3, $y2, $x2, $y3, $color);
+          if ($self->{'imagemap'} =~ /^true$/i) {
+	       $self->{'imagemap_data'}->[$i][$j] = [$x3, $y2, $x2, $y3];
+          }
+
+          $self->{'gd_obj'}->filledRectangle ($x3, $y2, $x2, $y3, $color);
+          if ($self->{'imagemap'} =~ /^true$/i) {
+              $self->{'imagemap_data'}->[$i][$j] = [$x3, $y2, $x2, $y3];
+          }
+	}
+	else {
+	  $self->{'gd_obj'}->filledRectangle ($x2, $y2, $x3, $y3, $color);
+	  if ($self->{'imagemap'} =~ /^true$/i) {
+	    $self->{'imagemap_data'}->[$i][$j] = [$x2, $y2, $x3, $y3];
+	  }
+	}
+
+	# now outline it. outline red if the bar had been cut off
+        unless ($cut){
+	  $self->{'gd_obj'}->rectangle ($x2, $y3, $x3, $y2, $misccolor);
+        }
+        else {
+          $pink = $self->{'gd_obj'}->colorAllocate(255,0,255);
+          $self->{'gd_obj'}->rectangle ($x2, $y3, $x3, $y2, $pink);
+        }
+        
+      } else {
+	  if ($self->{'imagemap'} =~ /^true$/i) {
+            $self->{'imagemap_data'}->[$i][$j] = [undef(), undef(), undef(), undef()];
+          }
+      }
+    }
+  }
+      
+  # and finaly box it off 
+  $self->{'gd_obj'}->rectangle ($self->{'curr_x_min'},
+  				$self->{'curr_y_min'},
+				$self->{'curr_x_max'},
+				$self->{'curr_y_max'},
+				$misccolor);
+  return;
+
+}
+
+## be a good module and return 1
+1;


Property changes on: packages/libchart-perl/branches/upstream/current/Chart/HorizontalBars.pm
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/Chart/Lines.pm
===================================================================
--- packages/libchart-perl/branches/upstream/current/Chart/Lines.pm	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/Chart/Lines.pm	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,310 @@
+#====================================================================
+#  Chart::Lines
+#                                
+#  written by david bonner        
+#  dbonner at cs.bu.edu              
+#
+#  maintained by the Chart Group
+#  Chart at wettzell.ifag.de
+#
+#---------------------------------------------------------------------
+# History:
+#----------
+# $RCSfile: Lines.pm,v $ $Revision: 1.4 $ $Date: 2003/02/14 14:08:24 $
+# $Author: dassing $
+# $Log: Lines.pm,v $
+# Revision 1.4  2003/02/14 14:08:24  dassing
+# First setup to cvs
+#
+#====================================================================
+
+package Chart::Lines;
+
+use Chart::Base '2.4.1';
+use GD;
+use Carp;
+use strict;
+
+ at Chart::Lines::ISA = qw(Chart::Base);
+$Chart::Lines::VERSION = '2.4.1';
+
+#>>>>>>>>>>>>>>>>>>>>>>>>>>#
+#  public methods go here  #
+#<<<<<<<<<<<<<<<<<<<<<<<<<<#
+
+
+
+#>>>>>>>>>>>>>>>>>>>>>>>>>>>#
+#  private methods go here  #
+#<<<<<<<<<<<<<<<<<<<<<<<<<<<#
+
+## finally get around to plotting the data
+sub _draw_data {
+  my $self = shift;
+  my $data = $self->{'dataref'};
+  my $misccolor = $self->_color_role_to_index('misc');
+  my ($x1, $x2, $x3, $y1, $y2, $y3, $mod, $abs_x_max, $abs_y_max, $tan_alpha);
+  my ($width, $height, $delta, $delta_num, $map, $t_x_min, $t_x_max, $t_y_min, $t_y_max);
+  my ($i, $j, $color, $brush, $zero_offset);
+  my $repair_top_flag = 0;
+  my $repair_bottom_flag = 0;
+
+  # init the imagemap data field if they asked for it
+  if ($self->{'imagemap'} =~ /^true$/i) {
+    $self->{'imagemap_data'} = [];
+  }
+
+  # find the delta value between data points, as well
+  # as the mapping constant
+  $width = $self->{'curr_x_max'} - $self->{'curr_x_min'};
+  $height = $self->{'curr_y_max'} - $self->{'curr_y_min'};
+  $delta = $width / ($self->{'num_datapoints'} > 0 ? $self->{'num_datapoints'} : 1);
+  $map = $height / ($self->{'max_val'} - $self->{'min_val'});
+
+  #for a xy-plot, use this delta and maybe an offset for the zero-axes
+  if ($self->{'xy_plot'} =~ /^true$/i ) {
+    $delta_num = $width / ($self->{'x_max_val'} - $self->{'x_min_val'});
+
+    if ($self->{'x_min_val'} <= 0 && $self->{'x_max_val'} >= 0) {
+       $zero_offset = abs($self->{'x_min_val'}) * abs($delta_num);
+    }
+    elsif ($self->{'x_min_val'} > 0 || $self->{'x_max_val'} < 0) {
+       $zero_offset =  -$self->{'x_min_val'} * $delta_num;
+    }
+    else {
+       $zero_offset = 0;
+    }
+  }
+  
+  # get the base x-y values
+  if ($self->{'xy_plot'} =~ /^true$/i ) {
+    $x1 = $self->{'curr_x_min'};
+  }
+  else {
+    $x1 = $self->{'curr_x_min'} + ($delta / 2);
+  }
+  if ($self->{'min_val'} >= 0 ) {
+    $y1 = $self->{'curr_y_max'};
+    $mod = $self->{'min_val'};
+  }
+  elsif ($self->{'max_val'} <= 0) {
+    $y1 = $self->{'curr_y_min'};
+    $mod = $self->{'max_val'};
+  }
+  else {
+    $y1 = $self->{'curr_y_min'} + ($map * $self->{'max_val'});
+    $mod = 0;
+    $self->{'gd_obj'}->line ($self->{'curr_x_min'}, $y1,
+                             $self->{'curr_x_max'}, $y1,
+                             $misccolor);
+  }
+
+  # draw the lines
+  for $i (1..$self->{'num_datasets'}) {
+    # get the color for this dataset, and set the brush
+    $color = $self->_color_role_to_index('dataset'.($i-1));
+    $brush = $self->_prepare_brush ($color);
+    $self->{'gd_obj'}->setBrush ($brush);
+    
+    # draw every line for this dataset
+    for $j (1..$self->{'num_datapoints'}) {
+      # don't try to draw anything if there's no data
+      if (defined ($data->[$i][$j]) and defined ($data->[$i][$j-1])) {
+        if ($self->{'xy_plot'} =~ /^true$/i ) {
+           $x2 = $x1 + $delta_num * $data->[0][$j-1] + $zero_offset;
+           $x3 = $x1 + $delta_num * $data->[0][$j] + $zero_offset;
+        }
+        else {
+           $x2 = $x1 + ($delta * ($j - 1));
+           $x3 = $x1 + ($delta * $j);
+        }
+	$y2 = $y1 - (($data->[$i][$j-1] - $mod) * $map);
+	$y3 = $y1 - (($data->[$i][$j] - $mod) * $map);
+
+        # now draw the line
+        # ----------------
+        # stepline option added by G.ST. 2005/02
+        #----------------
+        if ($self->{'stepline'} =~ /^true$/i ) 
+        {
+           if ($self->{'stepline_mode'} =~ /^begin$/i ) 
+           {
+              $self->{'gd_obj'}->line($x2, $y2, $x3, $y2, gdBrushed);
+              $self->{'gd_obj'}->line($x3, $y2, $x3, $y3, gdBrushed);
+           }
+           else 
+           {
+              $self->{'gd_obj'}->line($x2, $y2, $x2, $y3, gdBrushed);
+              $self->{'gd_obj'}->line($x2, $y3, $x3, $y3, gdBrushed);
+           }
+        }
+        # -----------------------------------
+        # end stepline option
+        #------------------------------------
+        else
+        {
+            $self->{'gd_obj'}->line($x2, $y2, $x3, $y3, gdBrushed);
+        }
+        
+        # set the flags, if the lines are out of the borders of the chart
+        if ( ($data->[$i][$j] > $self->{'max_val'}) || ($data->[$i][$j-1] > $self->{'max_val'}) ) {
+           $repair_top_flag = 1;
+        }
+        
+        if ( ($self->{'max_val'} <= 0) &&
+             (($data->[$i][$j] > $self->{'max_val'}) || ($data->[$i][$j-1] > $self->{'max_val'})) ) {
+           $repair_top_flag = 1;
+        }
+        if ( ($data->[$i][$j] < $self->{'min_val'}) || ($data->[$i][$j-1] < $self->{'min_val'}) ) {
+           $repair_bottom_flag = 1;
+        }
+
+	# store the imagemap data if they asked for it
+	if ($self->{'imagemap'} =~ /^true$/i) {
+	  $self->{'imagemap_data'}->[$i][$j-1] = [ $x2, $y2 ];
+	  $self->{'imagemap_data'}->[$i][$j] = [ $x3, $y3 ];
+	}
+      } else {
+	if ($self->{'imagemap'} =~ /^true$/i) {
+	  $self->{'imagemap_data'}->[$i][$j-1] = [ undef(), undef() ];
+	  $self->{'imagemap_data'}->[$i][$j] = [ undef(), undef() ];
+        }
+      }
+    }
+  }
+  # and finaly box it off
+  $self->{'gd_obj'}->rectangle ($self->{'curr_x_min'},
+  				$self->{'curr_y_min'},
+				$self->{'curr_x_max'},
+				$self->{'curr_y_max'},
+				$misccolor);
+
+   #get the width and the heigth of the complete picture
+  ($abs_x_max, $abs_y_max) = $self->{'gd_obj'}->getBounds();
+  
+  #repair the chart, if the lines are out of the borders of the chart
+  if ($repair_top_flag) {
+   #overwrite the ugly mistakes
+   $self->{'gd_obj'}->filledRectangle ($self->{'curr_x_min'}-($self->{'brush_size'}/2), 0,
+				$self->{'curr_x_max'}, $self->{'curr_y_min'}-1,
+				$self->_color_role_to_index('background'));
+
+   #save the actual x and y values
+   $t_x_min = $self->{'curr_x_min'};
+   $t_x_max = $self->{'curr_x_max'};
+   $t_y_min = $self->{'curr_y_min'};
+   $t_y_max = $self->{'curr_y_max'};
+
+
+   #get back to the point, where everything began
+   $self->{'curr_x_min'} = 0;
+   $self->{'curr_y_min'} = 0;
+   $self->{'curr_x_max'} = $abs_x_max;
+   $self->{'curr_y_max'} = $abs_y_max;
+
+   #draw the title again
+   if ($self->{'title'}) {
+    $self->_draw_title
+   }
+
+   #draw the sub title again
+   if ($self->{'sub_title'}) {
+    $self->_draw_sub_title
+   }
+
+   #draw the top legend again
+   if ($self->{'legend'} =~ /^top$/i) {
+    $self->_draw_top_legend;
+   }
+   
+   #reset the actual values
+   $self->{'curr_x_min'} = $t_x_min;
+   $self->{'curr_x_max'} = $t_x_max;
+   $self->{'curr_y_min'} = $t_y_min;
+   $self->{'curr_y_max'} = $t_y_max;
+  }
+
+  if ($repair_bottom_flag) {
+
+   #overwrite the ugly mistakes
+   $self->{'gd_obj'}->filledRectangle ($self->{'curr_x_min'}-($self->{'brush_size'}/2), $self->{'curr_y_max'}+1,
+				$self->{'curr_x_max'}, $abs_y_max,
+				$self->_color_role_to_index('background'));
+    #save the actual x and y values
+   $t_x_min = $self->{'curr_x_min'};
+   $t_x_max = $self->{'curr_x_max'};
+   $t_y_min = $self->{'curr_y_min'};
+   $t_y_max = $self->{'curr_y_max'};
+
+   #get back to the point, where everything began
+   $self->{'curr_x_min'} = 0;
+   $self->{'curr_y_min'} = 0;
+   $self->{'curr_x_max'} = $abs_x_max;
+   $self->{'curr_y_max'} = $abs_y_max-1;
+
+    # mark off the graph_border space
+   $self->{'curr_y_max'} -= 2* $self->{'graph_border'};
+   
+   #draw the bottom legend again
+   if ($self->{'legend'} =~ /^bottom$/i) {
+    $self->_draw_bottom_legend;
+   }
+   
+   #draw the x label again
+   if ($self->{'x_label'}) {
+    $self->_draw_x_label;
+   }
+
+   #get back to the start point for the ticks
+   $self->{'curr_x_min'} = $self->{'temp_x_min'};
+   $self->{'curr_y_min'} = $self->{'temp_y_min'};
+   $self->{'curr_x_max'} = $self->{'temp_x_max'};
+   $self->{'curr_y_max'} = $self->{'temp_y_max'};
+   
+   #draw the x ticks again
+   if ($self->{'xy_plot'} =~ /^true$/i) {
+      $self->_draw_x_number_ticks;
+   }
+   else {
+      $self->_draw_x_ticks;
+   }
+
+   #reset the actual values
+   $self->{'curr_x_min'} = $t_x_min;
+   $self->{'curr_x_max'} = $t_x_max;
+   $self->{'curr_y_min'} = $t_y_min;
+   $self->{'curr_y_max'} = $t_y_max;
+  }
+    
+  return;
+
+}
+
+
+##  set the gdBrush object to trick GD into drawing fat lines
+sub _prepare_brush {
+  my $self = shift;
+  my $color = shift;
+  my $radius = $self->{'brush_size'}/2;
+  my (@rgb, $brush, $white, $newcolor);
+
+  # get the rgb values for the desired color
+  @rgb = $self->{'gd_obj'}->rgb($color);
+
+  # create the new image
+  $brush = GD::Image->new ($radius*2, $radius*2);
+
+  # get the colors, make the background transparent
+  $white = $brush->colorAllocate (255,255,255);
+  $newcolor = $brush->colorAllocate (@rgb);
+  $brush->transparent ($white);
+
+  # draw the circle
+  $brush->arc ($radius-1, $radius-1, $radius, $radius, 0, 360, $newcolor);
+
+  # set the new image as the main object's brush
+  return $brush;
+}
+
+## be a good module and return 1
+1;

Added: packages/libchart-perl/branches/upstream/current/Chart/LinesPoints.pm
===================================================================
--- packages/libchart-perl/branches/upstream/current/Chart/LinesPoints.pm	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/Chart/LinesPoints.pm	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,345 @@
+#====================================================================
+#  Chart::LinesPoints
+#                                
+#  written by david bonner        
+#  dbonner at cs.bu.edu              
+#
+#  maintained by the Chart Group
+#  Chart at wettzell.ifag.de
+#
+#---------------------------------------------------------------------
+# History:
+#----------
+# $RCSfile: LinesPoints.pm,v $ $Revision: 1.4 $ $Date: 2003/02/14 14:10:36 $
+# $Author: dassing $
+# $Log: LinesPoints.pm,v $
+# Revision 1.4  2003/02/14 14:10:36  dassing
+# First setup to cvs
+#
+#====================================================================
+package Chart::LinesPoints;
+
+use Chart::Base '2.4.1';
+use GD;
+use Carp;
+use strict;
+
+ at Chart::LinesPoints::ISA = qw(Chart::Base);
+$Chart::LinesPoints::VERSION = '2.4.1';
+
+#>>>>>>>>>>>>>>>>>>>>>>>>>>#
+#  public methods go here  #
+#<<<<<<<<<<<<<<<<<<<<<<<<<<#
+
+
+
+#>>>>>>>>>>>>>>>>>>>>>>>>>>>#
+#  private methods go here  #
+#<<<<<<<<<<<<<<<<<<<<<<<<<<<#
+
+## finally get around to plotting the data
+sub _draw_data {
+  my $self = shift;
+  my $data = $self->{'dataref'};
+  my $misccolor = $self->_color_role_to_index('misc');
+  my ($x1, $x2, $x3, $y1, $y2, $y3, $mod, $abs_x_max, $abs_y_max);
+  my ($width, $height, $delta, $map, $t_x_min, $t_x_max, $t_y_min, $t_y_max);
+  my ($i, $j, $color, $brush, $zero_offset, $delta_num);
+  my $repair_top_flag = 0;
+  my $repair_bottom_flag = 0;
+  my $diff;
+  
+  # init the imagemap data field if they want it
+  if ($self->{'imagemap'} =~ /^true$/i) {
+    $self->{'imagemap_data'} = [];
+  }
+
+  # find the delta value between data points, as well
+  # as the mapping constant
+  $width = $self->{'curr_x_max'} - $self->{'curr_x_min'};
+  $height = $self->{'curr_y_max'} - $self->{'curr_y_min'};
+  $delta = $width / ($self->{'num_datapoints'} > 0 ? $self->{'num_datapoints'} : 1);
+  $diff = ($self->{'max_val'} - $self->{'min_val'});
+  $diff = 1 if $diff == 0;
+  $map = $height / $diff;
+
+  # get the base x-y values
+  if ($self->{'xy_plot'} =~ /^true$/i) {
+    $x1 = $self->{'curr_x_min'};
+  }
+  else {
+    $x1 = $self->{'curr_x_min'} + ($delta / 2);
+  }
+  if ($self->{'min_val'} >= 0) {
+    $y1 = $self->{'curr_y_max'};
+    $mod = $self->{'min_val'};
+  }
+  elsif ($self->{'max_val'} <= 0) {
+    $y1  = $self->{'curr_y_min'};
+    $mod = $self->{'max_val'};
+  }
+  else {
+    $y1 = $self->{'curr_y_min'} + ($map * $self->{'max_val'});
+    $mod = 0;
+    $self->{'gd_obj'}->line ($self->{'curr_x_min'}, $y1,
+                             $self->{'curr_x_max'}, $y1,
+                             $misccolor);
+  }
+
+  #for a xy-plot, use this delta and maybe an offset for the zero-axes
+  if ($self->{'xy_plot'} =~ /^true$/i ) {
+    $diff = ($self->{'x_max_val'} - $self->{'x_min_val'});
+    $diff = 1 if $diff == 0;
+    $delta_num = $width / ($self->{'x_max_val'} - $self->{'x_min_val'});
+
+    if ($self->{'x_min_val'} <= 0 && $self->{'x_max_val'} >= 0) {
+       $zero_offset = abs($self->{'x_min_val'}) * abs($delta_num);
+    }
+    elsif ($self->{'x_min_val'} > 0 || $self->{'x_max_val'} < 0) {
+       $zero_offset =  -$self->{'x_min_val'} * $delta_num;
+    }
+    else {
+       $zero_offset = 0;
+    }
+  }
+  
+  # draw the lines
+  for $i (1..$self->{'num_datasets'}) {
+    # get the color for this dataset, and set the brush
+    $color = $self->_color_role_to_index('dataset'.($i-1));
+    $brush = $self->_prepare_brush ($color, 'line');
+    $self->{'gd_obj'}->setBrush ($brush);
+
+    # draw every line for this dataset
+    for $j (1..$self->{'num_datapoints'}) {
+      # don't try to draw anything if there's no data
+      if (defined ($data->[$i][$j]) and defined ($data->[$i][$j-1])) {
+        if ($self->{'xy_plot'} =~ /^true$/i ) {
+           $x2 = $x1 + $delta_num * $data->[0][$j-1] + $zero_offset;
+           $x3 = $x1 + $delta_num * $data->[0][$j] + $zero_offset;
+        }
+        else {
+           $x2 = $x1 + ($delta * ($j - 1));
+           $x3 = $x1 + ($delta * $j);
+        }
+	$y2 = $y1 - (($data->[$i][$j-1] - $mod) * $map);
+	$y3 = $y1 - (($data->[$i][$j] - $mod) * $map);
+
+        #set the flags, if the lines are out of the borders of the chart
+        if ( ($data->[$i][$j] > $self->{'max_val'}) || ($data->[$i][$j-1] > $self->{'max_val'}) ) {
+           $repair_top_flag = 1;
+        }
+
+        if ( ($self->{'max_val'} <= 0) &&
+             (($data->[$i][$j] > $self->{'max_val'}) || ($data->[$i][$j-1] > $self->{'max_val'})) ) {
+           $repair_top_flag = 1;
+        }
+        if ( ($data->[$i][$j] < $self->{'min_val'}) || ($data->[$i][$j-1] < $self->{'min_val'}) ) {
+           $repair_bottom_flag = 1;
+        }
+
+        # draw the line
+        # ----------------
+        # stepline option added by G.ST. 2005/02
+        #----------------
+        if ($self->{'stepline'} =~ /^true$/i ) 
+        {
+           if ($self->{'stepline_mode'} =~ /^begin$/i ) 
+           {
+              $self->{'gd_obj'}->line($x2, $y2, $x3, $y2, gdBrushed);
+              $self->{'gd_obj'}->line($x3, $y2, $x3, $y3, gdBrushed);
+           }
+           else 
+           {
+              $self->{'gd_obj'}->line($x2, $y2, $x2, $y3, gdBrushed);
+              $self->{'gd_obj'}->line($x2, $y3, $x3, $y3, gdBrushed);
+           }
+        }
+        # -----------------------------------
+        # end stepline option
+        #------------------------------------
+        else
+	{
+            $self->{'gd_obj'}->line($x2, $y2, $x3, $y3, gdBrushed);
+        }
+      }
+    }
+
+    # reset the brush for points
+    $brush = $self->_prepare_brush ($color, 'point');
+    $self->{'gd_obj'}->setBrush ($brush);
+
+    # draw every point for this dataset
+    for $j (0..$self->{'num_datapoints'}) {
+      # don't try to draw anything if there's no data
+      if (defined ($data->[$i][$j])) {
+        if ($self->{'xy_plot'} =~ /^true$/i ) {
+           $x2 = $x1 + $delta_num * $data->[0][$j] + $zero_offset;
+           $x3 = $x2 ;
+        }
+        else {
+           $x2 = $x1 + ($delta * $j);
+           $x3 = $x2;
+        }
+        $y2 = $y1 - (($data->[$i][$j] - $mod) * $map);
+        $y3 = $y2;
+
+        # draw the point
+        $self->{'gd_obj'}->line($x2, $y2, $x3, $y3, gdBrushed);
+
+	# remember the imagemap data if they wanted it
+	if ($self->{'imagemap'} =~ /^true$/i) {
+	  $self->{'imagemap_data'}->[$i][$j] = [ $x2, $y2 ];
+	}
+      } else {
+	if ($self->{'imagemap'} =~ /^true$/i) {
+	  $self->{'imagemap_data'}->[$i][$j] = [ undef(), undef() ];
+        }
+      }
+    }
+  }
+      
+  # and finaly box it off 
+  $self->{'gd_obj'}->rectangle ($self->{'curr_x_min'},
+  				$self->{'curr_y_min'},
+				$self->{'curr_x_max'},
+				$self->{'curr_y_max'},
+				$misccolor);
+
+  #get the width and the heigth of the complete picture
+  ($abs_x_max, $abs_y_max) = $self->{'gd_obj'}->getBounds();
+
+  #repair the chart, if the lines are out of the borders of the chart
+  if ($repair_top_flag) { 
+   #overwrite the ugly mistakes
+#   $self->{'gd_obj'}->filledRectangle ($self->{'curr_x_min'}, 0,
+    $self->{'gd_obj'}->filledRectangle ($self->{'curr_x_min'}-($self->{'brush_size'}/2), 0,
+				$self->{'curr_x_max'}, $self->{'curr_y_min'}-2,
+				$self->_color_role_to_index('background'));
+
+   #save the actual x and y values
+   $t_x_min = $self->{'curr_x_min'};
+   $t_x_max = $self->{'curr_x_max'};
+   $t_y_min = $self->{'curr_y_min'};
+   $t_y_max = $self->{'curr_y_max'};
+
+
+   #get back to the point, where everything began
+   $self->{'curr_x_min'} = 0;
+   $self->{'curr_y_min'} = 0;
+   $self->{'curr_x_max'} = $abs_x_max;
+   $self->{'curr_y_max'} = $abs_y_max;
+
+   #draw the title again
+   if ($self->{'title'}) {
+    $self->_draw_title
+   }
+
+   #draw the sub title again
+   if ($self->{'sub_title'}) {
+    $self->_draw_sub_title
+   }
+
+   #draw the top legend again
+   if ($self->{'legend'} =~ /^top$/i) {
+    $self->_draw_top_legend;
+   }
+
+   #reset the actual values
+   $self->{'curr_x_min'} = $t_x_min;
+   $self->{'curr_x_max'} = $t_x_max;
+   $self->{'curr_y_min'} = $t_y_min;
+   $self->{'curr_y_max'} = $t_y_max;
+  }
+
+  if ($repair_bottom_flag) { 
+   #overwrite the ugly mistakes
+# $self->{'gd_obj'}->filledRectangle ($self->{'curr_x_min'}, $self->{'curr_y_max'}+1,
+   $self->{'gd_obj'}->filledRectangle ($self->{'curr_x_min'}-($self->{'brush_size'}/2), $self->{'curr_y_max'}+1,
+				$self->{'curr_x_max'}, $abs_y_max,
+				$self->_color_role_to_index('background'));
+
+    #save the actual x and y values
+   $t_x_min = $self->{'curr_x_min'};
+   $t_x_max = $self->{'curr_x_max'};
+   $t_y_min = $self->{'curr_y_min'};
+   $t_y_max = $self->{'curr_y_max'};
+
+   #get back to the point, where everything began
+   $self->{'curr_x_min'} = 0;
+   $self->{'curr_y_min'} = 0;
+   $self->{'curr_x_max'} = $abs_x_max;
+   $self->{'curr_y_max'} = $abs_y_max-1;
+
+    # mark off the graph_border space
+   $self->{'curr_y_max'} -= 2* $self->{'graph_border'};
+
+   #draw the bottom legend again
+   if ($self->{'legend'} =~ /^bottom$/i) {
+    $self->_draw_bottom_legend;
+   }
+
+   #draw the x label again
+   if ($self->{'x_label'}) {
+    $self->_draw_x_label;
+   }
+
+   #get back to the start point for the ticks
+   $self->{'curr_x_min'} = $self->{'temp_x_min'};
+   $self->{'curr_y_min'} = $self->{'temp_y_min'};
+   $self->{'curr_x_max'} = $self->{'temp_x_max'};
+   $self->{'curr_y_max'} = $self->{'temp_y_max'};
+
+   #draw the x ticks again
+   $self->_draw_x_ticks;
+
+   #reset the actual values
+   $self->{'curr_x_min'} = $t_x_min;
+   $self->{'curr_x_max'} = $t_x_max;
+   $self->{'curr_y_min'} = $t_y_min;
+   $self->{'curr_y_max'} = $t_y_max;
+  }
+
+  return;
+
+}
+
+
+##  set the gdBrush object to trick GD into drawing fat lines
+sub _prepare_brush {
+  my $self  = shift;
+  my $color = shift;
+  my $type  = shift;
+  my ($radius, @rgb, $brush, $white, $newcolor);
+
+  # get the rgb values for the desired color
+  @rgb = $self->{'gd_obj'}->rgb($color);
+
+  # get the appropriate brush size
+  if ($type eq 'line') {
+    $radius = $self->{'brush_size'}/2;
+  }
+  elsif ($type eq 'point') {
+    $radius = $self->{'pt_size'}/2;
+  }
+
+  # create the new image
+  $brush = GD::Image->new ($radius*2, $radius*2);
+
+  # get the colors, make the background transparent
+  $white = $brush->colorAllocate (255,255,255);
+  $newcolor = $brush->colorAllocate (@rgb);
+  $brush->transparent ($white);
+
+  # draw the circle
+  $brush->arc ($radius-1, $radius-1, $radius, $radius, 0, 360, $newcolor);
+
+  # fill it if we're using lines
+  $brush->fill ($radius-1, $radius-1, $newcolor);
+
+  # set the new image as the main object's brush
+  return $brush;
+}
+
+## be a good module and return 1
+1;

Added: packages/libchart-perl/branches/upstream/current/Chart/Mountain.pm
===================================================================
--- packages/libchart-perl/branches/upstream/current/Chart/Mountain.pm	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/Chart/Mountain.pm	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,269 @@
+#====================================================================
+# 
+#  Chart::Mountain
+# 
+#  Inspired by Chart::Lines
+#  by davidb bonner 
+#  dbonner at cs.bu.edu
+# 
+#  Updated for 
+#  compatibility with 
+#  changes to Chart::Base
+#  by peter clark
+#  ninjaz at webexpress.com
+#
+# Copyright 1998, 1999 by James F. Miner.
+# All rights reserved. 
+# This program is free software; you can redistribute it 
+# and/or modify it under the same terms as Perl itself. 
+#
+#  maintained by the Chart Group
+#  Chart at wettzell.ifag.de
+#
+#---------------------------------------------------------------------
+# History:
+#----------
+# $RCSfile: Mountain.pm,v $ $Revision: 1.4 $ $Date: 2003/02/14 14:16:23 $
+# $Author: dassing $
+# $Log: Mountain.pm,v $
+# Revision 1.4  2003/02/14 14:16:23  dassing
+# First setup to cvs
+#
+#
+#====================================================================
+
+package Chart::Mountain;
+
+use Chart::Base '2.4.1';
+use GD;
+use Carp;
+use strict;
+
+ at Chart::Mountain::ISA = qw ( Chart::Base );
+$Chart::Mountain::VERSION = '2.4.1';
+
+
+##  Some Mountain chart details:
+#
+#   The effective y data value for a given x point and dataset
+#   is the sum of the actual y data values of that dataset and 
+#   all datasets "below" it (i.e., with higher dataset indexes).
+# 
+#   If the y data value in any dataset is undef or negative for 
+#   a given x, then all datasets are treated as missing for that x.
+#   
+#   The y minimum is always forced to zero.
+# 
+#   To avoid a dataset area "cutting into" the area of the dataset below
+#   it, the y pixel for each dataset point will never be below the y pixel for
+#   the same point in the dataset below the dataset.
+
+#   This probably should have a custom legend method, because each 
+#   dataset is identified by the fill color (and optional pattern)
+#   of its area, not just a line color.  So the legend shou a square
+#   of the color and pattern for each dataset.
+
+#===================#
+#  private methods  #
+#===================#
+
+sub _find_y_range {
+    my $self = shift;
+    
+    #   This finds the maximum point-sum over all x points,
+    #   where the point-sum is the sum of the dataset values at that point.
+    #   If the y value in any dataset is undef for a given x, then all datasets
+    #   are treated as missing for that x.
+    
+    my $data = $self->{'dataref'};
+    my $max = undef;
+    for my $i (0..$#{$data->[0]}) {
+	my $y_sum = $data->[1]->[$i];
+	if ( defined $y_sum && $y_sum >= 0 ) {
+	    for my $dataset ( @$data[2..$#$data] ) { # order not important
+		my $datum = $dataset->[$i];
+		if ( defined $datum && $datum >= 0 ) { 
+		    $y_sum += $datum 
+		}
+		else { # undef or negative, treat all at same x as missing.
+		    $y_sum = undef;  
+		    last 
+		}
+	    }
+	}
+	if ( defined $y_sum ) {
+	    $max = $y_sum unless defined $max && $y_sum <= $max;
+	}
+    }
+
+    (0, $max);
+}
+
+
+sub _draw_data {
+    my $self = shift;
+    my $data = $self->{'dataref'};
+    
+    my @patterns = @{ $self->{'patterns'} || [] };
+    
+    # Calculate array of x pixel positions (@x).
+    my $x_step = ($self->{'curr_x_max'} - $self->{'curr_x_min'}) / ($self->{'num_datapoints'} > 0 ? $self->{'num_datapoints'} : 1);
+    my $x_min = $self->{'curr_x_min'} + $x_step / 2;
+    my $x_max = $self->{'curr_x_max'} - $x_step / 2;
+    my @x = map { $_ * $x_step + $x_min } 0..$self->{'num_datapoints'}-1;
+    my ($t_x_min, $t_x_max, $t_y_min, $t_y_max, $abs_x_max, $abs_y_max);
+    my $repair_top_flag = 0;
+    # Calculate array of y pixel positions for upper boundary each dataset (@y).
+    
+    my $map = ($self->{'max_val'})
+		? ($self->{'curr_y_max'} - $self->{'curr_y_min'}) / $self->{'max_val'}
+		: ($self->{'curr_y_max'} - $self->{'curr_y_min'}) / 10;
+
+    my $y_max = $self->{'curr_y_max'}; # max pixel point (lower y values)
+    
+    my @y;
+    for my $j (0..$#{$data->[0]}) {
+	my $sum = 0;
+	for my $i (reverse 1..$#{$data}) { # bottom to top of chart
+	    my $datum = $data->[$i][$j];
+
+            #set the repair flag, if the datum is out of the borders of the chart
+            if ( defined $datum && $datum > $self->{'max_val'}) { $repair_top_flag = 1;}
+            
+            
+            if ( defined $datum && $datum >= 0 ) {
+		$sum += $datum;
+		$y[$i-1][$j] = $y_max - $map * $sum;
+	    }
+	    else { # missing value, force all to undefined
+		foreach my $k (1..$#{$data}) { $y[$k-1][$j] = undef }
+		last;
+	    }
+	}
+    }
+    
+    # Find first and last x where y is defined in the bottom dataset.
+    my $x_begin = 0;
+    my $x_end = $self->{'num_datapoints'}-1;
+    while ( $x_begin <= $x_end && ! defined $y[-1]->[$x_begin] ) { $x_begin++ }
+    while ( $x_begin <= $x_end && ! defined $y[-1]->[$x_end] ) { $x_end-- }
+   
+    if ( $x_begin > $x_end ) { croak "Internal error: x_begin > x_end ($x_begin > $x_end)"; }
+    
+    # For each dataset, generate a polygon for the dataset's area of the chart,
+    # and fill the polygon with the dataset's color/pattern.
+    
+    my $poly = GD::Polygon->new;
+    $poly->addPt($x[$x_end], $y_max); # right end of x axis
+    $poly->addPt($x[$x_begin], $y_max); # left end of x axis (right-to-left)
+    
+    for my $dataset (reverse 0.. at y-1) {
+	my $y_ref = $y[$dataset];
+    
+	# Append points for this dataset to polygon, direction depends on $dataset % 2.
+	my $last_vertex_count = $poly->length;
+	if ( (@y - 1 - $dataset) % 2 ) { # right-to-left
+	    for (reverse $x_begin..$x_end) { 
+		$poly->addPt($x[$_], $y_ref->[$_]) if defined $y_ref->[$_] 
+	    }
+	}
+	else { # left-to-right
+	    for ($x_begin..$x_end) { 
+		$poly->addPt($x[$_], $y_ref->[$_]) if defined $y_ref->[$_] 
+	    }
+	}
+		
+	# draw the polygon
+	my $color = $self->_color_role_to_index('dataset'.$dataset);
+	if ( $patterns[$dataset] ) {
+	    $self->{'gd_obj'}->filledPolygon($poly, $color) if $patterns[$dataset]->transparent >= 0;
+	    $self->{'gd_obj'}->setTile($patterns[$dataset]);
+	    $self->{'gd_obj'}->filledPolygon($poly, gdTiled);
+	}
+	else {
+	    $self->{'gd_obj'}->filledPolygon($poly, $color);
+	}
+	
+	# delete previous dataset's points from the polygon, update $last_vertex_count.
+	unless ( $dataset == 0 ) { # don't bother do delete points after last area
+	    while ( $last_vertex_count ) { $poly->deletePt(0); $last_vertex_count-- }
+	}
+    }
+
+    # Enclose the plots
+    $self->{'gd_obj'}->rectangle(
+	$self->{'curr_x_min'}, $self->{'curr_y_min'},
+	$self->{'curr_x_max'}, $self->{'curr_y_max'},
+	$self->_color_role_to_index('misc')
+    );
+
+    #get the width and the heigth of the complete picture
+   ($abs_x_max, $abs_y_max) = $self->{'gd_obj'}->getBounds();
+
+    #repair the chart, if the lines are out of the borders of the chart
+    if ($repair_top_flag) {
+
+      #overwrite the ugly mistakes
+      $self->{'gd_obj'}->filledRectangle ($self->{'curr_x_min'}, 0,
+				$self->{'curr_x_max'}, $self->{'curr_y_min'}-1,
+				$self->_color_role_to_index('background'));
+
+      #save the actual x and y values
+      $t_x_min = $self->{'curr_x_min'};
+      $t_x_max = $self->{'curr_x_max'};
+      $t_y_min = $self->{'curr_y_min'};
+      $t_y_max = $self->{'curr_y_max'};
+
+
+      #get back to the point, where everything began
+      $self->{'curr_x_min'} = 0;
+      $self->{'curr_y_min'} = 0;
+      $self->{'curr_x_max'} = $abs_x_max;
+      $self->{'curr_y_max'} = $abs_y_max;
+
+      #draw the title again
+      if ($self->{'title'}) {
+        $self->_draw_title
+      }
+
+      #draw the sub title again
+      if ($self->{'sub_title'}) {
+        $self->_draw_sub_title
+      }
+
+      #draw the top legend again
+      if ($self->{'legend'} =~ /^top$/i) {
+         $self->_draw_top_legend;
+      }
+
+      #reset the actual values
+      $self->{'curr_x_min'} = $t_x_min;
+      $self->{'curr_x_max'} = $t_x_max;
+      $self->{'curr_y_min'} = $t_y_min;
+      $self->{'curr_y_max'} = $t_y_max;
+      }
+}    
+
+
+###############################################################
+
+### Fix a bug in GD::Polygon.  
+### A patch has been submitted to Lincoln Stein.
+
+require GD;
+unless ( defined &GD::Polygon::deletePt ) { 
+    *GD::Polygon::deletePt  = sub {
+	my($self,$index) = @_;
+	unless (($index >= 0) && ($index < @{$self->{'points'}})) {
+	    warn "Attempt to set an undefined polygon vertex";
+	    return undef;
+	}
+	my($vertex) = splice(@{$self->{'points'}},$index,1);
+	$self->{'length'}--;
+	return @$vertex;
+    }
+}
+
+###############################################################
+
+1;

Added: packages/libchart-perl/branches/upstream/current/Chart/Pareto.pm
===================================================================
--- packages/libchart-perl/branches/upstream/current/Chart/Pareto.pm	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/Chart/Pareto.pm	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,307 @@
+#====================================================================
+#  Chart::Pareto
+#
+#  written by Chart-Group
+#
+#  maintained by the Chart Group
+#  Chart at wettzell.ifag.de
+#
+#---------------------------------------------------------------------
+# History:
+#----------
+# $RCSfile: Pareto.pm,v $ $Revision: 1.2 $ $Date: 2003/02/14 14:18:33 $
+# $Author: dassing $
+# $Log: Pareto.pm,v $
+# Revision 1.2  2003/02/14 14:18:33  dassing
+# First setup to cvs
+#
+#====================================================================
+
+package Chart::Pareto;
+
+use Chart::Base '2.4.1';
+use GD;
+use Carp;
+use strict;
+
+ at Chart::Pareto::ISA = qw(Chart::Base);
+$Chart::Pareto::VERSION = '2.4.1';
+
+#>>>>>>>>>>>>>>>>>>>>>>>>>>#
+#  public methods go here  #
+#<<<<<<<<<<<<<<<<<<<<<<<<<<#
+
+
+
+#>>>>>>>>>>>>>>>>>>>>>>>>>>>#
+#  private methods go here  #
+#<<<<<<<<<<<<<<<<<<<<<<<<<<<#
+
+#calculate the range with the sum dataset1. all datas has to be positiv
+sub _find_y_range {
+  my $self = shift;
+  my $data = $self->{'dataref'};
+  my $sum = 0;
+
+  for ( my $i = 0; $i < $self->{'num_datapoints'} ; $i++) {
+    if ( $data->[1][$i] >= 0 ) {
+      $sum += $data->[1][$i];
+    }
+    else {
+      carp "We need positiv data, if we want to draw a pareto graph!!";
+      return 0;
+    }
+  }
+
+  #store the sum
+  $self->{'sum'} =  $sum;
+  #return the range
+  (0, $sum);
+}
+
+# sort the data
+sub _sort_data {
+   my $self = shift;
+   my $data = $self->{'dataref'};
+   my @labels = @{$data->[0]};
+   my @values = @{$data->[1]};
+
+   
+   # sort the values and their labels
+   @labels =  @labels [ sort {$values[$b] <=> $values[$a]} 0..$#labels];
+   @values = sort {$b <=> $a} @values;
+
+   #save the sorted values and their labels
+   @{$data->[0]} = @labels;
+   @{$data->[1]} = @values;
+   #finally return
+   return 1;
+}
+
+#  let them know what all the pretty colors mean
+sub _draw_legend {
+  my $self = shift;
+  my ($length);
+  my $num_dataset;
+  
+  # check to see if legend type is none..
+  if ($self->{'legend'} =~ /^none$/) {
+    return 1;
+  }
+  # check to see if they have as many labels as datasets,
+  # warn them if not
+  if (($#{$self->{'legend_labels'}} >= 0) &&
+       ((scalar(@{$self->{'legend_labels'}})) != 2)) {
+    carp "I need two legend labels. One for the data and one for the sum.";
+  }
+
+  # init a field to store the length of the longest legend label
+  unless ($self->{'max_legend_label'}) {
+    $self->{'max_legend_label'} = 0;
+  }
+
+  # fill in the legend labels, find the longest one
+  unless ($self->{'legend_labels'}[0]) {
+     $self->{'legend_labels'}[0] = "Dataset";
+  }
+  unless ($self->{'legend_labels'}[1]) {
+     $self->{'legend_labels'}[1] = "Running sum";
+  }
+
+  if (length($self->{'legend_labels'}[0]) >   length($self->{'legend_labels'}[1])) {
+      $self->{'max_legend_label'} = length($self->{'legend_labels'}[0]);
+  }
+  else {
+      $self->{'max_legend_label'} = length($self->{'legend_labels'}[1]);
+  }
+  
+  #set the number of datasets to 2, and store it
+  $num_dataset = $self->{'num_datasets'};
+  $self->{'num_datasets'} = 2;
+  
+  # different legend types
+  if ($self->{'legend'} eq 'bottom') {
+    $self->_draw_bottom_legend;
+  }
+  elsif ($self->{'legend'} eq 'right') {
+    $self->_draw_right_legend;
+  }
+  elsif ($self->{'legend'} eq 'left') {
+    $self->_draw_left_legend;
+  }
+  elsif ($self->{'legend'} eq 'top') {
+    $self->_draw_top_legend;
+  } else {
+    carp "I can't put a legend there (at ".$self->{'legend'}.")\n";
+  }
+
+  #reload the number of datasets
+  $self->{'num_datasets'} = $num_dataset;
+  
+  # and return
+  return 1;
+}
+
+
+## finally get around to plotting the data
+sub _draw_data {
+  my $self = shift;
+  my $data = $self->{'dataref'};
+  my $misccolor = $self->_color_role_to_index('misc');
+  my ($x1, $x2, $x3, $y1, $y2, $y3, $y1_line, $y2_line, $x1_line, $x2_line, $h, $w);
+  my ($width, $height, $delta1, $delta2, $map, $mod, $cut);
+  my ($i, $j, $color, $line_color, $percent, $per_label, $per_label_len);
+  my $sum = $self->{'sum'};
+  my $curr_sum = 0;
+  my $font = $self->{'legend_font'};
+  my $pink = $self->{'gd_obj'}->colorAllocate(255,0,255);
+  my $diff;
+  
+  # make sure we're using a real font
+  unless ((ref ($font)) eq 'GD::Font') {
+    croak "The subtitle font you specified isn\'t a GD Font object";
+  }
+
+  # get the size of the font
+  ($h, $w) = ($font->height, $font->width);
+
+  # init the imagemap data field if they wanted it
+  if ($self->{'imagemap'} =~ /^true$/i) {
+    $self->{'imagemap_data'} = [];
+  }
+
+  # find both delta values ($delta1 for stepping between different
+  # datapoint names, $delta2 for setpping between datasets for that
+  # point) and the mapping constant
+  $width = $self->{'curr_x_max'} - $self->{'curr_x_min'};
+  $height = $self->{'curr_y_max'} - $self->{'curr_y_min'};
+  $delta1 = $width / ( $self->{'num_datapoints'} > 0 ? $self->{'num_datapoints'} : 1);
+  $diff = ($self->{'max_val'} - $self->{'min_val'});
+  $diff = 1 if $diff == 0;
+  $map = $height / $diff;
+  if ($self->{'spaced_bars'} =~ /^true$/i) {
+    $delta2 = $delta1 / 3;
+  }
+  else {
+    $delta2 = $delta1 ;
+  }
+
+  # get the base x-y values
+  $x1 = $self->{'curr_x_min'};
+  $y1 = $self->{'curr_y_max'};
+  $y1_line = $y1;
+  $mod = $self->{'min_val'};
+  $x1_line = $self->{'curr_x_min'};
+
+  # draw the bars and the lines
+  $color = $self->_color_role_to_index('dataset0');
+  $line_color = $self->_color_role_to_index('dataset1');
+
+
+  # draw every bar for this dataset
+  for $j (0..$self->{'num_datapoints'}) {
+      # don't try to draw anything if there's no data
+      if (defined ($data->[1][$j])) {
+        #calculate the percent value for this data and the actual sum;
+        $curr_sum += $data->[1][$j];
+        $percent = int($curr_sum / ($sum || 1) * 100);
+
+        # find the bounds of the rectangle
+        if ($self->{'spaced_bars'} =~ /^true$/i) {
+          $x2 = $x1 + ($j * $delta1) + $delta2;
+	}
+	else {
+	  $x2 = $x1 + ($j * $delta1);
+	}
+	$y2 = $y1;
+	$x3 = $x2 + $delta2;
+	$y3 = $y1 - (($data->[1][$j] - $mod) * $map);
+
+        #cut the bars off, if needed
+        if ($data->[1][$j] > $self->{'max_val'}) {
+           $y3 = $y1 - (($self->{'max_val'} - $mod ) * $map) ;
+           $cut = 1;
+        }
+        elsif  ($data->[1][$j] < $self->{'min_val'}) {
+           $y3 = $y1 - (($self->{'min_val'} - $mod ) * $map) ;
+           $cut = 1;
+        }
+        else {
+           $cut = 0;
+        }
+        
+	# draw the bar
+	## y2 and y3 are reversed in some cases because GD's fill
+	## algorithm is lame
+        $self->{'gd_obj'}->filledRectangle ($x2, $y3, $x3, $y2, $color);
+        if ($self->{'imagemap'} =~ /^true$/i) {
+	    $self->{'imagemap_data'}->[1][$j] = [$x2, $y3, $x3, $y2];
+        }
+        # now outline it. outline red if the bar had been cut off
+        unless ($cut){
+	  $self->{'gd_obj'}->rectangle ($x2, $y3, $x3, $y2, $misccolor);
+        }
+        else {
+
+          $self->{'gd_obj'}->rectangle ($x2, $y3, $x3, $y2, $pink);
+        }
+        $x2_line = $x3;
+        if ( $self->{'max_val'} >= $curr_sum) {
+          #get the y value
+          $y2_line = $y1 - (($curr_sum - $mod) * $map);
+
+          #draw the line
+          $self->{'gd_obj'}->line ( $x1_line, $y1_line, $x2_line, $y2_line, $line_color);
+          #draw a little rectangle at the end of the line
+          $self->{'gd_obj'}->filledRectangle($x2_line-2, $y2_line-2, $x2_line+2, $y2_line+2, $line_color);
+
+          #draw the label for the percent value
+          $per_label = $percent.'%';
+          $per_label_len = length ($per_label) * $w;
+          $self->{'gd_obj'}-> string ($font, $x2_line - $per_label_len -1, $y2_line - $h -1,
+                                      $per_label, $line_color);
+
+          #update the values for next the line
+          $y1_line = $y2_line;
+          $x1_line = $x2_line;
+         }
+         else {
+          #get the y value
+          $y2_line = $y1 - (($self->{'max_val'} - $mod) * $map) ;
+          #draw the line
+          $self->{'gd_obj'}->line ( $x1_line, $y1_line, $x2_line, $y2_line, $pink);
+          #draw a little rectangle at the end of the line
+          $self->{'gd_obj'}->filledRectangle($x2_line-2, $y2_line-2, $x2_line+2, $y2_line+2, $pink);
+
+          #draw the label for the percent value
+          $per_label = $percent.'%';
+          $per_label_len = length ($per_label) * $w;
+          $self->{'gd_obj'}-> string ($font, $x2_line - $per_label_len -1, $y2_line - $h -1,
+                                  $per_label, $pink);
+
+          #update the values for the next line
+          $y1_line = $y2_line;
+          $x1_line = $x2_line;
+          }
+
+       }
+       else {
+	  if ($self->{'imagemap'} =~ /^true$/i) {
+            $self->{'imagemap_data'}->[1][$j] = [undef(), undef(), undef(), undef()];
+          }
+      }
+  }
+
+      
+  # and finaly box it off 
+  $self->{'gd_obj'}->rectangle ($self->{'curr_x_min'},
+  				$self->{'curr_y_min'},
+				$self->{'curr_x_max'},
+				$self->{'curr_y_max'},
+				$misccolor);
+  return;
+
+}
+
+## be a good module and return 1
+1;


Property changes on: packages/libchart-perl/branches/upstream/current/Chart/Pareto.pm
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/Chart/Pie.pm
===================================================================
--- packages/libchart-perl/branches/upstream/current/Chart/Pie.pm	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/Chart/Pie.pm	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,1027 @@
+#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>#
+#  Chart::Pie                    #
+#                                #
+#  written by Chart Group        #
+#                                #
+#  maintained by the Chart Group #
+#  Chart at wettzell.ifag.de        #
+#                                #
+#                                #
+#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<#
+
+package Chart::Pie;
+
+use Chart::Base '2.4.1';
+use GD;
+use Carp;
+use strict;
+
+ at Chart::Pie::ISA = qw(Chart::Base);
+$Chart::Pie::VERSION = '2.4.1';
+
+#>>>>>>>>>>>>>>>>>>>>>>>>>>#
+#  public methods go here  #
+#<<<<<<<<<<<<<<<<<<<<<<<<<<#
+
+
+
+#>>>>>>>>>>>>>>>>>>>>>>>>>>>#
+#  private methods go here  #
+#<<<<<<<<<<<<<<<<<<<<<<<<<<<#
+
+#Overwrite the legend methods to get the right legend
+sub _draw_right_legend {
+  my $self = shift;
+  my $data = $self->{'dataref'};
+  my @labels = @{$data->[0]};
+  my ($x1, $x2, $x3, $y1, $y2, $width, $color, $misccolor, $w, $h, $brush);
+  my $font = $self->{'legend_font'};
+  my $l1 = 0;
+  my $l2 =0;
+  my ($i, $j, $label, $dataset_sum);
+  my $max_label_len = 1;
+  
+  # make sure we're using a real font
+  unless ((ref ($font)) eq 'GD::Font') {
+    croak "The subtitle font you specified isn\'t a GD Font object";
+  }
+
+  # get the size of the font
+  ($h, $w) = ($font->height, $font->width);
+
+  # get the miscellaneous color
+  $misccolor = $self->_color_role_to_index('misc');
+
+  #find out what the sum of all datapoits is, needed for the Labels with percent
+    $dataset_sum = 0;
+    for my $j (0..$self->{'num_datapoints'}) 
+    {
+        if(defined $data->[1][$j])
+        {
+            $dataset_sum += $data->[1][$j];
+        }
+    }
+  
+    # find out how who wide the largest label text is
+    foreach (@labels) 
+    {
+        if ( length($_) > $l1) 
+        {
+            $l1 = length($_);
+        }
+    }
+    for (my $i =0 ; $i < ($self->{'num_datapoints'}) ; $i++) 
+    {
+        if ( length($data->[1][$i]) > $l2  ) 
+        {
+            $l2 = length($data->[1][$i]);
+        }
+    }
+  
+    if ($self->{'legend_label_values'} =~ /^value$/i ) 
+    {
+        $max_label_len = $l1 + $l2 +1;
+    }
+    elsif ($self->{'legend_label_values'} =~ /^percent$/i ) 
+    {
+        $max_label_len = $l1 +7;
+    }
+    elsif ($self->{'legend_label_values'} =~ /^both$/i ) 
+    {
+        $max_label_len = $l1 + $l2 +9;
+    }
+    else 
+    {
+        $max_label_len = $l1;
+    }
+
+    # find out how wide the largest label is
+    $width = (2 * $self->{'text_space'})
+    #+ ($self->{'max_legend_label'} * $w)
+    + $max_label_len *$w
+    + $self->{'legend_example_size'}
+    + (2 * $self->{'legend_space'});
+
+    # get some starting x-y values
+    $x1 = $self->{'curr_x_max'} - $width;
+    $x2 = $self->{'curr_x_max'};
+    $y1 = $self->{'curr_y_min'} + $self->{'graph_border'} ;
+    $y2 = $self->{'curr_y_min'} + $self->{'graph_border'} + $self->{'text_space'}
+          + ($self->{'num_datapoints'} * ($h + $self->{'text_space'}))
+	  + (2 * $self->{'legend_space'});
+
+    # box the legend off
+    $self->{'gd_obj'}->rectangle ($x1, $y1, $x2, $y2, $misccolor);
+
+    # leave that nice space inside the legend box
+    $x1 += $self->{'legend_space'};
+    $y1 += $self->{'legend_space'} + $self->{'text_space'};
+
+    # now draw the actual legend
+    for (0..$#labels) 
+    {
+        # get the color
+        $color = $self->_color_role_to_index('dataset'.$_);
+
+        # find the x-y coords
+        $x2 = $x1;
+        $x3 = $x2 + $self->{'legend_example_size'};
+        $y2 = $y1 + ($_ * ($self->{'text_space'} + $h)) + $h/2;
+
+        # do the line first
+        $self->{'gd_obj'}->line ($x2, $y2, $x3, $y2, $color);
+
+        # reset the brush for points
+        $brush = $self->_prepare_brush($color, 'point',
+	                    	$self->{'pointStyle' . $_});
+        $self->{'gd_obj'}->setBrush($brush);
+        # draw the point
+        $self->{'gd_obj'}->line(int(($x3+$x2)/2), $y2,
+				int(($x3+$x2)/2), $y2, gdBrushed);
+
+        # now the label
+        $x2 = $x3 + (2 * $self->{'text_space'});
+        $y2 -= $h/2;
+        if (defined $data->[1][$_]) 
+        {
+            if ( $self->{'legend_label_values'} =~ /^value$/i ) 
+            {
+                $self->{'gd_obj'}->string($font, $x2, $y2, $labels[$_].' '.$data->[1][$_], $color);
+            }
+            elsif ( $self->{'legend_label_values'} =~ /^percent$/i ) 
+            {
+                $label = sprintf("%s %4.2f%%",$labels[$_], $data->[1][$_] / ($dataset_sum || 1)* 100);
+                $self->{'gd_obj'}->string($font, $x2, $y2, $label, $color);
+            }
+            elsif ( $self->{'legend_label_values'} =~ /^both$/i ) 
+            {
+                if ( $data->[1][$_] =~ /\./ ) 
+                {
+                    $label = sprintf("%s %4.2f%% %.2f",$labels[$_], $data->[1][$_] / ($dataset_sum || 1) * 100, $data->[1][$_]);
+                }
+                else 
+                {
+                    $label = sprintf("%s %4.2f%% %d",$labels[$_], $data->[1][$_] / ($dataset_sum || 1)* 100, $data->[1][$_]);
+                }
+                $self->{'gd_obj'}->string($font, $x2, $y2, $label, $color);
+            }
+            else 
+            {
+                $self->{'gd_obj'}->string($font, $x2, $y2, $labels[$_], $color);
+            }
+
+        }
+    }
+
+    # mark off the used space
+    $self->{'curr_x_max'} -= $width;
+
+    # and return
+    return 1;
+}
+
+
+## put the legend on the left of the chart
+sub _draw_left_legend {
+  my $self = shift;
+  my $data = $self->{'dataref'};
+  my @labels = @{$data->[0]};
+  my ($x1, $x2, $x3, $y1, $y2, $width, $color, $misccolor, $w, $h, $brush);
+  my $font = $self->{'legend_font'};
+  my $max_label_len= 1;;
+  my $l1 = 0;
+  my $l2 = 0;
+  my ($dataset_sum, $label);
+  # make sure we're using a real font
+  unless ((ref ($font)) eq 'GD::Font') {
+    croak "The subtitle font you specified isn\'t a GD Font object";
+  }
+
+  # get the size of the font
+  ($h, $w) = ($font->height, $font->width);
+
+  # get the miscellaneous color
+  $misccolor = $self->_color_role_to_index('misc');
+
+  #find out what the sum of all datapoits is, needed for the Labels with percent
+  $dataset_sum = 0;
+  for my $j (0..$self->{'num_datapoints'}) {
+     if(defined $data->[1][$j]) {
+       $dataset_sum += $data->[1][$j];
+     }
+  }
+
+  # find out how who wide the largest label text is
+  foreach (@labels) {
+   if ( length($_) > $l1) {
+     $l1 = length($_);
+   }
+  }
+  for (my $i =0 ; $i < ($self->{'num_datapoints'}) ; $i++) {
+   if ( length($data->[1][$i]) > $l2 ) {
+      $l2 = length($data->[1][$i]);
+   }
+  }
+
+  if ($self->{'legend_label_values'} =~ /^value$/i ) {
+    $max_label_len = $l1 + $l2 +1;
+  }
+  elsif ($self->{'legend_label_values'} =~ /^percent$/i ) {
+    $max_label_len = $l1 +7;
+  }
+  elsif ($self->{'legend_label_values'} =~ /^both$/i ) {
+    $max_label_len = $l1 + $l2 +9;
+  }
+  else {
+    $max_label_len = $l1;
+  }
+
+  # find out how wide the largest label is
+  $width = (2 * $self->{'text_space'})
+    + ($max_label_len * $w)
+    + $self->{'legend_example_size'}
+    + (2 * $self->{'legend_space'});
+
+  # get some base x-y coordinates
+  $x1 = $self->{'curr_x_min'};
+  $x2 = $self->{'curr_x_min'} + $width;
+  $y1 = $self->{'curr_y_min'} + $self->{'graph_border'} ;
+  $y2 = $self->{'curr_y_min'} + $self->{'graph_border'} + $self->{'text_space'}
+          + ($self->{'num_datapoints'} * ($h + $self->{'text_space'}))
+	  + (2 * $self->{'legend_space'});
+
+  # box the legend off
+  $self->{'gd_obj'}->rectangle ($x1, $y1, $x2, $y2, $misccolor);
+
+  # leave that nice space inside the legend box
+  $x1 += $self->{'legend_space'};
+  $y1 += $self->{'legend_space'} + $self->{'text_space'};
+
+  # now draw the actual legend
+  for (0..$#labels) {
+    # get the color
+    $color = $self->_color_role_to_index('dataset'.$_);
+
+    # find the x-y coords
+    $x2 = $x1;
+    $x3 = $x2 + $self->{'legend_example_size'};
+    $y2 = $y1 + ($_ * ($self->{'text_space'} + $h)) + $h/2;
+
+    # do the line first
+    $self->{'gd_obj'}->line ($x2, $y2, $x3, $y2, $color);
+
+    # reset the brush for points
+    $brush = $self->_prepare_brush($color, 'point',
+				$self->{'pointStyle' . $_});
+    $self->{'gd_obj'}->setBrush($brush);
+    # draw the point
+    $self->{'gd_obj'}->line(int(($x3+$x2)/2), $y2,
+				int(($x3+$x2)/2), $y2, gdBrushed);
+
+    # now the label
+    $x2 = $x3 + (2 * $self->{'text_space'});
+    $y2 -= $h/2;
+    if ( $self->{'legend_label_values'} =~ /^value$/i ) {
+        $self->{'gd_obj'}->string($font, $x2, $y2, $labels[$_].' '.$data->[1][$_], $color);
+    }
+    elsif ( $self->{'legend_label_values'} =~ /^percent$/i ) {
+        $label = sprintf("%s %4.2f%%",$labels[$_], $data->[1][$_] / ($dataset_sum || 1) * 100);
+        $self->{'gd_obj'}->string($font, $x2, $y2, $label, $color);
+    }
+    elsif ( $self->{'legend_label_values'} =~ /^both$/i ) {
+        if ($data->[1][$_] =~ /\./) {
+           $label = sprintf("%s %4.2f%% %.2f",$labels[$_], $data->[1][$_] / ($dataset_sum || 1) * 100, $data->[1][$_]);
+        }
+        else {
+           $label = sprintf("%s %4.2f%% %d",$labels[$_], $data->[1][$_] / ($dataset_sum || 1)* 100, $data->[1][$_]);
+        }
+        $self->{'gd_obj'}->string($font, $x2, $y2, $label, $color);
+    }
+    else {
+        $self->{'gd_obj'}->string($font, $x2, $y2, $labels[$_], $color);
+    }
+
+  }
+
+  # mark off the used space
+  $self->{'curr_x_min'} += $width;
+
+  # and return
+  return 1;
+}
+
+
+## put the legend on the bottom of the chart
+sub _draw_bottom_legend {
+  my $self = shift;
+  my $data = $self->{'dataref'};
+  my @labels =@{$data->[0]};
+  my ($x1, $y1, $x2, $x3, $y2, $empty_width, $max_label_width, $cols, $rows, $color, $brush);
+  my ($col_width, $row_height, $r, $c, $index, $x, $y, $w, $h);
+  my $font = $self->{'legend_font'};
+  my $max_label_len;
+  my $l1 = 0;
+  my $l2 = 0;
+  my ($dataset_sum, $j);
+  my $label;
+  # make sure we're using a real font
+  unless ((ref ($font)) eq 'GD::Font') {
+    croak "The subtitle font you specified isn\'t a GD Font object";
+  }
+
+  # get the size of the font
+  ($h, $w) = ($font->height, $font->width);
+
+  # find the base x values
+  $x1 = $self->{'curr_x_min'} + $self->{'graph_border'}  ;
+         # + ($self->{'y_tick_label_length'} * $self->{'tick_label_font'}->width)
+	 # + $self->{'tick_len'} + (3 * $self->{'text_space'});
+  $x2 = $self->{'curr_x_max'} - $self->{'graph_border'};
+  if ($self->{'y_label'}) {
+    $x1 += $self->{'label_font'}->height + 2 * $self->{'text_space'};
+  }
+  if ($self->{'y_label2'}) {
+    $x2 -= $self->{'label_font'}->height + 2 * $self->{'text_space'};
+  }
+
+    #find out what the sum of all datapoits is, needed for the Labels with percent
+    $dataset_sum = 0;
+    for $j (0..$self->{'num_datapoints'}) 
+    {
+        if(defined $data->[1][$j])
+        {       
+            $dataset_sum += $data->[1][$j];
+        }
+    }
+
+    # find out how who wide the largest label text is, especially look what kind of
+    # label is needed
+    foreach (@labels) 
+    {
+        if ( length($_) > $l1) 
+        {
+            $l1 = length($_);
+        }
+    }
+    for (my $i =0 ; $i < ($self->{'num_datapoints'}) ; $i++) 
+    {
+        if ( length($data->[1][$i]) > $l2  ) 
+        {
+            $l2 = length($data->[1][$i]);
+        }
+    }
+
+
+    if ($self->{'legend_label_values'} =~ /^value$/i ) 
+    {
+        $max_label_len = $l1 + $l2 +1;
+    }
+    elsif ($self->{'legend_label_values'} =~ /^percent$/i ) 
+    {
+        $max_label_len = $l1 +7;
+    }
+    elsif ($self->{'legend_label_values'} =~ /^both$/i ) 
+    {
+        $max_label_len = $l1 + $l2 +9;
+    }
+    else 
+    {
+        $max_label_len = $l1;
+    }
+  
+    # figure out how wide the columns need to be, and how many we
+    # can fit in the space available
+    $empty_width = ($x2 - $x1) - (2 * $self->{'legend_space'});
+    $max_label_width = $max_label_len * $w
+    #$self->{'max_legend_label'} * $w
+    + (4 * $self->{'text_space'}) + $self->{'legend_example_size'};
+  $cols = int ($empty_width / $max_label_width);
+  unless ($cols) {
+    $cols = 1;
+  }
+  $col_width = $empty_width / $cols;
+
+  # figure out how many rows we need, remember how tall they are
+  $rows = int ($self->{'num_datapoints'} / $cols);
+  unless (($self->{'num_datapoints'} % $cols) == 0) {
+    $rows++;
+  }
+  unless ($rows) {
+    $rows = 1;
+  }
+  $row_height = $h + $self->{'text_space'};
+
+  # box the legend off
+  $y1 = $self->{'curr_y_max'} - $self->{'text_space'}
+          - ($rows * $row_height) - (2 * $self->{'legend_space'});
+  $y2 = $self->{'curr_y_max'};
+  $self->{'gd_obj'}->rectangle($x1, $y1, $x2, $y2,
+                               $self->_color_role_to_index('misc'));
+  $x1 += $self->{'legend_space'} + $self->{'text_space'};
+  $x2 -= $self->{'legend_space'};
+  $y1 += $self->{'legend_space'} + $self->{'text_space'};
+  $y2 -= $self->{'legend_space'} + $self->{'text_space'};
+
+  # draw in the actual legend
+  for $r (0..$rows-1) {
+    for $c (0..$cols-1) {
+      $index = ($r * $cols) + $c;  # find the index in the label array
+      if ($labels[$index]) {
+	# get the color
+        $color = $self->_color_role_to_index('dataset'.$index);
+
+        # get the x-y coordinate for the start of the example line
+	$x = $x1 + ($col_width * $c);
+        $y = $y1 + ($row_height * $r) + $h/2;
+
+	# now draw the example line
+        $self->{'gd_obj'}->line($x, $y,
+                                $x + $self->{'legend_example_size'}, $y,
+                                $color);
+
+        # reset the brush for points
+        $brush = $self->_prepare_brush($color, 'point',
+				$self->{'pointStyle' . $index});
+        $self->{'gd_obj'}->setBrush($brush);
+        # draw the point
+        $x3 = int($x + $self->{'legend_example_size'}/2);
+        $self->{'gd_obj'}->line($x3, $y, $x3, $y, gdBrushed);
+
+        # adjust the x-y coordinates for the start of the label
+	$x += $self->{'legend_example_size'} + (2 * $self->{'text_space'});
+        $y = $y1 + ($row_height * $r);
+
+	# now draw the label
+        if ( $self->{'legend_label_values'} =~ /^value$/i ) {
+           $self->{'gd_obj'}->string($font, $x, $y, $labels[$index].' '.$data->[1][$index], $color);
+	 #$self->{'gd_obj'}->stringTTF($color, FONT, 10, 0, $x, $y+10, $labels[$index].' '.$data->[1][$index]);     ############
+        }
+        elsif ( $self->{'legend_label_values'} =~ /^percent$/i ) {
+           $label = sprintf("%s %4.2f%%",$labels[$index], $data->[1][$index] / ($dataset_sum || 1)* 100);
+           $self->{'gd_obj'}->string($font, $x, $y, $label, $color);
+        }
+        elsif ( $self->{'legend_label_values'} =~ /^both$/i ) {
+           if ($data->[1][$index] =~ /\./) {
+              $label = sprintf("%s %4.2f%% %.2f",$labels[$index], $data->[1][$index] / ($dataset_sum || 1) * 100, $data->[1][$index]);
+           }
+           else {
+              $label = sprintf("%s %4.2f%% %d",$labels[$index], $data->[1][$index] / ($dataset_sum || 1) * 100, $data->[1][$index]);
+           }
+            $self->{'gd_obj'}->string($font, $x, $y, $label, $color); ###
+	   # $self->{'gd_obj'}->stringTTF($color, FONT, 10, 0, $x, $y, $label);
+  
+        }
+        else {
+           $self->{'gd_obj'}->string($font, $x, $y, $labels[$index], $color);
+        }
+      }
+    }
+  }
+
+  # mark off the space used
+  $self->{'curr_y_max'} -= ($rows * $row_height) + $self->{'text_space'}
+			      + (2 * $self->{'legend_space'});
+
+  # now return
+  return 1;
+}
+
+
+## put the legend on top of the chart
+sub _draw_top_legend {
+  my $self = shift;
+  my $data = $self->{'dataref'};
+  my ($max_label_len);
+  my $l1 = 0;
+  my $l2 = 0;
+  my @labels = @{$data->[0]};
+  my ($x1, $y1, $x2, $x3, $y2, $empty_width, $max_label_width, $cols, $rows, $color, $brush);
+  my ($col_width, $row_height, $r, $c, $index, $x, $y, $w, $h, $dataset_sum, $label);
+  my $font = $self->{'legend_font'};
+
+  # make sure we're using a real font
+  unless ((ref ($font)) eq 'GD::Font') {
+    croak "The subtitle font you specified isn\'t a GD Font object";
+  }
+
+  # get the size of the font
+  ($h, $w) = ($font->height, $font->width);
+
+    #find out what the sum of all datapoits is, needed for the Labels with percent
+    $dataset_sum = 0;
+    for my $j (0..$self->{'num_datapoints'}) 
+    {
+        if(defined $data->[1][$j])
+        {
+           $dataset_sum += $data->[1][$j];
+        }
+    }
+     
+    # get some base x coordinates
+    $x1 = $self->{'curr_x_min'}
+          + $self->{'graph_border'};
+         # + $self->{'y_tick_label_length'} * $self->{'tick_label_font'}->width
+	 # + $self->{'tick_len'} + (3 * $self->{'text_space'});
+    $x2 = $self->{'curr_x_max'} - $self->{'graph_border'};
+    if ($self->{'y_label'}) 
+    {
+        $x1 += $self->{'label_font'}->height + 2 * $self->{'text_space'};
+    }
+    if ($self->{'y_label2'}) 
+    {
+        $x2 -= $self->{'label_font'}->height + 2 * $self->{'text_space'};
+    }
+
+    # find out how who wide the largest label text is
+    foreach (@labels) 
+    {
+        if ( length($_) > $l1) 
+        {
+            $l1 = length($_);
+        }
+    }
+    for (my $i =0 ; $i < ($self->{'num_datapoints'}) ; $i++) 
+    {
+        if ( length($data->[1][$i]) > $l2  ) 
+        {
+            $l2 = length($data->[1][$i]);
+        }
+    }
+
+    if ($self->{'legend_label_values'} =~ /^value$/i ) 
+    {
+        $max_label_len = $l1 + $l2 +1;
+    }
+    elsif ($self->{'legend_label_values'} =~ /^percent$/i ) 
+    {
+        $max_label_len = $l1 +7;
+    }
+    elsif ($self->{'legend_label_values'} =~ /^both$/i ) 
+    {
+        $max_label_len = $l1 + $l2 +9;
+    }
+    else 
+    {
+        $max_label_len = $l1;
+    }
+
+    # figure out how wide the columns can be, and how many will fit
+    $empty_width = ($x2 - $x1) - (2 * $self->{'legend_space'});
+    $max_label_width = (4 * $self->{'text_space'})
+    # + ($self->{'max_legend_label'} * $w)
+    + $max_label_len * $w
+    + $self->{'legend_example_size'};
+    $cols = int ($empty_width / $max_label_width);
+    
+    unless ($cols) 
+    {
+        $cols = 1;
+    }
+    $col_width = $empty_width / $cols;
+
+    # figure out how many rows we need and remember how tall they are
+    $rows = int ($self->{'num_datapoints'} / $cols);
+    unless (($self->{'num_datapoints'} % $cols) == 0) 
+    {
+        $rows++;
+    }
+    unless ($rows) 
+    {
+        $rows = 1;
+    }
+    $row_height = $h + $self->{'text_space'};
+
+    # box the legend off
+    $y1 = $self->{'curr_y_min'};
+    $y2 = $self->{'curr_y_min'} + $self->{'text_space'}
+          + ($rows * $row_height) + (2 * $self->{'legend_space'});
+    $self->{'gd_obj'}->rectangle($x1, $y1, $x2, $y2,
+                               $self->_color_role_to_index('misc'));
+
+    # leave some space inside the legend
+    $x1 += $self->{'legend_space'} + $self->{'text_space'};
+    $x2 -= $self->{'legend_space'};
+    $y1 += $self->{'legend_space'} + $self->{'text_space'};
+    $y2 -= $self->{'legend_space'} + $self->{'text_space'};
+
+    # draw in the actual legend
+    for $r (0..$rows-1) 
+    {
+        for $c (0..$cols-1) 
+        {
+            $index = ($r * $cols) + $c;  # find the index in the label array
+            if ($labels[$index]) 
+            {
+	        # get the color
+                $color = $self->_color_role_to_index('dataset'.$index);
+
+	        # find the x-y coords
+	        $x = $x1 + ($col_width * $c);
+                $y = $y1 + ($row_height * $r) + $h/2;
+
+	        # draw the line first
+                $self->{'gd_obj'}->line($x, $y,
+                                $x + $self->{'legend_example_size'}, $y,
+                                $color);
+
+                # reset the brush for points
+                $brush = $self->_prepare_brush($color, 'point',
+				$self->{'pointStyle' . $index});
+                $self->{'gd_obj'}->setBrush($brush);
+        
+                # draw the point
+                $x3 = int($x + $self->{'legend_example_size'}/2);
+                $self->{'gd_obj'}->line($x3, $y, $x3, $y, gdBrushed);
+
+                # now the label
+	        $x += $self->{'legend_example_size'} + (2 * $self->{'text_space'});
+	        $y -= $h/2;
+                if ( $self->{'legend_label_values'} =~ /^value$/i ) 
+                {
+                    $self->{'gd_obj'}->string($font, $x, $y, $labels[$index].' '.$data->[1][$index], $color);
+                }
+                elsif ( $self->{'legend_label_values'} =~ /^percent$/i ) 
+                {
+                    $label = sprintf("%s %4.2f%%",$labels[$index], $data->[1][$index] / ($dataset_sum || 1) * 100);
+                    $self->{'gd_obj'}->string($font, $x, $y, $label, $color);
+                }
+                elsif ( $self->{'legend_label_values'} =~ /^both$/i ) 
+                {
+                    if ( $data->[1][$index] =~ /\./) 
+                    {
+                        $label = sprintf("%s %4.2f%% %.2f",$labels[$index], $data->[1][$index] / ($dataset_sum || 1) * 100, $data->[1][$index]);
+                    }
+                    else 
+                    {
+                        $label = sprintf("%s %4.2f%% %d",$labels[$index], $data->[1][$index] / ($dataset_sum || 1) * 100, $data->[1][$index]);
+                    }
+                    $self->{'gd_obj'}->string($font, $x, $y, $label, $color);
+                }
+                else 
+                {
+                    $self->{'gd_obj'}->string($font, $x, $y, $labels[$index], $color);
+                }
+            }
+        }
+    }
+
+    # mark off the space used
+    $self->{'curr_y_min'} += ($rows * $row_height) + $self->{'text_space'}
+			      + 2 * $self->{'legend_space'};
+
+    # now return
+    return 1;
+}
+
+# Override the ticks methods for the pie charts
+# as they do not always make sense.
+sub _draw_x_ticks {
+  my $self = shift;
+
+  return;
+}
+sub _draw_y_ticks {
+  my $self = shift;
+
+  return;
+}
+
+sub _find_y_scale {
+  my $self = shift;
+
+  return;
+}
+
+
+
+## finally get around to plotting the data
+sub _draw_data {
+    my $self = shift;
+    my $data = $self->{'dataref'};
+    my $misccolor = $self->_color_role_to_index('misc');
+    my $textcolor = $self->_color_role_to_index('text');
+    my $background = $self->_color_role_to_index('background');
+    my ($width, $height, $centerX, $centerY, $diameter, $text_diameter);
+    my $dataset_sum;
+    my ($start_degrees, $end_degrees, $label_degrees, $labelY_repeat_count);
+    my $max_label_len;
+    my ($pi, $rd2dg, $dg2rd); 
+    my ($font, $fontW, $fontH, $labelX, $labelY);
+    my $label;
+    my ($i, $j, $color);
+    my $label_length; 
+    my $degrees=0;
+    my $insidecolor;
+    my $forbidden_degrees = 0;   # last occupied degree
+    my %labelinfo;              
+ 
+    # set up initial constant values
+    $pi = 3.14159265;
+    $dg2rd = $pi/180;   # Degree to Radians
+    $rd2dg = 180/$pi;   # Radian to Degree
+    $start_degrees=0;
+    $end_degrees=0;
+    $font = $self->{'legend_font'};
+    $fontW = $self->{'legend_font'}->width;
+    $fontH = $self->{'legend_font'}->height;
+    $label_degrees = $labelY_repeat_count = 0;
+  
+
+    # init the imagemap data field if they wanted it
+    if ($self->{'imagemap'} =~ /^true$/i) 
+    {
+        $self->{'imagemap_data'} = [];
+    }
+
+    # find width and height
+    $width = $self->{'curr_x_max'} - $self->{'curr_x_min'};
+    $height = $self->{'curr_y_max'} - $self->{'curr_y_min'};
+
+ 
+    # okay, add up all the numbers of all the datasets, to get the
+    # sum total. This will be used to determine the percentage 
+    # of each dataset. Obviously, negative numbers might be bad :)
+    $dataset_sum = 0;
+    for $j (0..$self->{'num_datapoints'}) 
+    {
+    
+        if(defined $data->[1][$j])
+        {  
+            #add to sum
+            $dataset_sum += $data->[1][$j];
+            #don't allow negativ values
+            if ($data->[1][$j] < 0) 
+            {
+                croak "We need positiv data for a pie chart (which is not true for data[$j])!";
+            }
+        }
+    }
+   
+    # find the longest label
+    # first we need the length of the values
+    $max_label_len = 1;
+    for $j (0..($self->{'num_datapoints'}-1)) 
+    {
+        # don't try to draw anything if there's no data
+        $labelinfo{$j}{data} = 'undefined';
+        if (defined ($data->[1][$j])) 
+        {
+            $labelinfo{$j}{data} = $data->[1][$j];
+            $label = $data->[0][$j];
+            $labelinfo{$j}{labeldata} = $label;
+            
+            if( defined $self->{'label_values'})  
+            {
+                if($self->{'label_values'} =~ /^percent$/i)
+                {
+                    $label = sprintf("%s %4.2f%%",$label, $data->[1][$j] / ($dataset_sum || 1)  * 100);
+                }
+                elsif($self->{'label_values'} =~ /^value$/i)
+                {
+                    if ($data->[1][$j] =~ /\./) 
+                    {
+                        $label = sprintf("%s %.2f",$label, $data->[1][$j]);
+                    }
+                    else 
+                    {
+                        $label = sprintf("%s %d",$label,$data->[1][$j]);
+                    }
+                }
+                elsif ($self->{'label_values'} =~ /^both$/i)
+                {
+                    if ($data->[1][$j] =~ /\./) 
+                    {
+                        $label = sprintf("%s %4.2f%% %.2f",$label,
+                                          $data->[1][$j] / ($dataset_sum || 1)* 100,
+                                          $data->[1][$j]);
+                    }
+                    else 
+                    {
+                        $label = sprintf("%s %4.2f%% %d",$label,
+                                          $data->[1][$j] / ($dataset_sum || 1) * 100,
+                                          $data->[1][$j]);
+                    }
+                }
+                elsif($self->{'label_values'} =~ /^none$/i)
+                {
+                    $label = sprintf("%s",$label);
+                }
+            }
+	    $label_length = length($label);
+	    $labelinfo{$j}{labelstring} = $label,
+            $labelinfo{$j}{labellength} = $label_length;
+         
+       }
+       $max_label_len = $label_length if ( $max_label_len < $label_length );
+    }
+    $max_label_len *= $fontW;
+
+    # find center point, from which the pie will be drawn around
+    $centerX = int($width/2)  + $self->{'curr_x_min'};
+    $centerY = int($height/2) + $self->{'curr_y_min'};
+
+    # always draw a circle, which means the diameter will be the smaller
+    # of the width and height. let enougth space for the labels
+  
+    my $labeldistance = 2*$self->maximum($fontW,$fontH);
+    $diameter = $self->minimum($width,$height) - 2*$max_label_len - $labeldistance;
+
+    # make sure, that we have a positive diameter
+    if ($diameter < 0) 
+    {
+        croak "I have calculated a negative diameter for the pie chart, maybe your labels are too long or the picture is too small.";
+    }
+  
+    $text_diameter = $diameter + $labeldistance;			       
+    $self->{'gd_obj'}->arc($centerX, $centerY, $diameter, $diameter,
+                               0, 360, $misccolor);
+    # for DEBUG!!
+    #$self->{'gd_obj'}->arc($centerX, $centerY, $text_diameter, $text_diameter,
+    #                           0, 360, $misccolor);
+
+    for $j (0..($self->{'num_datapoints'}-1)) 
+    {
+        #next if $labelinfo{$j}{data} eq 'undefined';
+        # get the color for this datapoint, take the color of the datasets
+        $color = $self->_color_role_to_index('dataset'.$j);
+   
+        $label = $labelinfo{$j}{labelstring};
+        $label_length = $labelinfo{$j}{labellength};
+
+        # The first value starts at 0 degrees, each additional dataset
+        # stops where the previous left off, and since I've already 
+        # calculated the sum_total for the whole graph, I know that
+        # the final pie slice will end at 360 degrees.
+
+        # So, get the degree offset for this dataset
+        $end_degrees = $start_degrees + ($data->[1][$j] / ($dataset_sum || 1)  * 360);
+    
+        $degrees = $start_degrees+($end_degrees-$start_degrees)/2;
+  
+        # stick the label in the middle of the slice
+        $label_degrees = ($start_degrees + $end_degrees) / 2;
+
+        # The following drawings are in a very specific ordering, and are not
+        # intuitive as to why they are being done this way, but it is basically
+        # because the GD module doesn't provide a filledArc() method. So, I
+        # developed my own, below.
+ 
+        # First, draw an arc, in black, from the starting offset, all the 
+        # way to 360 degrees.
+        $self->{'gd_obj'}->arc($centerX,$centerY,
+                                $diameter, $diameter,
+                                $start_degrees, 360,
+                                $misccolor);
+
+        # This is tricky, but draw a short line in the desired color, along the
+        # path that will be the end of this pie slice of data. But, make sure not
+        # to extend this line to intersect with the boundary of the arc. This
+        # is crucial.
+        if ( $start_degrees != $end_degrees )
+        {
+            $self->{'gd_obj'}->line($centerX, $centerY,
+                                    $centerX + .4*$diameter*cos($end_degrees*$dg2rd),
+                                    $centerY + .4*$diameter*sin($end_degrees*$dg2rd),
+                                    $color);
+            # Draw the radius of the beginning side of the pie slice, in black
+            $self->{'gd_obj'}->line($centerX,$centerY,
+                        $centerX + .5*$diameter*cos($start_degrees*$dg2rd),
+                        $centerY + .5*$diameter*sin($start_degrees*$dg2rd),
+                        $misccolor);
+ 
+
+            # Now, execute fillToBorder, starting from a point on the end line, in the
+            # desired pie slice color, and fill until a black pixel if encountered.
+            # What this means, is that a series of pie slices is drawn, each starting
+            # at the correct location, but each ending at 360 degrees. 
+    
+            $self->{'gd_obj'}->fillToBorder(
+                                            $centerX + .4*$diameter*cos($end_degrees*$dg2rd),
+                                            $centerY + .4*$diameter*sin($end_degrees*$dg2rd),
+                                            $misccolor, $color
+                                           );
+        }
+        # Figure out where to place the label
+        if ( $j == 0 )
+        {
+            $forbidden_degrees = $rd2dg*atan2($fontH,0.5*$text_diameter);
+        }
+        else
+        { 
+            $label_degrees = $self->maximum($label_degrees,$forbidden_degrees);
+            my $winkel = cos($label_degrees*$dg2rd);
+            my $h;
+            
+            $winkel = abs($winkel);
+            if ( abs($winkel) < 0.01 )
+            {
+               $h    = 0;
+            }
+            else
+            {
+               $h    = $fontH/$winkel;
+            }
+            
+            my $atan = atan2($h,0.5*$text_diameter); #  -pi ... +pi
+
+            #print $j.",". $atan*$rd2dg.",".cos($label_degrees*$dg2rd).",".$h.",".$label_degrees."\n";
+            
+            $forbidden_degrees = $label_degrees + $rd2dg*$atan;
+            
+        }
+        $labelX = $centerX+$text_diameter*0.5*cos($label_degrees*$dg2rd);
+        $labelY = $centerY+$text_diameter*0.5*sin($label_degrees*$dg2rd);
+        
+        #        # For debugging
+        #        # Draw Point
+        #        # reset the brush for points
+        #        my $brush = $self->_prepare_brush($color, 'point',
+	#			$self->{'pointStyle' . '0'});
+        #        $self->{'gd_obj'}->setBrush($brush);
+        # 
+        #        # draw the point
+        #        $self->{'gd_obj'}->line($labelX, $labelY, $labelX, $labelY, gdBrushed);
+        #        # end for debugging
+
+        # Okay, if a bunch of very small datasets are close together, they can
+        # overwrite each other. The following if statement is to help keep
+        # labels of neighbor datasets from being overlapped. It ain't perfect,
+        # but it does a pretty good job.
+	
+        if ( ($label_degrees >= 270 && $label_degrees <= 360) || 
+             ($label_degrees >= 0   && $label_degrees <= 90 ) )
+        {
+            # right side of the circle
+            # as 0 degrees means east
+            $self->{'gd_obj'}->string($font, $labelX, $labelY-$fontH*0.5, 
+                                      $label, $textcolor); # $textcolor would mark everything black
+            
+        }
+        else
+        {
+            $self->{'gd_obj'}->string($font, $labelX-length($label)*$fontW, $labelY-$fontH*0.5, 
+                                      $label, $textcolor); # $textcolor would mark everything black
+        }
+  
+        if ($self->{'legend_lines'} =~ /^true$/i) 
+        {
+            $self->{'gd_obj'}->line(
+                                    $centerX+0.5*$diameter*cos($degrees*$dg2rd),
+		                    $centerY+0.5*$diameter*sin($degrees*$dg2rd),
+		                    $labelX, $labelY, $color
+                                   );                 
+        }	    
+       
+        # reset starting point for next dataset and continue.    
+        $start_degrees      = $end_degrees;
+    }
+  
+  
+  
+    # print "Center $centerX, $centerY\n";
+    # print "Durchmesser $diameter\n";
+    # print "Hintergrund $background\n";  
+  
+    if ( defined($self->{'ring'}) &&  abs($self->{'ring'}) < 1 ) 
+    {
+        # print "bground $bground\n";
+        my $hole = (1- abs($self->{'ring'}));
+        if ($self->{'grey_background'} =~ /^true$/i) 
+        {
+            $insidecolor = $self->_color_role_to_index('grey_background');
+        }
+        else 
+        {
+            $insidecolor = $background;
+        }  
+   
+		       
+        $self->{'gd_obj'}->filledArc($centerX, $centerY, 
+                               $hole*$diameter, 
+                               $hole*$diameter,
+                               0, 360, $insidecolor);
+			       
+        $self->{'gd_obj'}->arc($centerX, $centerY, 
+                               $hole*$diameter, 
+                               $hole*$diameter,
+                               0, 360, $misccolor);			       
+  
+    }
+  
+  
+  
+    # and finaly box it off 
+  
+ 
+    $self->{'gd_obj'}->rectangle ($self->{'curr_x_min'},
+                                $self->{'curr_y_min'},
+                                $self->{'curr_x_max'},
+                                $self->{'curr_y_max'},
+                                $misccolor);
+    return;
+
+}
+
+
+## be a good module and return 1
+1;


Property changes on: packages/libchart-perl/branches/upstream/current/Chart/Pie.pm
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/Chart/Points.pm
===================================================================
--- packages/libchart-perl/branches/upstream/current/Chart/Points.pm	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/Chart/Points.pm	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,180 @@
+#====================================================================
+#  Chart::Points
+#
+#  written by david bonner
+#  dbonner at cs.bu.edu
+# 
+#  maintained by the Chart Group
+#  Chart at wettzell.ifag.de
+#
+#---------------------------------------------------------------------
+# History:
+#----------
+# $RCSfile: Points.pm,v $ $Revision: 1.4 $ $Date: 2003/02/14 14:22:05 $
+# $Author: dassing $
+# $Log: Points.pm,v $
+# Revision 1.4  2003/02/14 14:22:05  dassing
+# First setup to cvs
+#
+#====================================================================
+
+package Chart::Points;
+
+use Chart::Base '2.4.1';
+use GD;
+use Carp;
+use strict;
+
+ at Chart::Points::ISA = qw(Chart::Base);
+$Chart::Points::VERSION = '2.4.1';
+
+#>>>>>>>>>>>>>>>>>>>>>>>>>>#
+#  public methods go here  #
+#<<<<<<<<<<<<<<<<<<<<<<<<<<#
+
+
+
+#>>>>>>>>>>>>>>>>>>>>>>>>>>>#
+#  private methods go here  #
+#<<<<<<<<<<<<<<<<<<<<<<<<<<<#
+
+## finally get around to plotting the data
+sub _draw_data {
+  my $self = shift;
+  my $data = $self->{'dataref'};
+  my $misccolor = $self->_color_role_to_index('misc');
+  my ($x1, $x2, $x3, $y1, $y2, $y3, $mod);
+  my ($width, $height, $delta, $map, $delta_num, $zero_offset);
+  my ($i, $j, $color, $brush);
+  my $diff;
+
+  # init the imagemap data field if they want it
+  if ($self->{'imagemap'} =~ /^true$/i) {
+    $self->{'imagemap_data'} = [];
+  }
+
+  # find the delta value between data points, as well
+  # as the mapping constant
+  $width = $self->{'curr_x_max'} - $self->{'curr_x_min'};
+  $height = $self->{'curr_y_max'} - $self->{'curr_y_min'};
+  $delta = $width / ( $self->{'num_datapoints'} > 0 ? $self->{'num_datapoints'} : 1);
+  $diff = ($self->{'max_val'} - $self->{'min_val'});
+  $diff = 1 if $diff == 0;
+  $map = $height / $diff;
+
+  #for a xy-plot, use this delta and maybe an offset for the zero-axes
+  if ($self->{'xy_plot'} =~ /^true$/i ) {
+    $diff = ($self->{'x_max_val'} - $self->{'x_min_val'});
+    $diff = 1 if $diff == 0;
+    $delta_num = $width / $diff;
+
+    if ($self->{'x_min_val'} <= 0 && $self->{'x_max_val'} >= 0) {
+       $zero_offset = abs($self->{'x_min_val'}) * abs($delta_num);
+    }
+    elsif ($self->{'x_min_val'} > 0 || $self->{'x_max_val'} < 0) {
+       $zero_offset =  -$self->{'x_min_val'} * $delta_num;
+    }
+    else {
+       $zero_offset = 0;
+    }
+  }
+  
+  # get the base x-y values
+  if ($self->{'xy_plot'} =~ /^false$/i ) {
+    $x1 = $self->{'curr_x_min'} + ($delta / 2);
+  }
+  else {
+    $x1 = $self->{'curr_x_min'};
+  }
+  if ($self->{'min_val'} >= 0) {
+    $y1 = $self->{'curr_y_max'};
+    $mod = $self->{'min_val'};
+  }
+  elsif ($self->{'max_val'} <= 0) {
+    $y1 = $self->{'curr_y_min'};
+    $mod = $self->{'max_val'};
+  }
+  else {
+    $y1 = $self->{'curr_y_min'} + ($map * $self->{'max_val'});
+    $mod = 0;
+    $self->{'gd_obj'}->line ($self->{'curr_x_min'}, $y1,
+                             $self->{'curr_x_max'}, $y1,
+                             $misccolor);
+  }
+  
+  # draw the points
+  for $i (1..$self->{'num_datasets'}) {
+    # get the color for this dataset, and set the brush
+    $color = $self->_color_role_to_index('dataset'.($i-1));
+    $brush = $self->_prepare_brush ($color);
+    $self->{'gd_obj'}->setBrush ($brush);
+
+    # draw every point for this dataset
+    for $j (0..$self->{'num_datapoints'}) {
+      # don't try to draw anything if there's no data
+      if (defined ($data->[$i][$j])) {
+        if ($self->{'xy_plot'} =~ /^true$/i ) {
+           $x2 = $x1 + $delta_num * $data->[0][$j] + $zero_offset;
+           $x3 = $x2 ;
+        }
+        else {
+           $x2 = $x1 + ($delta * $j);
+           $x3 = $x2;
+        }
+	$y2 = $y1 - (($data->[$i][$j] - $mod) * $map);
+	$y3 = $y2;
+
+	# draw the point only if it is within the chart borders
+        if ($data->[$i][$j] <= $self->{'max_val'} && $data->[$i][$j] >= $self->{'min_val'}) {
+          $self->{'gd_obj'}->line($x2, $y2, $x3, $y3, gdBrushed);
+        }
+
+	# store the imagemap data if they asked for it
+	if ($self->{'imagemap'} =~ /^true$/i) {
+	  $self->{'imagemap_data'}->[$i][$j] = [ $x2, $y2 ];
+	}
+      }
+    }
+  }
+      
+  # and finaly box it off 
+  $self->{'gd_obj'}->rectangle ($self->{'curr_x_min'},
+  				$self->{'curr_y_min'},
+				$self->{'curr_x_max'},
+				$self->{'curr_y_max'},
+				$misccolor);
+  return;
+
+}
+
+
+##  set the gdBrush object to have nice circular points
+sub _prepare_brush {
+  my $self = shift;
+  my $color = shift;
+  my $radius = $self->{'pt_size'}/2;
+  my (@rgb, $brush, $white, $newcolor);
+
+  # get the rgb values for the desired color
+  @rgb = $self->{'gd_obj'}->rgb($color);
+
+  # create the new image
+  $brush = GD::Image->new ($radius*2, $radius*2);
+
+  # get the colors, make the background transparent
+  $white = $brush->colorAllocate (255,255,255);
+  $newcolor = $brush->colorAllocate (@rgb);
+  $brush->transparent ($white);
+
+  # draw the circle
+  $brush->arc ($radius-1, $radius-1, $radius, $radius, 0, 360, $newcolor);
+
+  # and fill it
+  $brush->fill ($radius-1, $radius-1, $newcolor);
+
+  # set the new image as the main object's brush
+  return $brush;
+}
+
+## be a good module and return 1
+1;

Added: packages/libchart-perl/branches/upstream/current/Chart/Split.pm
===================================================================
--- packages/libchart-perl/branches/upstream/current/Chart/Split.pm	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/Chart/Split.pm	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,638 @@
+#====================================================================
+#  Chart::Split
+#
+#  written by Chart-Group
+#
+#  maintained by the Chart Group
+#  Chart at wettzell.ifag.de
+#
+#---------------------------------------------------------------------
+# History:
+#----------
+# $RCSfile: Split.pm,v $ $Revision: 1.2 $ $Date: 2003/02/14 14:25:30 $
+# $Author: dassing $
+# $Log: Split.pm,v $
+# Revision 1.2  2003/02/14 14:25:30  dassing
+# First setup to cvs
+#
+#====================================================================
+
+package Chart::Split;
+
+use Chart::Base '2.4.1';
+use GD;
+use Carp;
+use strict;
+
+ at Chart::Split::ISA = qw(Chart::Base);
+$Chart::Split::VERSION = '2.4.1';
+
+#>>>>>>>>>>>>>>>>>>>>>>>>>>#
+#  public methods go here  #
+#<<<<<<<<<<<<<<<<<<<<<<<<<<#
+
+
+
+#>>>>>>>>>>>>>>>>>>>>>>>>>>>#
+#  private methods go here  #
+#<<<<<<<<<<<<<<<<<<<<<<<<<<<#
+
+#draw the ticks
+sub _draw_x_number_ticks {
+    my $self = shift;
+    my $data = $self->{'dataref'};
+    my $font = $self->{'tick_label_font'};
+    my $textcolor = $self->_color_role_to_index('text');
+    my $misccolor = $self->_color_role_to_index('misc');
+    my $num_points = $self->{'num_datapoints'};
+    my ($h, $w, $width, $step, $start, $interval, $label, $stag, @labels);
+    my ($x_start, $y_start, $y, $x, $lines, $delta, $ticks);
+    my $x_label_len = 1;
+    my $y_label_len = 1;
+    my $x_max = -0x80000000;
+    
+    $self->{'grid_data'}-> {'x'} = [];
+
+    # find the width
+    $width = $self->{'curr_x_max'} - $self->{'curr_x_min'}; $width = 1 if $width == 0;
+
+    # make sure we got a real font
+    unless ((ref $font) eq 'GD::Font') {
+           croak "The tick label font you specified isn\'t a GD Font object";
+    }
+
+    # find out how big the font is
+    ($w, $h) = ($font->width, $font->height);
+
+    unless (defined $self->{'start'} && defined $self->{'interval'}) {
+           croak "I need two values from you to draw a split chart: start and interval!";
+    }
+    else {
+      $interval = $self->{'interval'};
+      $start = $self->{'start'};
+      $ticks = $self->{'interval_ticks'}-1;
+      $label = $start;
+    }
+
+
+    #look after devision by zero!
+    if ( $ticks ==0 ) { $ticks=1; }
+    
+    #calculate the step between the ticks
+    $step = $interval/$ticks;
+
+    for (0..$ticks) {
+         push @labels, $self->{f_x_tick}-> (sprintf ("%.".$self->{'precision'}."f", $label));
+         $label += $step;
+    }
+
+    #find the biggest x value
+    foreach (@{$data->[0]}) {
+      if ($_ > $x_max) {
+        $x_max = $_;
+      }
+    }
+
+    #find the length of the x and y labels
+    foreach (@labels) {
+      if (length($_) > $x_label_len) {
+        $x_label_len = length($_);
+      }
+    }
+    
+    #find the amount of lines
+    $lines = int((($x_max-$start) / $interval)+0.99999999999);
+    $lines = 1 if $lines == 0;
+    
+    #find the length, of the label.
+    $y_label_len = length($lines);
+
+    #get the starting point and the width
+    if ($lines > 1) {  #if there are y-ticks
+     if ($self->{'y_axes'} =~ /^right$/i) {
+       $x_start = $self->{'curr_x_min'}  ;
+       $width = $self->{'curr_x_max'}-$x_start - $self->{'text_space'}*2- $y_label_len*$w-$self->{'tick_len'};
+
+     }
+     elsif ($self->{'y_axes'} =~ /^both$/i) {
+        $x_start = $self->{'curr_x_min'} + ($w * $y_label_len) +2*$self->{'text_space'} + $self->{'tick_len'};
+        $width = $self->{'curr_x_max'} - $x_start- ($w * $y_label_len)
+                 - 2 * $self->{'text_space'} - $self->{'tick_len'};
+     }
+     else {
+         $x_start = $self->{'curr_x_min'} + ($w * $y_label_len)
+         + 3 * $self->{'text_space'} ;
+         $width = $self->{'curr_x_max'} - $x_start;
+     }
+    }
+    else {        #if there are no y-axes
+     $x_start = $self->{'curr_x_min'};
+     $width = $self->{'curr_x_max'} - $x_start;
+    }
+    
+    #and the y_start value
+    $y_start = $self->{'curr_y_max'} - $h - $self->{'text_space'};
+    
+    #get the delta value
+    $delta = $width / ($ticks);
+
+    if ( ! defined($self->{'skip_x_ticks'}) ) {
+     $self->{'skip_x_ticks'} = 1;
+    }
+    #draw the labels
+    if ($self->{'x_ticks'} =~ /^normal$/i ) {
+      if ($self->{'skip_x_ticks'} > 1) {      #draw a normal tick every nth label
+         for ( 0..$#labels-1) {
+             if ( defined ($labels[$_*$self->{'skip_x_ticks'}]) ) {
+                $x = $x_start + $delta*($_*$self->{'skip_x_ticks'})
+                     - ($w * length($labels[$_*$self->{'skip_x_ticks'}]))/2;
+                $self->{'gd_obj'}->string($font, $x, $y_start,$labels[$_*$self->{'skip_x_ticks'}], $textcolor);
+             }
+         }
+      }
+      elsif($self->{'custom_x_ticks'}) {     #draw only the normal ticks they wanted
+         foreach (@{$self->{'custom_x_ticks'}}) {
+             if ( defined $labels[$_] ) {
+                $x = $x_start + $delta*$_ - ($w * length($labels[$_]))/2;
+                $self->{'gd_obj'}->string($font, $x, $y_start, $labels[$_], $textcolor);
+             }
+         }
+      }
+      else {
+        for (0..$#labels) {                 #draw all ticks normal
+            if ( defined $labels[$_] ) {
+               $x = $x_start + $delta*($_) - ($w * length($labels[$_]))/2;
+               $self->{'gd_obj'}->string($font, $x, $y_start,$labels[$_], $textcolor);
+            }
+        }
+      }
+    }
+    elsif ($self->{'x_ticks'} =~ /^staggered$/i ) {
+      $stag = 0;
+      if ($self->{'skip_x_ticks'} > 1 ) {   #draw a staggered tick every nth label
+         for ( 0..$#labels-1) {
+             if ( defined ($labels[$_*$self->{'skip_x_ticks'}])) {
+               $x = $x_start + $delta*($_*$self->{'skip_x_ticks'})
+                     - ($w * length($labels[$_*$self->{'skip_x_ticks'}]))/2;
+               if ($stag % 2 == 0) {
+                  $y_start -= $self->{'text_space'} + $h;
+               }
+               $self->{'gd_obj'}->string($font, $x, $y_start,$labels[$_*$self->{'skip_x_ticks'}], $textcolor);
+               if ($stag % 2 == 0) {
+                  $y_start += $self->{'text_space'} + $h;
+               }
+               $stag++;
+             }
+         }
+      }
+      elsif ($self->{'custom_x_ticks'}) {      # draw only the wanted ticks staggered
+         foreach (sort (@{$self->{'custom_x_ticks'}})) {
+             if ( defined $labels[$_]) {
+                $x = $x_start + $delta*$_ - ($w*(length($labels[$_])))/2;
+                if ($stag % 2 == 0) {
+                  $y_start -= $self->{'text_space'} + $h;
+                }
+                $self->{'gd_obj'}->string($font, $x, $y_start,$labels[$_], $textcolor);
+                if ($stag % 2 == 0) {
+                  $y_start += $self->{'text_space'} + $h;
+                }
+                $stag++;
+             }
+         }
+      }
+      else {         # draw all ticks staggered
+         for (0..$#labels) {
+            if ( defined $labels[$_] ) {
+               $x = $x_start + $delta*$_  -($w*(length($labels[$_])))/2;
+              if ($stag % 2 == 0) {
+                  $y_start -= $self->{'text_space'} + $h;
+              }
+              $self->{'gd_obj'}->string($font, $x, $y_start,$labels[$_], $textcolor);
+              if ($stag % 2 == 0) {
+                  $y_start += $self->{'text_space'} + $h;
+              }
+              $stag++;
+            }
+         }
+      }
+    }
+    elsif ( $self->{'x_ticks'} =~ /^vertical$/i ) {
+       $y_start = $self->{'curr_y_max'} - $self->{'text_space'};
+       if ( $self->{'skip_x_ticks'} > 1) {                 #draw every nth tick vertical
+          for (0..$#labels) {
+              if (defined $_) {
+                 $x = $x_start + $delta*($_ * $self->{'skip_x_ticks'}) - $h/2;
+                 $y = $y_start - ($x_label_len- length($labels[$_*$self->{'skip_x_ticks'}]))*$w;
+                 $self->{'gd_obj'}->stringUp($font, $x, $y,$labels[$_*$self->{'skip_x_ticks'}], $textcolor);
+              }
+          }
+       }
+       elsif ( $self->{'custom_x_ticks'} ) {
+          foreach ( @{$self->{'custom_x_ticks'}}) {    #draw the ticks they want vertical
+             if (defined $labels[$_]) {
+                $x = $x_start + $delta*$_ - $h/2;
+                $y = $y_start - ($x_label_len- length($labels[$_]))*$w;
+                $self->{'gd_obj'}->stringUp($font, $x, $y,$labels[$_], $textcolor);
+             }
+          }
+       }
+       else {                # draw all ticks vertical
+          for ( 0..$#labels) {
+              if ( defined $labels[$_]) {
+                 $x = $x_start + $delta*$_ - $h/2;
+                 $y = $y_start - ($x_label_len- length($labels[$_]))*$w;
+                 $self->{'gd_obj'}->stringUp($font, $x, $y,$labels[$_], $textcolor);
+              }
+          }
+       }
+       
+    }
+    
+    #update the borders
+    if ($self->{'interval_ticks'} > 0) {
+     if ($self->{'x_ticks'} =~ /^normal$/i ) {
+        $self->{'curr_y_max'} -= $h + $self->{'text_space'}*2;
+     }
+     elsif ($self->{'x_ticks'} =~ /^staggered$/i ) {
+        $self->{'curr_y_max'} -= 2*$h + 3*$self->{'text_space'};
+     }
+     elsif ($self->{'x_ticks'} =~ /^vertical$/i ) {
+        $self->{'curr_y_max'} -= $w * $x_label_len + $self->{'text_space'} * 2;
+     }
+    }
+    
+    #draw the ticks
+    $y_start = $self->{'curr_y_max'};
+    $y = $y_start - $self->{'tick_len'};
+
+    if ($self->{'skip_x_ticks'} > 1) {
+       for ( 0..int(($#labels  )/$self->{'skip_x_ticks'})) {
+           $x = $x_start + $delta*($_*$self->{'skip_x_ticks'}) ;
+           $self->{'gd_obj'}->line($x, $y_start, $x, $y, $misccolor);
+           if ( $self->{'grid_lines'} =~ /^true$/i or $self->{'x_grid_lines'} =~ /^true$/i) {
+                $self->{'grid_data'} ->{'x'}->[$_] = $x;
+           }
+       }
+    }
+    elsif ($self->{'custom_x_ticks'}) {
+       foreach (@{$self->{'custom_x_ticks'}}) {
+           if ($_ <= $ticks) {
+              $x = $x_start + $delta*$_;
+              $self->{'gd_obj'}->line($x, $y_start, $x, $y, $misccolor);
+              if ( $self->{'grid_lines'} =~ /^true$/i or $self->{'x_grid_lines'} =~ /^true$/i) {
+                $self->{'grid_data'} ->{'x'}->[$_] = $x;
+              }
+           }
+       }
+    }
+    else {
+       for (0..$#labels) {
+           $x = $x_start + $_*$delta;
+           $self->{'gd_obj'}->line($x, $y_start, $x, $y, $misccolor);
+           if ( $self->{'grid_lines'} =~ /^true$/i or $self->{'x_grid_lines'} =~ /^true$/i) {
+                $self->{'grid_data'} ->{'x'}->[$_] = $x;
+           }
+       }
+    }
+    
+    #another update of the borders
+    $self->{'curr_y_max'} -= $self->{'tick_len'} if $self->{'interval_ticks'} > 0;
+
+    #finally return
+    return;
+}
+
+# override the funktion implemented in base
+sub _draw_x_ticks {
+    my $self = shift;
+
+    #Use always the _draw_x_tick funktion because we always do a xy_plot!!!
+    $self->_draw_x_number_ticks();
+    
+    #and return
+    return 1;
+}
+
+sub _draw_y_ticks {
+    my $self = shift;
+    my $side = shift || 'left';
+    my $data = $self->{'dataref'};
+    my $font = $self->{'tick_label_font'};
+    my $textcolor = $self->_color_role_to_index('text');
+    my $misccolor = $self->_color_role_to_index('misc');
+    my @labels = @{$self->{'y_tick_labels'}};
+    my $num_points = $self->{'num_datapoints'};
+    my ($w, $h);
+    my ($x_start, $x, $y_start, $y, $start, $interval);
+    my ($height, $delta, $label, $lines,$label_len);
+    my ($s, $f);
+    my $x_max = -0x80000000;
+    $self->{grid_data}->{'y'} = [];
+    $self->{grid_data}->{'y2'} = [];
+
+    # find the height
+    $height = $self->{'curr_y_max'} - $self->{'curr_y_min'};
+
+    # make sure we got a real font
+    unless ((ref $font) eq 'GD::Font') {
+           croak "The tick label font you specified isn\'t a GD Font object";
+    }
+
+    # find out how big the font is
+    ($w, $h) = ($font->width, $font->height);
+    
+    #get the base variables
+    $interval = $self->{'interval'};
+    $start = $self->{'start'};
+
+    #find the biggest x value
+    foreach (@{$data->[0]}) {
+      if ($_ > $x_max) {
+        $x_max = $_;
+      }
+    }
+    #calculate the number of lines and the length
+    $lines = int((($x_max-$start)/ $interval)+0.99999999999);
+    $lines = 1 if $lines == 0;
+    $label_len = length($lines);
+
+    #get the space between two lines
+    $delta = $height / $lines;
+
+    #now draw them
+    if ($lines > 1) {
+     if ( $side =~ /^right$/i ) {
+       #get the starting point
+       $x_start = $self->{'curr_x_max'};
+       $y_start = $self->{'curr_y_min'};
+
+       #draw the labels
+       for $label (0..$lines-1) {
+           $x = $x_start - $self->{'text_space'} - $label_len*$w;
+           $y = $y_start + $label*$delta + $delta/2 -$h/2;
+           $self->{'gd_obj'}->string($font, $x, $y, $label, $textcolor);
+       }
+
+       #draw the ticks
+       for $label ( 0..$lines) {
+           $x = $x_start - $self->{'text_space'} *2 - $label_len*$w - $self->{'tick_len'};
+           $y = $y_start + $label*$delta;
+           $self->{'gd_obj'} ->line( $x_start-$self->{'text_space'}, $y, $x, $y, $misccolor);
+           #add data for grid_lines
+           push @{$self->{grid_data} ->{'y'}}, $y;
+       }
+
+       #update the borders
+       $self->{'curr_x_max'} = $x_start - $self->{'text_space'}*2- $label_len*$w-$self->{'tick_len'};
+
+     }
+
+     elsif ( $side =~ /^both$/i) {
+       #get the starting point
+       $x_start = $self->{'curr_x_min'};
+       $y_start = $self->{'curr_y_min'};
+
+       #first the left side
+       #draw the labels
+       for $label (0..$lines-1) {
+           $x = $self->{'curr_x_min'}+$self->{'text_space'}*2;
+           $y = $y_start+ $label*$delta + $delta/2 -$h/2;
+           $self->{'gd_obj'}->string($font, $x, $y, $self->{'f_y_tick'}->($label), $textcolor);
+       }
+       #draw the ticks
+       for $label (0..$lines) {
+           $x = $x_start + $self->{'text_space'}*2+ $label_len*$w+$self->{'tick_len'};
+           $y = $y_start+ $label*$delta ;
+           $self->{'gd_obj'}->line( $x_start+$self->{'text_space'}, $y, $x, $y, $misccolor);
+       }
+       
+       #then the right side
+       #get the starting point
+       $x_start = $self->{'curr_x_max'};
+       $y_start = $self->{'curr_y_min'};
+
+       #draw the labels
+       for $label (0..$lines-1) {
+           $x = $x_start - $self->{'text_space'} - $label_len*$w;
+           $y = $y_start + $label*$delta + $delta/2 -$h/2;
+           $self->{'gd_obj'}->string($font, $x, $y, $self->{'f_y_tick'}->($label), $textcolor);
+       }
+
+       #draw the ticks
+       for $label ( 0..$lines) {
+           $x = $x_start - $self->{'text_space'} *2 - $label_len*$w - $self->{'tick_len'};
+           $y = $y_start + $label*$delta;
+           $self->{'gd_obj'} ->line( $x_start-$self->{'text_space'}, $y, $x, $y, $misccolor);
+           #add data for grid_lines
+           push @{$self->{grid_data} ->{'y'}}, $y;
+       }
+       #update the borders
+       $self->{'curr_x_min'} += $self->{'text_space'}*2 + $label_len*$w+$self->{'tick_len'};
+       $self->{'curr_x_max'} = $x_start -$self->{'text_space'}*2 - $label_len*$w-$self->{'tick_len'};
+
+     }
+     else {
+
+       #get the starting point
+       $x_start = $self->{'curr_x_min'};
+       $y_start = $self->{'curr_y_min'};
+
+       #draw the labels
+       for $label (0..$lines-1) {
+           $x = $self->{'curr_x_min'}+$self->{'text_space'}*2;
+           $y = $y_start+ $label*$delta + $delta/2 -$h/2;
+           $self->{'gd_obj'}->string($font, $x, $y, $self->{'f_y_tick'}->($label), $textcolor);
+       }
+       #draw the ticks
+       for $label (0..$lines) {
+           $x = $x_start + $label_len*$w+$self->{'tick_len'}+$self->{'text_space'}*3;
+           $y = $y_start+ $label*$delta ;
+           $self->{'gd_obj'}->line( $x_start+$self->{'text_space'}, $y, $x, $y, $misccolor);
+           #this is also where we have to draw the grid_lines
+           push @{$self->{grid_data}->{'y'}} , $y;
+       }
+       #update the borders
+       $self->{'curr_x_min'} = $x_start + $self->{'text_space'}*3+ $label_len*$w;
+     }
+
+    }
+
+    #finally return
+    return 1;
+}
+
+
+#plot the data
+sub _draw_data {
+    my $self = shift;
+    my $data = $self->{'dataref'};
+    my $misccolor = $self->_color_role_to_index('misc');
+    my $num_points = $self->{'num_datapoints'}; $num_points = 1 if $num_points == 0;
+    my $num_sets = $self->{'num_datasets'}; $num_sets = 1 if $num_sets == 0;
+    my ($lines, $split, $width, $height, $delta_lines, $delta_sets, $map, $last_line );
+    my ($akt_line, $akt_set, $akt_point, $color, $x_start, $y_start, $x, $y);
+    my ($x_last, $y_last, $delta_point, $brush, $mod, $x_interval, $start);
+    my $i =0;
+    my $interval = ($self->{'max_val'} - $self->{'min_val'}); $interval = 1 if $interval == 0;
+    my $x_max = -0x80000000;
+    
+    # find the height and the width
+    $width = $self->{'curr_x_max'} - $self->{'curr_x_min'};  $width  = 1 if $width == 0;
+    $height = $self->{'curr_y_max'} - $self->{'curr_y_min'}; $height = 1 if $height == 0;
+
+    # init the imagemap data field if they asked for it
+    if ($self->{'imagemap'} =~ /^true$/i) {
+       $self->{'imagemap_data'} = [];
+    }
+    #get the base values
+    $x_interval = $self->{'interval'}; $x_interval = 1 if $x_interval == 0;
+    $start = $self->{'start'};
+
+    #find the biggest x value
+    foreach (@{$data->[0]}) {
+      if ($_ > $x_max) {
+        $x_max = $_;
+      }
+    }
+    
+    #calculate the number of lines
+    $lines = int((($x_max-$start)/ $x_interval)+0.99999999999); $lines = 1 if $lines == 0;
+
+    #find delta_lines for the space between the lines
+    #and delta_sets for the space of the datasets of one line
+    #and the delta_point for the space between the datapoints
+    $delta_lines = $height / $lines;
+    $delta_sets = $delta_lines / $num_sets;
+    $delta_point = $width / ($x_interval);
+
+    #find $map, for the y values
+    $map = $delta_sets / $interval;
+
+    #find the mod and the y_start value
+    #correct the start value, if scale is set! Otherwise the plot is to high or to low!
+    #The corecction, isn't perfect, but it does a good job in most cases.
+    if ($self->{'min_val'} >= 0) {
+         $mod = $self->{'min_val'};
+         if ($self->{'scale'} > 1) {
+             $y_start = $self->{'curr_y_min'}
+                       +($interval*$map/2) *($self->{'scale'}-1);
+         }
+         else {
+             $y_start = $self->{'curr_y_min'}
+         }
+    }
+    elsif ($self->{'max_val'} <= 0) {
+         $mod = $self->{'min_val'};
+         if ($self->{'scale'} > 1) {
+             $y_start = $self->{'curr_y_min'}
+                      +($interval*$map/2) *($self->{'scale'}-1);
+         }
+         else {
+             $y_start = $self->{'curr_y_min'};
+         }
+    }
+    else {
+            $y_start = $self->{'curr_y_min'}+ ($map * $self->{'min_val'});
+            $mod = 0;
+    }
+
+    #The upper right corner is the point, where we start
+    $x_start = $self->{'curr_x_min'};
+
+    #draw the lines
+    for $akt_set (0..$num_sets-1) {
+      for $akt_point (0..$self->{'num_datapoints'}-1) {
+        #get the color for this dataset
+        $color = $self->_color_role_to_index('dataset'.$akt_set);
+        $brush = $self->_prepare_brush ($color, 'line');
+        $self->{'gd_obj'}->setBrush ($brush);
+        
+        #start with the first point at line number zero
+        $last_line =0;
+        for $akt_line ($last_line..$lines-1) {
+           #update the last line. That makes it a little bit faster.
+           $last_line = $akt_line;
+           
+           #Don't try to draw, if there is no data
+           if (defined $data->[0][$akt_point]) {
+               if ( $data->[0][$akt_point] <= (($akt_line+1)*$x_interval +$start)
+                   && $data->[0][$akt_point] >= $akt_line*$x_interval + $start)  {
+
+                  #the current point
+                 $x = $x_start + ($data->[0][$akt_point]
+                      - ($akt_line *$x_interval)- ($start))* $delta_point;
+                 $y = $y_start + $akt_line*$delta_lines
+                      + $akt_set*$delta_sets  + $delta_sets
+                      -($data->[1+$akt_set][$akt_point]-$mod) * $map *$self->{'scale'};
+
+                 #draw the line
+                 $self->{'gd_obj'}->line($x_last, $y_last, $x, $y, gdBrushed)if $akt_point!=0;
+               
+                 #calculate the start point for the next line
+                 #first if the next point is in the same line
+                 if  ( defined ($data->[0][$akt_point+1]) && $data->[0][$akt_point+1] <= (($akt_line+1)*$x_interval +$start)
+                      && $data->[0][$akt_point+1] > $akt_line*$x_interval + $start  ){
+                    $x_last = $x;
+                    $y_last = $y;
+                 }
+                 #second, if the next point is not in the same line
+                 else {
+                    $x_last = $self->{'curr_x_min'};
+                    $y_last = $y_start + ($akt_line+1)*$delta_lines
+                              + $akt_set*$delta_sets  + $delta_sets
+                              -($data->[1+$akt_set][$akt_point]-$mod) * $map *$self->{'scale'};
+                 }
+
+                 # store the imagemap data if they asked for it
+                 if ($self->{'imagemap'} =~ /^true$/i) {
+	              $self->{'imagemap_data'}->[$akt_set][$akt_point-1] = [ $x_last, $y_last ];
+	              $self->{'imagemap_data'}->[$akt_set][$akt_point] = [ $x, $y ];
+                     }
+               }
+               else {  #Go to the next line. Maybe the current point is in that line!
+                 next;
+               }
+           }
+           else {
+               if ($self->{'imagemap'} =~ /^true$/i) {
+	             $self->{'imagemap_data'}->[$akt_set][$akt_point-1] = [ undef(), undef() ];
+	             $self->{'imagemap_data'}->[$akt_set][$akt_point] = [ undef(), undef() ];
+               }
+           }
+        }
+      }
+    }
+
+    $y_start = $self->{'curr_y_min'};
+    #draw some nice little lines
+    for $akt_set (0..$num_sets-1) {
+        for $akt_line (0..$lines-1) {
+           #draw a line between the sets at the left side of the chart
+           $self->{'gd_obj'}->line($x_start,
+                               $y_start+ $akt_line*$delta_lines + $akt_set*$delta_sets,
+                               $x_start+$self->{'tick_len'},
+                               $y_start+ $akt_line*$delta_lines + $akt_set*$delta_sets,
+                               $misccolor);
+           #draw a line between the sets at the right side of the chart
+           $self->{'gd_obj'}->line($self->{'curr_x_max'},
+                               $y_start + $akt_line*$delta_lines + $akt_set*$delta_sets,
+                               $self->{'curr_x_max'}-$self->{'tick_len'},
+                               $y_start + $akt_line*$delta_lines + $akt_set*$delta_sets,
+                               $misccolor);
+        }
+    }
+    
+    #Box it off
+    $self->{'gd_obj'}->rectangle ($self->{'curr_x_min'},
+  				$self->{'curr_y_min'},
+				$self->{'curr_x_max'},
+				$self->{'curr_y_max'},
+				$misccolor);
+
+    #finally retrun
+    return;
+}
+
+#be a good modul and return 1
+1;
+


Property changes on: packages/libchart-perl/branches/upstream/current/Chart/Split.pm
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/Chart/StackedBars.pm
===================================================================
--- packages/libchart-perl/branches/upstream/current/Chart/StackedBars.pm	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/Chart/StackedBars.pm	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,574 @@
+#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>#
+#  Chart::StackedBars            #
+#                                #
+#  written by david bonner       #
+#  dbonner at cs.bu.edu             #
+#                                #
+#  maintained by the Chart Group #
+#  Chart at wettzell.ifag.de        #
+#                                #
+#  theft is treason, citizen     #
+#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<#
+
+package Chart::StackedBars;
+
+use Chart::Base '2.4.1';
+use GD;
+use Carp;
+use strict;
+
+ at Chart::StackedBars::ISA = qw(Chart::Base);
+$Chart::StackedBars::VERSION = '2.4.1';
+
+#>>>>>>>>>>>>>>>>>>>>>>>>>>#
+#  public methods go here  #
+#<<<<<<<<<<<<<<<<<<<<<<<<<<#
+
+#>>>>>>>>>>>>>>>>>>>>>>>>>>>#
+#  private methods go here  #
+#<<<<<<<<<<<<<<<<<<<<<<<<<<<#
+
+## override check_data to make sure we don't get datasets with positive
+## and negative values mixed
+sub _check_data {
+  my $self = shift;
+  my $data = $self->{'dataref'};
+  my $length = 0;
+  my ($i, $j, $posneg);
+  my $composite;
+  # remember the number of datasets
+  if (defined $self->{'composite_info'}) { 
+    if ($self->{'composite_info'}[0][0] =~ /^StackedBars$/i) {
+      $composite=0; 
+      }
+    if ($self->{'composite_info'}[1][0] =~ /^StackedBars$/i) {
+      $composite=1;
+      }
+ # $self->{'num_datasets'} = $#{$data};     ###
+  
+  $self->{'num_datasets'} = ($#{$self->{'composite_info'}[$composite][1]})+1;
+  }
+  else {
+  $self->{'num_datasets'} = $#{$data}; 
+  }
+  # remember the number of points in the largest dataset
+  $self->{'num_datapoints'} = 0;
+  for (0..$self->{'num_datasets'}) { 
+  if (scalar(@{$data->[$_]}) > $self->{'num_datapoints'}) {
+      $self->{'num_datapoints'} = scalar(@{$data->[$_]});
+    }
+  }
+
+  # make sure the datasets don't mix pos and neg values
+  for $i (0..$self->{'num_datapoints'}-1) {
+    $posneg = '';
+    for $j (1..$self->{'num_datasets'}) {
+      if ($data->[$j][$i] > 0) {
+	if ($posneg eq 'neg') {
+	  croak "The values for a Chart::StackedBars data point must either be all positive or all negative";
+	}
+	else {
+	  $posneg = 'pos';
+	}
+      }
+      elsif ($data->[$j][$i] < 0) {
+	if ($posneg eq 'pos') {
+	  croak "The values for a Chart::StackedBars data point must either be all positive or all negative";
+	}
+	else {
+	  $posneg = 'neg';
+	}
+      }
+    }
+  }
+
+  # find good min and max y-values for the plot
+  $self->_find_y_scale;
+
+  # find the longest x-tick label
+  for (@{$data->[0]}) {
+    if (length($_) > $length) {
+      $length = length ($_);
+    }
+  }
+
+  # now store it in the object
+  $self->{'x_tick_label_length'} = $length;
+
+  
+  return;
+}
+
+
+sub _find_y_range {
+  my $self = shift;
+  
+  #   This finds the minimum and maximum point-sum over all x points,
+  #   where the point-sum is the sum of the dataset values for that point.
+  #   If the y value in any dataset is undef for a given x, it simply
+  #   adds nothing to the sum.
+  
+  
+  my $data = $self->{'dataref'};
+  my $max = undef;
+  my $min = undef;
+  for my $i (0..$#{$data->[0]}) { # data point
+    my $sum = $data->[1]->[$i] || 0;
+    for my $dataset ( @$data[2..$#$data] ) { # order not important
+      my $datum = $dataset->[$i];
+      $sum += $datum if defined $datum;
+    }
+    if ( defined $max ) {
+      if ( $sum > $max ) { $max = $sum }
+      elsif ( $sum < $min ) { $min = $sum }
+    }
+    else { $min = $max = $sum }
+  }
+
+
+  # make sure all-positive or all-negative charts get anchored at
+  # zero so that we don't cut out some parts of the bars
+  if (($max > 0) && ($min > 0)) {
+    $min = 0;
+  }
+  if (($min < 0) && ($max < 0)) {
+    $max = 0;
+  }
+
+	($min, $max);
+}
+
+
+# ## override _find_y_scale to account for stacked bars
+# sub _find_y_scale {
+#   my $self = shift;
+#   my $raw = $self->{'dataref'};
+#   my $data = [@{$raw->[1]}];
+#   my ($i, $j, $max, $min);
+#   my ($order, $mult, $tmp);
+#   my ($range, $delta, @dec, $y_ticks);
+#   my $labels = [];
+#   my $length = 0;
+# 
+#   # use realy weird max and min values
+#   $max = -999999999999;
+#   $min = 999999999999;
+# 
+#   # go through and stack them
+#   for $i (0..$self->{'num_datapoints'}-1) {
+#     for $j (2..$self->{'num_datasets'}) {
+#       $data->[$i] += $raw->[$j][$i];
+#     }
+#   }
+# 
+#   # get max and min values
+#   for $i (0..$self->{'num_datapoints'}-1) {
+#     if ($data->[$i] > $max) {
+#       $max = $data->[$i];
+#     }
+#     if ($data->[$i] < $min) {
+#       $min = $data->[$i];
+#     }
+#   }
+# 
+#   # make sure all-positive or all-negative charts get anchored at
+#   # zero so that we don't cut out some parts of the bars
+#   if (($max > 0) && ($min > 0)) {
+#     $min = 0;
+#   }
+#   if (($min < 0) && ($max < 0)) {
+#     $max = 0;
+#   }
+# 
+#   # calculate good max value
+#   if ($max < -10) {
+#     $tmp = -$max;
+#     $order = int((log $tmp) / (log 10));
+#     $mult = int ($tmp / (10 ** $order));
+#     $tmp = ($mult - 1) * (10 ** $order);
+#     $max = -$tmp;
+#   }
+#   elsif ($max < 0) {
+#     $max = 0;
+#   }
+#   elsif ($max > 10) {
+#     $order = int((log $max) / (log 10));
+#     $mult = int ($max / (10 ** $order));
+#     $max = ($mult + 1) * (10 ** $order);
+#   }
+#   elsif ($max >= 0) {
+#     $max = 10;
+#   }
+# 
+#   # now go for a good min
+#   if ($min < -10) {
+#     $tmp = -$min;
+#     $order = int((log $tmp) / (log 10));
+#     $mult = int ($tmp / (10 ** $order));
+#     $tmp = ($mult + 1) * (10 ** $order);
+#     $min = -$tmp;
+#   }
+#   elsif ($min < 0) {
+#     $min = -10;
+#   }
+#   elsif ($min > 10) {
+#     $order = int ((log $min) / (log 10));
+#     $mult = int ($min / (10 ** $order));
+#     $min = $mult * (10 ** $order);
+#   }
+#   elsif ($min >= 0) {
+#     $min = 0;
+#   }
+# 
+#   # put the appropriate min and max values into the object if necessary
+#   unless (defined ($self->{'max_val'})) {
+#     $self->{'max_val'} = $max;
+#   }
+#   unless (defined ($self->{'min_val'})) {
+#     $self->{'min_val'} = $min;
+#   }
+# 
+#   # generate the y_tick labels, store them in the object
+#   # figure out which one is going to be the longest
+#   $range = $self->{'max_val'} - $self->{'min_val'};
+#   $y_ticks = $self->{'y_ticks'} - 1;
+#   ## Don't adjust y_ticks if the user specified custom labels
+#   if ($self->{'integer_ticks_only'} =~ /^true$/i && ! $self->{'y_tick_labels'}) {
+#     unless (($range % $y_ticks) == 0) {
+#       while (($range % $y_ticks) != 0) {
+# 	$y_ticks++;
+#       }
+#       $self->{'y_ticks'} = $y_ticks + 1;
+#     }
+#   }
+#     
+#   $delta = $range / $y_ticks;
+#   for (0..$y_ticks) {
+#     $tmp = $self->{'min_val'} + ($delta * $_);
+#     @dec = split /\./, $tmp;
+#     if ($dec[1] && (length($dec[1]) > 3)) {
+#       $tmp = sprintf("%.3f", $tmp);
+#     }
+#     $labels->[$_] = $tmp;
+#     if (length($tmp) > $length) {
+#       $length = length($tmp);
+#     }
+#   }
+# 
+#   # store it in the object
+#   $self->{'y_tick_labels'} = $labels;
+#   $self->{'y_tick_label_length'} = $length;
+#  
+#   # and return
+#   return;
+# }
+
+
+## finally get around to plotting the data
+sub _draw_data {
+  my $self = shift;
+  my $raw = $self->{'dataref'};
+  my $data = [];
+  my $misccolor = $self->_color_role_to_index('misc');
+  my ($width, $height, $delta, $map, $mod);
+  my ($x1, $y1, $x2, $y2, $x3, $y3, $i, $j, $color, $cut);
+  my $pink = $self->{'gd_obj'}->colorAllocate(255,0,255);
+
+  # init the imagemap data field if they want it
+  if ($self->{'imagemap'} =~ /^true$/i) {
+    $self->{'imagemap_data'} = [];
+  }
+   
+  # width and height of remaining area, delta for width of bars, mapping value
+  $width = $self->{'curr_x_max'} - $self->{'curr_x_min'};
+   
+  if ($self->{'spaced_bars'} =~ /^true$/i) {
+   $delta = ($width / ($self->{'num_datapoints'} * 2));
+    }
+  else {
+    $delta = $width / $self->{'num_datapoints'};
+    }
+  $height = $self->{'curr_y_max'} - $self->{'curr_y_min'};
+  $map = $height / ($self->{'max_val'} - $self->{'min_val'});
+
+  # get the base x and y values
+  $x1 = $self->{'curr_x_min'};
+  if ($self->{'min_val'} >= 0) {
+    $y1 = $self->{'curr_y_max'};
+    $mod = $self->{'min_val'};
+  }
+  elsif ($self->{'max_val'} <= 0) {
+    $y1 = $self->{'curr_y_min'};
+    $mod = $self->{'max_val'};
+  }
+  else {
+    $y1 = $self->{'curr_y_min'} + ($map * $self->{'max_val'});
+    $mod = 0;
+    $self->{'gd_obj'}->line ($self->{'curr_x_min'}, $y1,
+                             $self->{'curr_x_max'}, $y1,
+			     $misccolor);
+  }
+
+  
+  # create another copy of the data, but stacked
+  $data->[1] = [@{$raw->[1]}];
+  for $i (0..$self->{'num_datapoints'}-1) {
+    for $j (2..$self->{'num_datasets'}) {
+      $data->[$j][$i] = $data->[$j-1][$i] + $raw->[$j][$i];
+    }
+  }
+ 
+  # draw the damn bars
+  for $i (0..$self->{'num_datapoints'}-1) {
+    # init the y values for this datapoint
+    $y2 = $y1;
+    
+    
+    for $j (1..$self->{'num_datasets'}) {
+      # get the color
+      $color = $self->_color_role_to_index('dataset'.($j-1));
+      
+      # set up the geometry for the bar
+      if ($self->{'spaced_bars'} =~ /^true$/i) {
+        $x2 = $x1 + (2 * $i * $delta) + ($delta / 2);
+       	$x3 = $x2 + $delta;
+	
+      }
+      else {
+        $x2 = $x1 + ($i * $delta);
+        $x3 = $x2 + $delta;
+      }
+      $y3 = $y1 - (($data->[$j][$i] - $mod) * $map);
+     
+      #cut the bars off, if needed
+      if ($data->[$j][$i] > $self->{'max_val'}) {
+           $y3 = $y1 - (($self->{'max_val'} - $mod ) * $map) ;
+           $cut = 1;
+      }
+      elsif  ($data->[$j][$i] < $self->{'min_val'}) {
+           $y3 = $y1 - (($self->{'min_val'} - $mod ) * $map) ;
+           $cut = 1;
+      }
+      else {
+           $cut = 0;
+      }
+      
+      # draw the bar
+      ## y2 and y3 are reversed in some cases because GD's fill
+      ## algorithm is lame
+      if ($data->[$j][$i] > 0) {
+        $self->{'gd_obj'}->filledRectangle ($x2, $y3, $x3, $y2, $color);
+	if ($self->{'imagemap'} =~ /^true$/i) {
+	  $self->{'imagemap_data'}->[$j][$i] = [ $x2, $y3, $x3, $y2 ];
+	}
+      }
+      else {
+        $self->{'gd_obj'}->filledRectangle ($x2, $y2, $x3, $y3, $color);
+	if ($self->{'imagemap'} =~ /^true$/i) {
+	  $self->{'imagemap_data'}->[$j][$i] = [ $x2, $y2, $x3, $y3 ];
+	}
+      }
+
+      # now outline it. outline red if the bar had been cut off
+      unless ($cut){
+	  $self->{'gd_obj'}->rectangle ($x2, $y2, $x3, $y3, $misccolor);
+      }
+      else {
+          $self->{'gd_obj'}->rectangle ($x2, $y2, $x3, $y3, $misccolor);
+          $self->{'gd_obj'}->rectangle ($x2, $y1, $x3, $y3, $pink);
+      }
+
+      # now bootstrap the y values
+      $y2 = $y3; 
+    }
+  }
+
+  
+  # and finaly box it off 
+  $self->{'gd_obj'}->rectangle ($self->{'curr_x_min'},
+  				$self->{'curr_y_min'},
+ 				$self->{'curr_x_max'},
+ 				$self->{'curr_y_max'},
+ 				$misccolor);
+  return;
+  
+}
+
+
+
+sub _draw_left_legend {
+  my $self = shift;
+  my @labels = @{$self->{'legend_labels'}};
+  my ($x1, $x2, $x3, $y1, $y2, $width, $color, $misccolor, $w, $h, $brush);
+  my $font = $self->{'legend_font'};
+ 
+  # make sure we're using a real font
+  unless ((ref ($font)) eq 'GD::Font') {
+    croak "The subtitle font you specified isn\'t a GD Font object";
+  }
+
+  # get the size of the font
+  ($h, $w) = ($font->height, $font->width);
+
+  # get the miscellaneous color
+  $misccolor = $self->_color_role_to_index('misc');
+
+  # find out how wide the largest label is
+  $width = (2 * $self->{'text_space'})
+    + ($self->{'max_legend_label'} * $w)
+    + $self->{'legend_example_size'}
+    + (2 * $self->{'legend_space'});
+
+  # get some base x-y coordinates
+  $x1 = $self->{'curr_x_min'};
+  $x2 = $self->{'curr_x_min'} + $width;
+  $y1 = $self->{'curr_y_min'} + $self->{'graph_border'} ;
+  $y2 = $self->{'curr_y_min'} + $self->{'graph_border'} + $self->{'text_space'}
+          + ($self->{'num_datasets'} * ($h + $self->{'text_space'}))
+	  + (2 * $self->{'legend_space'});
+
+  # box the legend off
+  $self->{'gd_obj'}->rectangle ($x1, $y1, $x2, $y2, $misccolor);
+
+  # leave that nice space inside the legend box
+  $x1 += $self->{'legend_space'};
+  $y1 += $self->{'legend_space'} + $self->{'text_space'};
+
+  # now draw the actual legend
+  for (0..$#labels) {
+    # get the color
+    my $c = $self->{'num_datasets'}-$_-1;
+    # color of the datasets in the legend
+    if ($self->{'dataref'}[1][0] <0) {
+        $color = $self->_color_role_to_index('dataset'.$_);
+    }
+    else {
+        $color = $self->_color_role_to_index('dataset'.$c);
+    }
+
+    # find the x-y coords
+    $x2 = $x1;
+    $x3 = $x2 + $self->{'legend_example_size'};
+    $y2 = $y1 + ($_ * ($self->{'text_space'} + $h)) + $h/2;
+
+    # do the line first
+    $self->{'gd_obj'}->line ($x2, $y2, $x3, $y2, $color);
+
+    # reset the brush for points
+    $brush = $self->_prepare_brush($color, 'point',
+				$self->{'pointStyle' . $_});
+    $self->{'gd_obj'}->setBrush($brush);
+    # draw the point
+    $self->{'gd_obj'}->line(int(($x3+$x2)/2), $y2,
+				int(($x3+$x2)/2), $y2, gdBrushed);
+    
+    # now the label
+    $x2 = $x3 + (2 * $self->{'text_space'});
+    $y2 -= $h/2;
+    # order of the datasets in the legend
+    if ($self->{'dataref'}[1][0] <0) {
+        $self->{'gd_obj'}->string ($font, $x2, $y2, $labels[$_], $color);
+    }
+    else {
+        $self->{'gd_obj'}->string ($font, $x2, $y2, $labels[$c], $color);
+    }
+  }
+
+  # mark off the used space
+  $self->{'curr_x_min'} += $width;
+
+  # and return
+  return 1;
+}
+
+
+sub _draw_right_legend {
+  my $self = shift;
+  my @labels = @{$self->{'legend_labels'}};
+  my ($x1, $x2, $x3, $y1, $y2, $width, $color, $misccolor, $w, $h, $brush);
+  my $font = $self->{'legend_font'};
+ 
+  # make sure we're using a real font
+  unless ((ref ($font)) eq 'GD::Font') {
+    croak "The subtitle font you specified isn\'t a GD Font object";
+  }
+
+  # get the size of the font
+  ($h, $w) = ($font->height, $font->width);
+
+  # get the miscellaneous color
+  $misccolor = $self->_color_role_to_index('misc');
+
+  # find out how wide the largest label is
+  $width = (2 * $self->{'text_space'})
+    + ($self->{'max_legend_label'} * $w)
+    + $self->{'legend_example_size'}
+    + (2 * $self->{'legend_space'});
+
+  # get some starting x-y values
+  $x1 = $self->{'curr_x_max'} - $width;
+  $x2 = $self->{'curr_x_max'};
+  $y1 = $self->{'curr_y_min'} + $self->{'graph_border'} ;
+  $y2 = $self->{'curr_y_min'} + $self->{'graph_border'} + $self->{'text_space'}
+          + ($self->{'num_datasets'} * ($h + $self->{'text_space'}))
+	  + (2 * $self->{'legend_space'});
+
+  # box the legend off
+  $self->{'gd_obj'}->rectangle ($x1, $y1, $x2, $y2, $misccolor);
+
+  # leave that nice space inside the legend box
+  $x1 += $self->{'legend_space'};
+  $y1 += $self->{'legend_space'} + $self->{'text_space'};
+
+  
+  # now draw the actual legend
+  for (0..$#labels) {
+    # get the color
+    my $c = $self->{'num_datasets'}-$_-1;
+    # color of the datasets in the legend  
+     
+   
+    if ($self->{'dataref'}[1][0] < 0) {
+        $color = $self->_color_role_to_index('dataset'.$_);
+    }
+    else {	
+        $color = $self->_color_role_to_index('dataset'.$c);
+    }
+
+    # find the x-y coords
+    $x2 = $x1;
+    $x3 = $x2 + $self->{'legend_example_size'};
+    $y2 = $y1 + ($_ * ($self->{'text_space'} + $h)) + $h/2;
+
+    # do the line first
+    $self->{'gd_obj'}->line ($x2, $y2, $x3, $y2, $color);
+
+    # reset the brush for points
+    $brush = $self->_prepare_brush($color, 'point',
+				$self->{'pointStyle' . $_});
+    $self->{'gd_obj'}->setBrush($brush);
+    # draw the point
+    $self->{'gd_obj'}->line(int(($x3+$x2)/2), $y2,
+				int(($x3+$x2)/2), $y2, gdBrushed);
+
+    # now the label
+    $x2 = $x3 + (2 * $self->{'text_space'});
+    $y2 -= $h/2;
+    # order of the datasets in the legend
+    if ($self->{'dataref'}[1][0] <0) {
+        $self->{'gd_obj'}->string ($font, $x2, $y2, $labels[$_], $color);
+    }
+    else {
+        $self->{'gd_obj'}->string ($font, $x2, $y2, $labels[$c], $color);
+    }
+  }
+
+  # mark off the used space
+  $self->{'curr_x_max'} -= $width;
+
+  # and return
+  return 1;
+}
+
+## be a good module and return 1
+1;

Added: packages/libchart-perl/branches/upstream/current/Chart.pod
===================================================================
--- packages/libchart-perl/branches/upstream/current/Chart.pod	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/Chart.pod	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,752 @@
+=head1 NAME
+
+Chart - a series of charting modules 
+
+=head1 SYNOPSIS 
+
+    use Chart::type;   (type is one of: Points, Lines, Bars, LinesPoints, Composite,
+    StackedBars, Mountain, Pie, HorizontalBars, Split, ErrorBars, Pareto, Direction) 
+
+    $obj = Chart::type->new;
+    $obj = Chart::type->new ( $png_width, $png_height );
+
+    $obj->set ( $key_1, $val_1, ... ,$key_n, $val_n );
+    $obj->set ( $key_1 => $val_1,
+	        ...
+	        $key_n => $val_n );
+    $obj->set ( %hash );
+
+    # GIFgraph.pm-style API to produce png formatted charts
+    @data = ( \@x_tick_labels, \@dataset1, ... , \@dataset_n );
+    $obj->png ( "filename", \@data );
+    $obj->png ( $filehandle, \@data );
+    $obj->png ( FILEHANDLE, \@data );
+    $obj->cgi_png ( \@data );
+
+    # Graph.pm-style API
+    $obj->add_pt ($label, $val_1, ... , $val_n);
+    $obj->add_dataset ($val_1, ... , $val_n);
+    $obj->png ( "filename" );
+    $obj->png ( $filehandle );
+    $obj->png ( FILEHANDLE );
+    $obj->cgi_png ();
+
+    The similiar functions are available for jpeg
+
+    # Retrieve imagemap information
+    $obj->set ( 'imagemap' => 'true' );
+    $imagemap_ref = $obj->imagemap_dump ();
+
+
+=head1 DESCRIPTION
+
+These manpages give you the most important information about Chart.
+There is also a complete documentation (Documentation.pdf) within
+the Chart package. Look at it to get more information.
+This module is an attempt to build a general purpose graphing module
+that is easily modified and expanded.  I borrowed most of the API
+from Martien Verbruggen's GIFgraph module.  I liked most of GIFgraph,
+but I thought it was to difficult to modify, and it was missing a few
+things that I needed, most notably legends.  So I decided to write
+a new module from scratch, and I've designed it from the bottom up
+to be easy to modify.  Like GIFgraph, Chart uses Lincoln Stein's GD 
+module for all of its graphics primitives calls.
+
+=head2 use-ing Chart
+
+Okay, so you caught me.  There's really no Chart::type module.
+All of the different chart types (Points, Lines, Bars, LinesPoints,
+Composite, StackedBars, Pie, Pareto, HorizontalBars, Split, ErrorBars,
+Direction and Mountain so far) are classes by themselves, each inheriting 
+a bunch of methods from the Chart::Base class.  Simply replace
+the word type with the type of chart you want and you're on your way.  
+For example,
+
+  use Chart::Lines;
+
+would invoke the lines module.
+
+=head2 Getting an object
+
+The new method can either be called without arguments, in which
+case it returns an object with the default image size (400x300 pixels),
+or you can specify the width and height of the image.  Just remember
+to replace type with the type of graph you want.  For example,
+
+  $obj = Chart::Bars->new (600,400);
+
+would return a Chart::Bars object containing a 600x400 pixel
+image.  New also initializes most of the default variables, which you 
+can subsequently change with the set method.
+
+
+=head2 Setting different options
+
+This is where the fun begins.  Set looks for a hash of keys and
+values.  You can pass it a hash that you've already constructed, like
+
+  %hash = ('title' => 'Foo Bar');
+  $obj->set (%hash);
+
+or you can try just constructing the hash inside the set call, like
+
+  $obj->set ('title' => 'Foo Bar');
+
+The following are all of the currently supported options:
+
+=over 4
+
+=item 'transparent'
+
+Makes the background of the image transparent if set to 'true'.  Useful
+for making web page images.  Default is 'false'.
+
+=item 'png_border'
+
+Sets the number of pixels used as a border between the graph
+and the edges of the png/jpeg.  Defaults to 10.
+
+=item 'graph_border'
+
+Sets the number of pixels used as a border between the title/labels
+and the actual graph within the png.  Defaults to 10.
+
+=item 'text_space'
+
+Sets the amount of space left on the sides of text, to make it more
+readable.  Defaults to 2.
+
+=item 'title'
+
+Tells GD graph what to use for the title of the graph.  If empty,
+no title is drawn.  It recognizes '\n' as a newline, and acts accordingly.
+Remember, if you want to use normal quotation marks insted of single 
+quotation marks then you have to qoute "\\n". Default is empty.
+
+=item 'sub_title'
+
+Write a sub-title under the title in smaller letters.
+ 
+=item 'x_label'
+
+Tells Chart what to use for the x-axis label.  If empty, no label
+is drawn.  Default is empty.
+
+=item 'y_label', 'y_label2'
+
+Tells Chart what to use for the y-axis labels.  If empty, no label
+is drawn.  Default is empty.
+
+=item 'legend'
+
+Specifies the placement of the legend.  Valid values are 'left', 'right',
+'top', 'bottom'.  Setting this to 'none' tells chart not to draw a
+legend.  Default is 'right'.
+
+=item 'legend_labels'
+
+Sets the values for the labels for the different datasets.  Should
+be assigned a reference to an array of labels.  For example,
+
+  @labels = ('foo', 'bar');
+  $obj->set ('legend_labels' => \@labels);
+
+Default is empty, in which case 'Dataset 1', 'Dataset 2', etc. are
+used as the labels.  
+
+
+=item 'tick_len'
+
+Sets the length of the x- and y-ticks in pixels.  Default is 4. 
+
+=item 'x_ticks'
+
+Specifies how to draw the x-tick labels.  Valid values are 'normal',
+'staggered' (staggers the labels vertically), and 'vertical' (the
+labels are draw upwards).  Default is 'normal'.
+
+=item 'xy_plot'
+
+Forces Chart to plot a x-y-graph, which means, that the x-axis is also
+numeric if set to 'true'. Very usefull for mathematical graphs.
+Works for Lines, Points, LinesPoints and ErrorBars. Split makes always a 
+xy_plot. Defaults to 'false'.
+
+=item 'min_y_ticks'
+
+Sets the minimum number of y_ticks to draw when generating a scale.
+Default is 6, The minimum is 2.
+
+=item 'max_y_ticks'
+
+Sets the maximum number of y_ticks to draw when generating a scale.
+Default is 100. This limit is used to avoid ploting an unreasonably
+large number of ticks if non-round values are used for the min_val
+and max_val.
+
+The value for 'max_y_ticks' should be at least 5 times larger than
+'min_y_ticks'.
+
+=item 'max_x_ticks', 'min_x_ticks'
+
+Work similar as 'max_y_ticks' and 'min_y_ticks'. Of course, only for a 
+xy_plot.
+
+=item 'integer_ticks_only'
+
+Specifies how to draw the x- and y-ticks: as floating point 
+('false', '0') or as integer numbers ('true', 1). Default: 'false'
+
+=item 'skip_int_ticks'
+
+If 'integer_ticks_only' was set to 'true' the labels and ticks will 
+be drawn every nth tick. Of course in horizontalBars it affects th
+x-axis. Default to 1, no skipping. 
+
+=item 'precision'
+
+Sets the number of numerals after the decimal point. Affects in most
+cases the y-axis. But also the x-axis if 'xy_plot' was set and also
+the labels in a pie chart. Defaults to 3. 
+
+=item 'max_val'
+
+Sets the maximum y-value on the graph, overriding the normal auto-scaling.
+Default is undef.
+
+=item 'min_val'
+
+Sets the minimum y-value on the graph, overriding the normal auto-scaling.
+Default is undef.
+
+Caution should be used when setting 'max_val' and 'min_val' to floating
+point or non-round numbers. This is because the scale must start & end
+on a tick, ticks must have round-number intervals, and include round
+numbers.
+
+Example: Suppose your dataset has a range of 35-114 units, If you specify
+them as the 'min_val' & 'max_val', The y_axis will be ploted with 80 ticks
+every 1 unit.. If no 'min_val' & 'max_val', the system will autoscale the
+range to 30-120 with 10 ticks every 10 units.
+
+If the 'min_val' & 'max_val' are specifed to exesive precision, they may
+be overiden by the system, ploting a maximum 'max_y_ticks' ticks.
+
+=item 'include_zero'
+
+If 'true', forces the y-axis to include zero if it is not in the dataset
+range. Default is 'false'.
+
+In general, it is better to use this, than to set the 'min_val' if that
+is all you want to acheve.
+
+=item 'pt_size'
+
+Sets the radius of the points (for Chart::Points, etc.) in pixels.  
+Default is 18.
+
+=item 'brush_size'
+
+Sets the width of the lines (for Chart::Lines, etc.) in pixels.
+Default is 6.
+
+=item 'skip_x_ticks'
+
+Sets the number of x-ticks and x-tick labels to skip.  (ie.  
+if 'skip_x_ticks' was set to 4, Chart would draw every 4th x-tick
+and x-tick label).  Default is undef.
+
+=item 'custom_x_ticks'
+
+Used in points, lines, linespoints, errorbars and bars charts, this option
+allows you to specify exatly which x-ticks and x-tick labels should
+be drawn.  It should be assigned a reference to an array of desired
+ticks.  Just remember that I'm counting from the 0th element of the
+array.  (ie., if 'custom_x_ticks' is assigned [0,3,4], then the 0th,
+3rd, and 4th x-ticks will be displayed)
+
+=item 'f_x_tick'
+
+Needs a reference to a function which uses the x-tick labels generated by
+the '@data->[0]' as the argument. The result of this function can reformat
+the labels. For instance
+
+   $obj -> set ('f_x_tick' => \&formatter );
+
+An example for the function formatter: x labels are seconds since an event. 
+The referenced function can transformat this seconds to hour, minutes and seconds.
+ 
+=item 'f_y_tick'
+
+The same situation as for 'f_x_tick' but now used for y labels.
+ 
+=item 'colors'
+
+This option lets you control the colors the chart will use.  It takes
+a reference to a hash.  The hash should contain keys mapped to references
+to arrays of rgb values.  For instance,
+
+	$obj->set('colors' => {'background' => [255,255,255]});
+
+sets the background color to white (which is the default).  Valid keys for
+this hash are
+
+	'background' (background color for the png)
+	'title' (color of the title)
+	'text' (all the text in the chart)
+	'x_label' (color of the x-axis label)
+	'y_label' (color of the first y axis label)
+	'y_label2' (color of the second y axis label)
+	'grid_lines' (color of the grid lines)
+	'x_grid_lines' (color of the x grid lines - for x axis ticks)
+	'y_grid_lines' (color of the y grid lines - for to left y axis ticks)
+	'y2_grid_lines' (color of the y2 grid lines - for right y axis ticks)
+	'dataset0'..'dataset63' (the different datasets)
+	'misc' (everything else, ie. ticks, box around the legend)
+
+NB. For composite charts, there is a limit of 8 datasets per component.
+The colors for 'dataset8' through 'dataset15' become the colors
+for 'dataset0' through 'dataset7' for the second component chart.
+
+=item 'title_font'
+
+This option changes the font of the title. The key has to be a GD font. 
+eg. GD::Font->Large
+
+=item 'label_font'
+
+This option changes the font of the labels. The key has to be a GD font. 
+
+=item 'legend_font'
+
+This option changes the font of the text in the legend. 
+The key has to be a GD font. 
+
+=item 'tick_label_font' 
+
+This is the font for the tick labels. It also needs 
+a GD font object as an argument.
+
+=item 'grey_background'
+
+Puts a nice soft grey background on the actual data plot when
+set to 'true'.  Default is 'true'.
+
+=item 'y_axes'
+
+Tells Chart where to place the y-axis. Has no effect on Composite and Pie.
+Valid values are 'left', 'right' and 'both'. Defaults to 'left'.
+
+=item 'x_grid_lines'
+
+Draws grid lines matching up to x ticks if set to 'true'. Default is false.
+
+=item 'y_grid_lines'
+
+Draws grid lines matching up to y ticks if set to 'true'. Default is false.
+
+=item 'grid_lines'
+
+Draws grid lines matching up to x and y ticks. 
+
+=item 'spaced_bars'
+
+Leaves space between the groups of bars at each data point when set
+to 'true'.  This just makes it easier to read a bar chart.  Default
+is 'true'.
+
+=item 'imagemap'
+
+Lets Chart know you're going to ask for information about the placement
+of the data for use in creating an image map from the png.  This information
+can be retrieved using the imagemap_dump() method.  NB. that the 
+imagemap_dump() method cannot be called until after the Chart has been
+generated (ie. using the png() or cgi_png() methods).
+
+=item 'sort'
+
+In a xy-plot, the data will be sorted ascending if set to 'true'.
+(Should be set if the data isn't sorted, especially in Lines, Split 
+and LinesPoints) In a Pareto Chart the data will be sorted descending. 
+Defaults to 'false'.
+
+=item 'composite_info'
+
+This option is only used for composite charts.  It contains the
+information about which types to use for the two component charts,
+and which datasets belong to which component chart. It should be
+a reference to an array of array references, containing information 
+like the following
+
+	$obj->set ('composite_info' => [ ['Bars', [1,2]],
+					 ['Lines', [3,4] ] ]);
+
+This example would set the two component charts to be a bar chart and
+a line chart.  It would use the first two data sets for the bar 
+chart (note that the numbering starts at 1, not zero like most of
+the other numbered things in Chart), and the second two data sets
+for the line chart.  The default is undef.
+
+NB. Chart::Composite can only do two component charts.
+
+=item 'min_val1', 'min_val2'
+
+Only for composite charts, these options specify the minimum y-value
+for the first and second components respectively.  Both default to
+undef.
+
+=item 'max_val1', 'max_val2'
+
+Only for composite charts, these options specify the maximum y-value
+for the first and second components respectively.  Both default to
+undef.
+
+=item 'ylabel2'
+
+The label for the right y-axis (the second component chart) on a composite
+chart.  Default is undef.
+
+=item 'y_ticks1', 'y_ticks2'
+
+The number of y ticks to use on the first and second y-axis on a composite
+chart.  Please note that if you just set the 'y_ticks' option, both axes 
+will use that number of y ticks.  Both default to undef.
+
+=item 'f_y_ticks1', 'f_y_ticks2'
+
+Only for composite charts, needs a reference to a function 
+which has one argument and has to return
+a string which labels the first resp. second y axis.
+Both default to undef.
+
+=item 'same_y_axes'
+
+Forces both component charts in a composite chart to use the same maximum 
+and minimum y-values if set to 'true'.  This helps to keep the composite 
+charts from being too confusing.  Default is undef.
+
+=item 'no_cache'
+
+Adds Pragma: no-cache to the http header.  Be careful with this one, as
+Netscape 4.5 is unfriendly with POST using this method.
+
+=item 'legend_example_size'
+
+Sets the length of the example line in the legend in pixels. Defaults to 20.
+
+=item 'same_error'
+
+This is a option only for ErrorBars. It tells chart that you want use the same 
+error value of a data point if set to 'true'. Look at the documentation
+to see how the module ErrorBars works. Default: 'false'.
+
+=item 'skip_y_ticks'
+
+Does the same for the y-axis at a HorizontalBars chart as 'skip_x_ticks'
+does for other charts. Defaults to 1.
+
+=item 'label_values' 
+
+Tells a pie chart what labels to draw beside the pie. Valid values are
+'percent', 'value', 'both' and 'none'. Defaults to 'percent'.
+
+=item 'legend_label_values'
+
+Tells a pie chart what labels to draw in the legende. Valid values are
+'percent', 'value', 'both' and 'none'. Defaults to 'value'.
+
+=item 'start'
+
+Required value for a split chart. Sets the start value of the first interval.
+If the x coordinate of the first data point is zero, you should 'set' to
+zero. Default is 'undef'.
+
+=item 'interval'
+
+Also a required value for a split chart. It sets the interval of one line
+to plot. Defaults 'undef'.
+
+=item 'interval_ticks'
+
+Sets the number of ticks for the x-axis of a Split chart. Defaults to 5.
+
+=item 'scale'
+
+Every y-value of a split chart will be multiplied with that value, but
+the scale won't change. Which means that split allows to overdraw certain 
+rows! Only useful if you want to give prominence to the maximal amplitudes
+of the data. Defaults to 1. 
+
+=item 'point'
+
+Indicates to draw points in a direction chart. 'true' or 'false' possible. 
+Defaults to 'true'.
+
+=item 'line'
+
+If you turn this optin to 'true', then direction will connect the points 
+with lines. Defaults to 'false'.
+
+=item 'arrow'
+
+This is also an option for the direction module. If set to 'true', chart 
+will draw a arrow from the center to the point. Defaults to 'false'.
+
+=item 'angle_interval'
+
+This option tells direction, how many angle lines should be drawn. The
+default value is 30, which means that a line will be drawn eyery
+30 degrees. Valid Values are: 0, 5, 10, 15, 20, 30, 45 and 60. If you
+choose 0, direction will draw no line.
+
+=item 'min_circles'
+
+Sets the minimum number of circles when generating a scale for direction.
+Default is 4, minimum is 2.
+
+=item 'max_circles'
+
+Sets the maximum number of circles when generating a scale for direction.
+Default is 100. This limit is used to avoid plotting  an unreasonable 
+large number of ticks if non-round values are used for the min_val and
+max_val.
+
+=item 'pairs'
+
+Only used for direction how to handle more datasets. 
+               If 'pairs' is set to 'true', 
+               Chart uses the first dataset as a set of degrees and 
+               the second dataset as a set of values. 
+               Then, the third set is a set of degrees und the fourth a set of values \dots. \\
+               If 'pairs' is set to 'false', 
+               Chart uses the first dataset as a set of angels 
+               and all following datasets as sets of values.
+               Defaults to 'false'.
+
+Sets the maximum number of circles when generating a scale for direction.
+Default is 100. This limit is used to avoid plotting  an unreasonable 
+large number of ticks if non-round values are used for the min_val and
+max_val.
+
+=back
+
+=head2 GIFgraph.pm-style API
+
+=over 4
+
+=item Sending the image to a file
+
+Invoking the png method causes the graph to be plotted and saved to 
+a file.  It takes the name of the output file and a reference to the
+data as arguments.  For example,
+
+  $obj->png ("foo.png", \@data);
+
+would plot the data in @data, and the save the image to foo.png.
+Of course, this then beggars the question "What should @data look
+like?".  Well, just like GIFgraph, @data should contain references
+to arrays of data, with the first array reference pointing to an
+array of x-tick labels.  For example,
+
+  @data = ( [ 'foo', 'bar', 'junk' ],
+	    [ 30.2,  23.5,  92.1   ] );
+
+would set up a graph with one dataset, and three data points in that
+set.  In general, the @data array should look something like
+
+  @data = ( \@x_tick_labels, \@dataset1, ... , \@dataset_n );
+
+And no worries, I make my own internal copy of the data, so that it doesn't
+mess with yours.
+
+=item CGI and Chart
+
+Okay, so you're probably thinking, "Do I always have to save these images
+to disk?  What if I want to use Chart to create dynamic images for my
+web site?"  Well, here's the answer to that.
+
+  $obj->cgi_png ( \@data );
+
+The cgi_png method will print the chart, along with the appropriate http
+header, to stdout, allowing you to call chart-generating scripts directly
+from your html pages (ie. with a <lt>img src=image.pl<gt> HTML tag).  The @data
+array should be set up the same way as for the normal png method.
+
+=back
+
+=head2 Graph.pm-style API
+
+You might ask, "But what if I just want to add a few points to the graph, 
+and then display it, without all those references to references?".  Well,
+friend, the solution is simple.  Borrowing the add_pt idea from Matt
+Kruse's Graph module, you simply make a few calls to the add_pt method,
+like so:
+
+    $obj->add_pt ('foo', 30, 25);
+    $obj->add_pt ('bar', 16, 32);
+
+Or, if you want to be able to add entire datasets, simply use the add_dataset
+method:
+
+    $obj->add_dataset ('foo', 'bar');
+    $obj->add_dataset (30, 16);
+    $obj->add_dataset (25, 32);
+
+These methods check to make sure that the points and datasets you are
+adding are the same size as the ones already there.  So, if you have
+two datasets currently stored, and try to add a data point with three
+different values, it will carp (per the Carp module) an error message.
+Similarly, if you try to add a dataset with 4 data points,
+and all the other datasets have 3 data points, it will carp an error
+message.
+
+Don't forget, when using this API, that I treat the first dataset as
+a series of x-tick labels.  So, in the above examples, the graph would
+have two x-ticks, labeled 'foo' and 'bar', each with two data points.
+Pie and ErrorBars handle it different, look at the documentation
+to see how it works.
+
+=over 4
+
+=item Adding a datafile
+
+You can also add a complete datafile to a chart object. Just use the
+add_datafile() method.
+
+	$obj->add_datafile('file', 'set' or 'pt');
+
+file can be the name of the data file or a filehandle. 
+'set' or 'pt is the type of the datafile. 
+If the parameter is 'set' then each line in the data file
+has to be a complete data set. The value of the set has to be 
+seperated by whitespaces. For example the file looks like this:
+
+	'foo'  'bar'
+	30     16
+	25     32
+
+If the parameter is 'pt', one line has to include all values
+of one data point seperated by whitespaces. For example:
+
+	'foo'  30  25
+	'bar'  16  32
+
+
+=item Clearing the data
+
+A simple call to the clear_data method empties any values that may
+have been entered.
+
+    $obj->clear_data ();
+
+=item Getting a copy of the data
+
+If you want a copy of the data that has been added so far, make a call
+to the get_data method like so:
+
+    	$dataref = $obj->get_data;
+
+It returns (you guessed it!) a reference to an array of references to
+datasets.  So the x-tick labels would be stored as
+
+    	@x_labels = @{$dataref->[0]};
+
+=item Sending the image to a file
+
+If you just want to print this chart to a file, all you have to do
+is pass the name of the file to the png() method.
+
+  	$obj->png ("foo.png");
+
+=item Sending the image to a filehandle
+
+If you want to do something else with the image, you can also pass
+a filehandle (either a typeglob or a FileHandle object) to png, and
+it will print directly to that.
+
+	$obj->png ($filehandle);
+	$obj->png (FILEHANDLE);
+
+
+=item CGI and Chart
+
+Okay, so you're probably thinking (again), "Do I always have to save these 
+images to disk?  What if I want to use Chart to create dynamic images for
+my web site?"  Well, here's the answer to that.
+
+  	$obj->cgi_png ();
+
+The cgi_png method will print the chart, along with the appropriate http
+header, to stdout, allowing you to call chart-generating scripts directly
+from your html pages (ie. with a <lt>img src=image.pl<gt> HTML tag). 
+
+=back
+
+=head2 Imagemap Support
+
+Chart can also return the pixel positioning information so that you can
+create image maps from the pngs Chart generates.  Simply set the 'imagemap'
+option to 'true' before you generate the png, then call the imagemap_dump()
+method afterwards to retrieve the information.  You will be returned a
+data structure almost identical to the @data array described above to pass
+the data into Chart.
+
+	$imagemap_data = $obj->imagemap_dump ();
+
+Instead of single data values, you will be passed references to arrays
+of pixel information.  For Bars, HorizontalBars and StackedBars charts, 
+the arrays will contain two x-y pairs (specifying the upper left and 
+lower right corner of the bar), like so
+
+	( $x1, $y1, $x2, $y2 ) = @{ $imagemap_data->[$dataset][$datapoint] };
+
+For Lines, Points, ErrorBars, Split and LinesPoints, the arrays will contain 
+a single x-y pair (specifying the center of the point), like so
+
+	( $x, $y ) = @{ $imagemap_data->[$dataset][$datapoint] };
+
+A few caveats apply here.  First of all, GD treats the upper-left corner
+of the png as the (0,0) point, so positive y values are measured from the
+top of the png, not the bottom.  Second, these values will most likely
+contain long decimal values.  GD, of course, has to truncate these to 
+single pixel values.  Since I don't know how GD does it, I can't truncate
+it the same way he does.  In a worst-case scenario, this will result in
+an error of one pixel on your imagemap.  If this is really an issue, your
+only option is to either experiment with it, or to contact Lincoln Stein
+and ask him.  Third, please remember that the 0th dataset will be empty,
+since that's the place in the @data array for the data point labels.
+
+
+=head1 TO DO
+
+=over 4
+
+
+=item *
+
+Add some 3-D graphs.
+Include True Type Fonts
+
+=back
+
+=head1 BUGS
+
+Probably quite a few, since it's been completely rewritten.  As usual,
+please mail me with any bugs, patches, suggestions, comments, flames,
+death threats, etc.
+
+=head1 AUTHOR
+
+David Bonner (dbonner at cs.bu.edu)
+
+=head1 MAINTAINER
+
+Chart Group (Chart at wettzell.ifag.de)
+
+=head1 COPYRIGHT
+
+Copyright(c) 1997-1998 by David Bonner, 1999 by Peter Clark,
+2001 by the Chart group at BKG-Wettzell.
+All rights reserved.  This program is free software; you can
+redistribute it and/or modify it under the same terms as Perl 
+itself.

Added: packages/libchart-perl/branches/upstream/current/Documentation.pdf
===================================================================
(Binary files differ)


Property changes on: packages/libchart-perl/branches/upstream/current/Documentation.pdf
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:mime-type
   + application/octet-stream

Added: packages/libchart-perl/branches/upstream/current/MANIFEST
===================================================================
--- packages/libchart-perl/branches/upstream/current/MANIFEST	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/MANIFEST	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,150 @@
+Chart.pod
+Chart/Bars.pm
+Chart/Base.pm
+Chart/Composite.pm
+Chart/Direction.pm
+Chart/ErrorBars.pm
+Chart/HorizontalBars.pm
+Chart/Lines.pm
+Chart/LinesPoints.pm
+Chart/Mountain.pm
+Chart/Pareto.pm
+Chart/Pie.pm
+Chart/Points.pm
+Chart/Split.pm
+Chart/StackedBars.pm
+doc/LaTeX/Aufbau.png
+doc/LaTeX/Aufbau1.png
+doc/LaTeX/bars.tex
+doc/LaTeX/base.tex
+doc/LaTeX/composite.png
+doc/LaTeX/composite.tex
+doc/LaTeX/composite_f.png
+doc/LaTeX/d_bars.png
+doc/LaTeX/d_hbars4.png
+doc/LaTeX/d_lines2.png
+doc/LaTeX/d_linesp2.png
+doc/LaTeX/d_pareto2.png
+doc/LaTeX/d_pie3.png
+doc/LaTeX/definitions.tex
+doc/LaTeX/description.tex
+doc/LaTeX/direction.png
+doc/LaTeX/direction.tex
+doc/LaTeX/Documentation.dvi
+doc/LaTeX/Documentation.pdf
+doc/LaTeX/Documentation.tex
+doc/LaTeX/Elemente.png
+doc/LaTeX/error.png
+doc/LaTeX/error.tex
+doc/LaTeX/example.tex
+doc/LaTeX/hbars.tex
+doc/LaTeX/lines.tex
+doc/LaTeX/linespoints.tex
+doc/LaTeX/mountain-1.png
+doc/LaTeX/mountain.png
+doc/LaTeX/mountain.tex
+doc/LaTeX/ort.png
+doc/LaTeX/pareto.tex
+doc/LaTeX/pie.tex
+doc/LaTeX/points.png
+doc/LaTeX/points.tex
+doc/LaTeX/split.tex
+doc/LaTeX/stacked.tex
+doc/LaTeX/stackedbars.png
+doc/LaTeX/stunde.png
+Documentation.pdf
+Makefile
+Makefile.PL
+MANIFEST			This list of files
+MANIFEST.SKIP
+META.yml
+patterns/PATTERN0.GIF
+patterns/PATTERN0.PNG
+patterns/PATTERN1.GIF
+patterns/PATTERN1.PNG
+patterns/PATTERN2.GIF
+patterns/PATTERN2.PNG
+patterns/PATTERN3.GIF
+patterns/PATTERN3.PNG
+patterns/PATTERN4.GIF
+patterns/PATTERN4.PNG
+patterns/PATTERN5.GIF
+patterns/PATTERN5.PNG
+pm_to_blib
+README
+rgb.txt
+t/bars.t
+t/bars_10.t
+t/bars_2.t
+t/bars_3.t
+t/bars_4.t
+t/bars_5.t
+t/bars_6.t
+t/bars_7.t
+t/bars_8.t
+t/bars_9.t
+t/composite.png
+t/composite.t
+t/composite_1.t
+t/composite_2.t
+t/composite_3.t
+t/composite_4.t
+t/composite_5.t
+t/composite_6.t
+t/composite_f.t
+t/direction_1.t
+t/direction_2.t
+t/direction_3.t
+t/direction_4.t
+t/error_1.t
+t/error_2.t
+t/f_ticks.t
+t/hbars_1.t
+t/hbars_2.t
+t/hbars_3.t
+t/hbars_4.t
+t/Humidity.t
+t/lines.t
+t/lines_1.t
+t/lines_2.t
+t/lines_3.t
+t/lines_4.t
+t/lines_5.t
+t/lines_6.t
+t/lines_7.t
+t/lines_8.t
+t/linespoints.t
+t/linespoints_1.t
+t/linespoints_2.t
+t/linespoints_3.t
+t/linespoints_4.t
+t/linespoints_5.t
+t/linespoints_6.t
+t/linespoints_7.t
+t/mapbars.t
+t/mapcomp.t
+t/Math_1_over_x.t
+t/mountain.t
+t/mountain_2.t
+t/pareto_1.t
+t/pareto_2.t
+t/pareto_3.t
+t/pie_1.t
+t/pie_10.t
+t/pie_2.t
+t/pie_3.t
+t/pie_4.t
+t/pie_5.t
+t/pie_6.t
+t/pie_7.t
+t/pie_8.t
+t/pie_9.t
+t/points.t
+t/points_100.t
+t/points_2.t
+t/split_1.t
+t/split_2.t
+t/stackedbars.t
+t/stackedbars_2.t
+t/stackedbars_3.t
+TODO

Added: packages/libchart-perl/branches/upstream/current/MANIFEST.SKIP
===================================================================
--- packages/libchart-perl/branches/upstream/current/MANIFEST.SKIP	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/MANIFEST.SKIP	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,24 @@
+.exists$
+.aux$
+.bak$
+.idx$
+.ilg$
+.ind$
+.lof$
+.log$
+.lot$
+.ps$
+.tcp$
+.toc$
+.tps$
+.v0$
+.v1$
+CVS/
+.tar$
+.tar.gz$
+^test/
+^tt/
+Publications/
+samples/
+samples_tt/
+blib/

Added: packages/libchart-perl/branches/upstream/current/META.yml
===================================================================
--- packages/libchart-perl/branches/upstream/current/META.yml	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/META.yml	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,11 @@
+# http://module-build.sourceforge.net/META-spec.html
+#XXXXXXX This is a prototype!!!  It will change in the future!!! XXXXX#
+name:         Chart
+version:      2.4.1
+version_from: 
+installdirs:  site
+requires:
+    GD:                            1.2
+
+distribution_type: module
+generated_by: ExtUtils::MakeMaker version 6.17

Added: packages/libchart-perl/branches/upstream/current/Makefile
===================================================================
--- packages/libchart-perl/branches/upstream/current/Makefile	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/Makefile	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,786 @@
+# This Makefile is for the Chart extension to perl.
+#
+# It was generated automatically by MakeMaker version
+# 6.17 (Revision: 1.133) from the contents of
+# Makefile.PL. Don't edit this file, edit Makefile.PL instead.
+#
+#       ANY CHANGES MADE HERE WILL BE LOST!
+#
+#   MakeMaker ARGV: ()
+#
+#   MakeMaker Parameters:
+
+#     NAME => q[Chart]
+#     PREREQ_PM => { GD=>q[1.2] }
+#     VERSION => q[2.4.1]
+#     dist => { COMPRESS=>q[gzip], SUFFIX=>q[gz] }
+
+# --- MakeMaker post_initialize section:
+
+
+# --- MakeMaker const_config section:
+
+# These definitions are from config.sh (via /usr/local/lib/perl5/5.8.6/alpha-dec_osf/Config.pm)
+
+# They may have been overridden via Makefile.PL or on the command line
+AR = ar
+CC = cc
+CCCDLFLAGS =  
+CCDLFLAGS =   -Wl,-rpath,/usr/local/lib/perl5/5.8.6/alpha-dec_osf/CORE
+DLEXT = so
+DLSRC = dl_dlopen.xs
+LD = ld
+LDDLFLAGS = -shared -expect_unresolved "*" -O4 -msym -std -s -L/usr/local/lib
+LDFLAGS =  -L/usr/local/lib
+LIBC = /usr/shlib/libc.so
+LIB_EXT = .a
+OBJ_EXT = .o
+OSNAME = dec_osf
+OSVERS = 5.1a
+RANLIB = :
+SITELIBEXP = /usr/local/lib/perl5/site_perl/5.8.6
+SITEARCHEXP = /usr/local/lib/perl5/site_perl/5.8.6/alpha-dec_osf
+SO = so
+EXE_EXT = 
+FULL_AR = /usr/bin/ar
+VENDORARCHEXP = 
+VENDORLIBEXP = 
+
+
+# --- MakeMaker constants section:
+AR_STATIC_ARGS = cr
+DIRFILESEP = /
+NAME = Chart
+NAME_SYM = Chart
+VERSION = 2.4.1
+VERSION_MACRO = VERSION
+VERSION_SYM = 2_4_1
+DEFINE_VERSION = -D$(VERSION_MACRO)=\"$(VERSION)\"
+XS_VERSION = 2.4.1
+XS_VERSION_MACRO = XS_VERSION
+XS_DEFINE_VERSION = -D$(XS_VERSION_MACRO)=\"$(XS_VERSION)\"
+INST_ARCHLIB = blib/arch
+INST_SCRIPT = blib/script
+INST_BIN = blib/bin
+INST_LIB = blib/lib
+INST_MAN1DIR = blib/man1
+INST_MAN3DIR = blib/man3
+MAN1EXT = 1
+MAN3EXT = 3
+INSTALLDIRS = site
+DESTDIR = 
+PREFIX = 
+PERLPREFIX = /usr/local
+SITEPREFIX = /usr/local
+VENDORPREFIX = 
+INSTALLPRIVLIB = $(PERLPREFIX)/lib/perl5/5.8.6
+DESTINSTALLPRIVLIB = $(DESTDIR)$(INSTALLPRIVLIB)
+INSTALLSITELIB = $(SITEPREFIX)/lib/perl5/site_perl/5.8.6
+DESTINSTALLSITELIB = $(DESTDIR)$(INSTALLSITELIB)
+INSTALLVENDORLIB = 
+DESTINSTALLVENDORLIB = $(DESTDIR)$(INSTALLVENDORLIB)
+INSTALLARCHLIB = $(PERLPREFIX)/lib/perl5/5.8.6/alpha-dec_osf
+DESTINSTALLARCHLIB = $(DESTDIR)$(INSTALLARCHLIB)
+INSTALLSITEARCH = $(SITEPREFIX)/lib/perl5/site_perl/5.8.6/alpha-dec_osf
+DESTINSTALLSITEARCH = $(DESTDIR)$(INSTALLSITEARCH)
+INSTALLVENDORARCH = 
+DESTINSTALLVENDORARCH = $(DESTDIR)$(INSTALLVENDORARCH)
+INSTALLBIN = $(PERLPREFIX)/bin
+DESTINSTALLBIN = $(DESTDIR)$(INSTALLBIN)
+INSTALLSITEBIN = $(SITEPREFIX)/bin
+DESTINSTALLSITEBIN = $(DESTDIR)$(INSTALLSITEBIN)
+INSTALLVENDORBIN = 
+DESTINSTALLVENDORBIN = $(DESTDIR)$(INSTALLVENDORBIN)
+INSTALLSCRIPT = $(PERLPREFIX)/scripts
+DESTINSTALLSCRIPT = $(DESTDIR)$(INSTALLSCRIPT)
+INSTALLMAN1DIR = $(PERLPREFIX)/man/man1
+DESTINSTALLMAN1DIR = $(DESTDIR)$(INSTALLMAN1DIR)
+INSTALLSITEMAN1DIR = $(SITEPREFIX)/man/man1
+DESTINSTALLSITEMAN1DIR = $(DESTDIR)$(INSTALLSITEMAN1DIR)
+INSTALLVENDORMAN1DIR = 
+DESTINSTALLVENDORMAN1DIR = $(DESTDIR)$(INSTALLVENDORMAN1DIR)
+INSTALLMAN3DIR = $(PERLPREFIX)/man/man3
+DESTINSTALLMAN3DIR = $(DESTDIR)$(INSTALLMAN3DIR)
+INSTALLSITEMAN3DIR = $(SITEPREFIX)/man/man3
+DESTINSTALLSITEMAN3DIR = $(DESTDIR)$(INSTALLSITEMAN3DIR)
+INSTALLVENDORMAN3DIR = 
+DESTINSTALLVENDORMAN3DIR = $(DESTDIR)$(INSTALLVENDORMAN3DIR)
+PERL_LIB = /usr/local/lib/perl5/5.8.6
+PERL_ARCHLIB = /usr/local/lib/perl5/5.8.6/alpha-dec_osf
+LIBPERL_A = libperl.a
+FIRST_MAKEFILE = Makefile
+MAKEFILE_OLD = $(FIRST_MAKEFILE).old
+MAKE_APERL_FILE = $(FIRST_MAKEFILE).aperl
+PERLMAINCC = $(CC)
+PERL_INC = /usr/local/lib/perl5/5.8.6/alpha-dec_osf/CORE
+PERL = /usr/local/bin/perl
+FULLPERL = /usr/local/bin/perl
+ABSPERL = $(PERL)
+PERLRUN = $(PERL)
+FULLPERLRUN = $(FULLPERL)
+ABSPERLRUN = $(ABSPERL)
+PERLRUNINST = $(PERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)"
+FULLPERLRUNINST = $(FULLPERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)"
+ABSPERLRUNINST = $(ABSPERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)"
+PERL_CORE = 0
+PERM_RW = 644
+PERM_RWX = 755
+
+MAKEMAKER   = /usr/local/lib/perl5/5.8.6/ExtUtils/MakeMaker.pm
+MM_VERSION  = 6.17
+MM_REVISION = 1.133
+
+# FULLEXT = Pathname for extension directory (eg Foo/Bar/Oracle).
+# BASEEXT = Basename part of FULLEXT. May be just equal FULLEXT. (eg Oracle)
+# PARENT_NAME = NAME without BASEEXT and no trailing :: (eg Foo::Bar)
+# DLBASE  = Basename part of dynamic library. May be just equal BASEEXT.
+FULLEXT = Chart
+BASEEXT = Chart
+PARENT_NAME = 
+DLBASE = $(BASEEXT)
+VERSION_FROM = 
+OBJECT = 
+LDFROM = $(OBJECT)
+LINKTYPE = dynamic
+
+# Handy lists of source code files:
+XS_FILES = 
+C_FILES  = 
+O_FILES  = 
+H_FILES  = 
+MAN1PODS = 
+MAN3PODS = Chart.pod
+
+# Where is the Config information that we are using/depend on
+CONFIGDEP = $(PERL_ARCHLIB)$(DIRFILESEP)Config.pm $(PERL_INC)$(DIRFILESEP)config.h
+
+# Where to build things
+INST_LIBDIR      = $(INST_LIB)
+INST_ARCHLIBDIR  = $(INST_ARCHLIB)
+
+INST_AUTODIR     = $(INST_LIB)/auto/$(FULLEXT)
+INST_ARCHAUTODIR = $(INST_ARCHLIB)/auto/$(FULLEXT)
+
+INST_STATIC      = 
+INST_DYNAMIC     = 
+INST_BOOT        = 
+
+# Extra linker info
+EXPORT_LIST        = 
+PERL_ARCHIVE       = 
+PERL_ARCHIVE_AFTER = 
+
+
+TO_INST_PM = Chart.pod \
+	Chart/Bars.pm \
+	Chart/Base.pm \
+	Chart/Composite.pm \
+	Chart/Direction.pm \
+	Chart/ErrorBars.pm \
+	Chart/HorizontalBars.pm \
+	Chart/Lines.pm \
+	Chart/LinesPoints.pm \
+	Chart/Mountain.pm \
+	Chart/Pareto.pm \
+	Chart/Pie.pm \
+	Chart/Points.pm \
+	Chart/Split.pm \
+	Chart/StackedBars.pm
+
+PM_TO_BLIB = Chart/Base.pm \
+	$(INST_LIB)/Chart/Base.pm \
+	Chart.pod \
+	$(INST_LIB)/Chart.pod \
+	Chart/Lines.pm \
+	$(INST_LIB)/Chart/Lines.pm \
+	Chart/HorizontalBars.pm \
+	$(INST_LIB)/Chart/HorizontalBars.pm \
+	Chart/Pareto.pm \
+	$(INST_LIB)/Chart/Pareto.pm \
+	Chart/Composite.pm \
+	$(INST_LIB)/Chart/Composite.pm \
+	Chart/Mountain.pm \
+	$(INST_LIB)/Chart/Mountain.pm \
+	Chart/Direction.pm \
+	$(INST_LIB)/Chart/Direction.pm \
+	Chart/Pie.pm \
+	$(INST_LIB)/Chart/Pie.pm \
+	Chart/Points.pm \
+	$(INST_LIB)/Chart/Points.pm \
+	Chart/Split.pm \
+	$(INST_LIB)/Chart/Split.pm \
+	Chart/ErrorBars.pm \
+	$(INST_LIB)/Chart/ErrorBars.pm \
+	Chart/Bars.pm \
+	$(INST_LIB)/Chart/Bars.pm \
+	Chart/StackedBars.pm \
+	$(INST_LIB)/Chart/StackedBars.pm \
+	Chart/LinesPoints.pm \
+	$(INST_LIB)/Chart/LinesPoints.pm
+
+
+# --- MakeMaker platform_constants section:
+MM_Unix_VERSION = 1.42
+PERL_MALLOC_DEF = -DPERL_EXTMALLOC_DEF -Dmalloc=Perl_malloc -Dfree=Perl_mfree -Drealloc=Perl_realloc -Dcalloc=Perl_calloc
+
+
+# --- MakeMaker tool_autosplit section:
+# Usage: $(AUTOSPLITFILE) FileToSplit AutoDirToSplitInto
+AUTOSPLITFILE = $(PERLRUN)  -e 'use AutoSplit;  autosplit($$ARGV[0], $$ARGV[1], 0, 1, 1)'
+
+
+
+# --- MakeMaker tool_xsubpp section:
+
+
+# --- MakeMaker tools_other section:
+SHELL = /bin/sh
+CHMOD = chmod
+CP = cp
+MV = mv
+NOOP = $(SHELL) -c true
+NOECHO = @
+RM_F = rm -f
+RM_RF = rm -rf
+TEST_F = test -f
+TOUCH = touch
+UMASK_NULL = umask 0
+DEV_NULL = > /dev/null 2>&1
+MKPATH = $(PERLRUN) "-MExtUtils::Command" -e mkpath
+EQUALIZE_TIMESTAMP = $(PERLRUN) "-MExtUtils::Command" -e eqtime
+ECHO = echo
+ECHO_N = echo -n
+UNINST = 0
+VERBINST = 0
+MOD_INSTALL = $(PERLRUN) -MExtUtils::Install -e 'install({@ARGV}, '\''$(VERBINST)'\'', 0, '\''$(UNINST)'\'');'
+DOC_INSTALL = $(PERLRUN) "-MExtUtils::Command::MM" -e perllocal_install
+UNINSTALL = $(PERLRUN) "-MExtUtils::Command::MM" -e uninstall
+WARN_IF_OLD_PACKLIST = $(PERLRUN) "-MExtUtils::Command::MM" -e warn_if_old_packlist
+
+
+# --- MakeMaker makemakerdflt section:
+makemakerdflt: all
+	$(NOECHO) $(NOOP)
+
+
+# --- MakeMaker dist section:
+TAR = tar
+TARFLAGS = cvf
+ZIP = zip
+ZIPFLAGS = -r
+COMPRESS = gzip
+SUFFIX = gz
+SHAR = shar
+PREOP = $(NOECHO) $(NOOP)
+POSTOP = $(NOECHO) $(NOOP)
+TO_UNIX = $(NOECHO) $(NOOP)
+CI = ci -u
+RCS_LABEL = rcs -Nv$(VERSION_SYM): -q
+DIST_CP = best
+DIST_DEFAULT = tardist
+DISTNAME = Chart
+DISTVNAME = Chart-2.4.1
+
+
+# --- MakeMaker macro section:
+
+
+# --- MakeMaker depend section:
+
+
+# --- MakeMaker cflags section:
+
+
+# --- MakeMaker const_loadlibs section:
+
+
+# --- MakeMaker const_cccmd section:
+
+
+# --- MakeMaker post_constants section:
+
+
+# --- MakeMaker pasthru section:
+
+PASTHRU = LIB="$(LIB)"\
+	LIBPERL_A="$(LIBPERL_A)"\
+	LINKTYPE="$(LINKTYPE)"\
+	PREFIX="$(PREFIX)"\
+	OPTIMIZE="$(OPTIMIZE)"\
+	PASTHRU_DEFINE="$(PASTHRU_DEFINE)"\
+	PASTHRU_INC="$(PASTHRU_INC)"
+
+
+# --- MakeMaker special_targets section:
+.SUFFIXES: .xs .c .C .cpp .i .s .cxx .cc $(OBJ_EXT)
+
+.PHONY: all config static dynamic test linkext manifest
+
+
+
+# --- MakeMaker c_o section:
+
+
+# --- MakeMaker xs_c section:
+
+
+# --- MakeMaker xs_o section:
+
+
+# --- MakeMaker top_targets section:
+all :: pure_all manifypods
+	$(NOECHO) $(NOOP)
+
+
+pure_all :: config pm_to_blib subdirs linkext
+	$(NOECHO) $(NOOP)
+
+subdirs :: $(MYEXTLIB)
+	$(NOECHO) $(NOOP)
+
+config :: $(FIRST_MAKEFILE) $(INST_LIBDIR)$(DIRFILESEP).exists
+	$(NOECHO) $(NOOP)
+
+config :: $(INST_ARCHAUTODIR)$(DIRFILESEP).exists
+	$(NOECHO) $(NOOP)
+
+config :: $(INST_AUTODIR)$(DIRFILESEP).exists
+	$(NOECHO) $(NOOP)
+
+$(INST_AUTODIR)/.exists :: /usr/local/lib/perl5/5.8.6/alpha-dec_osf/CORE/perl.h
+	$(NOECHO) $(MKPATH) $(INST_AUTODIR)
+	$(NOECHO) $(EQUALIZE_TIMESTAMP) /usr/local/lib/perl5/5.8.6/alpha-dec_osf/CORE/perl.h $(INST_AUTODIR)/.exists
+
+	-$(NOECHO) $(CHMOD) $(PERM_RWX) $(INST_AUTODIR)
+
+$(INST_LIBDIR)/.exists :: /usr/local/lib/perl5/5.8.6/alpha-dec_osf/CORE/perl.h
+	$(NOECHO) $(MKPATH) $(INST_LIBDIR)
+	$(NOECHO) $(EQUALIZE_TIMESTAMP) /usr/local/lib/perl5/5.8.6/alpha-dec_osf/CORE/perl.h $(INST_LIBDIR)/.exists
+
+	-$(NOECHO) $(CHMOD) $(PERM_RWX) $(INST_LIBDIR)
+
+$(INST_ARCHAUTODIR)/.exists :: /usr/local/lib/perl5/5.8.6/alpha-dec_osf/CORE/perl.h
+	$(NOECHO) $(MKPATH) $(INST_ARCHAUTODIR)
+	$(NOECHO) $(EQUALIZE_TIMESTAMP) /usr/local/lib/perl5/5.8.6/alpha-dec_osf/CORE/perl.h $(INST_ARCHAUTODIR)/.exists
+
+	-$(NOECHO) $(CHMOD) $(PERM_RWX) $(INST_ARCHAUTODIR)
+
+config :: $(INST_MAN3DIR)$(DIRFILESEP).exists
+	$(NOECHO) $(NOOP)
+
+
+$(INST_MAN3DIR)/.exists :: /usr/local/lib/perl5/5.8.6/alpha-dec_osf/CORE/perl.h
+	$(NOECHO) $(MKPATH) $(INST_MAN3DIR)
+	$(NOECHO) $(EQUALIZE_TIMESTAMP) /usr/local/lib/perl5/5.8.6/alpha-dec_osf/CORE/perl.h $(INST_MAN3DIR)/.exists
+
+	-$(NOECHO) $(CHMOD) $(PERM_RWX) $(INST_MAN3DIR)
+
+help:
+	perldoc ExtUtils::MakeMaker
+
+
+# --- MakeMaker linkext section:
+
+linkext :: $(LINKTYPE)
+	$(NOECHO) $(NOOP)
+
+
+# --- MakeMaker dlsyms section:
+
+
+# --- MakeMaker dynamic section:
+
+dynamic :: $(FIRST_MAKEFILE) $(INST_DYNAMIC) $(INST_BOOT)
+	$(NOECHO) $(NOOP)
+
+
+# --- MakeMaker dynamic_bs section:
+
+BOOTSTRAP =
+
+
+# --- MakeMaker dynamic_lib section:
+
+
+# --- MakeMaker static section:
+
+## $(INST_PM) has been moved to the all: target.
+## It remains here for awhile to allow for old usage: "make static"
+static :: $(FIRST_MAKEFILE) $(INST_STATIC)
+	$(NOECHO) $(NOOP)
+
+
+# --- MakeMaker static_lib section:
+
+
+# --- MakeMaker manifypods section:
+
+POD2MAN_EXE = $(PERLRUN) "-MExtUtils::Command::MM" -e pod2man "--"
+POD2MAN = $(POD2MAN_EXE)
+
+
+manifypods : pure_all  \
+	Chart.pod \
+	Chart.pod
+	$(NOECHO) $(POD2MAN) --section=3 --perm_rw=$(PERM_RW)\
+	  Chart.pod $(INST_MAN3DIR)/Chart.$(MAN3EXT) 
+
+
+
+
+# --- MakeMaker processPL section:
+
+
+# --- MakeMaker installbin section:
+
+
+# --- MakeMaker subdirs section:
+
+# none
+
+# --- MakeMaker clean_subdirs section:
+clean_subdirs :
+	$(NOECHO) $(NOOP)
+
+
+# --- MakeMaker clean section:
+
+# Delete temporary files but do not touch installed files. We don't delete
+# the Makefile here so a later make realclean still has a makefile to use.
+
+clean :: clean_subdirs
+	-$(RM_RF) ./blib $(MAKE_APERL_FILE) $(INST_ARCHAUTODIR)/extralibs.all $(INST_ARCHAUTODIR)/extralibs.ld perlmain.c tmon.out mon.out so_locations pm_to_blib *$(OBJ_EXT) *$(LIB_EXT) perl.exe perl perl$(EXE_EXT) $(BOOTSTRAP) $(BASEEXT).bso $(BASEEXT).def lib$(BASEEXT).def $(BASEEXT).exp $(BASEEXT).x core core.*perl.*.? *perl.core core.[0-9] core.[0-9][0-9] core.[0-9][0-9][0-9] core.[0-9][0-9][0-9][0-9] core.[0-9][0-9][0-9][0-9][0-9]
+	-$(MV) $(FIRST_MAKEFILE) $(MAKEFILE_OLD) $(DEV_NULL)
+
+
+# --- MakeMaker realclean_subdirs section:
+realclean_subdirs :
+	$(NOECHO) $(NOOP)
+
+
+# --- MakeMaker realclean section:
+
+# Delete temporary files (via clean) and also delete installed files
+realclean purge ::  clean realclean_subdirs
+	$(RM_RF) $(INST_AUTODIR) $(INST_ARCHAUTODIR)
+	$(RM_RF) $(DISTVNAME)
+	$(RM_F)  $(INST_LIB)/Chart/Split.pm $(INST_LIB)/Chart/Mountain.pm $(INST_LIB)/Chart.pod $(INST_LIB)/Chart/Points.pm $(INST_LIB)/Chart/HorizontalBars.pm $(MAKEFILE_OLD) $(INST_LIB)/Chart/LinesPoints.pm
+	$(RM_F) $(INST_LIB)/Chart/Direction.pm $(INST_LIB)/Chart/Base.pm $(INST_LIB)/Chart/ErrorBars.pm $(FIRST_MAKEFILE) $(INST_LIB)/Chart/Pareto.pm $(INST_LIB)/Chart/StackedBars.pm $(INST_LIB)/Chart/Composite.pm
+	$(RM_F) $(INST_LIB)/Chart/Lines.pm $(INST_LIB)/Chart/Pie.pm $(INST_LIB)/Chart/Bars.pm
+
+
+# --- MakeMaker metafile section:
+metafile :
+	$(NOECHO) $(ECHO) '# http://module-build.sourceforge.net/META-spec.html' > META.yml
+	$(NOECHO) $(ECHO) '#XXXXXXX This is a prototype!!!  It will change in the future!!! XXXXX#' >> META.yml
+	$(NOECHO) $(ECHO) 'name:         Chart' >> META.yml
+	$(NOECHO) $(ECHO) 'version:      2.4.1' >> META.yml
+	$(NOECHO) $(ECHO) 'version_from: ' >> META.yml
+	$(NOECHO) $(ECHO) 'installdirs:  site' >> META.yml
+	$(NOECHO) $(ECHO) 'requires:' >> META.yml
+	$(NOECHO) $(ECHO) '    GD:                            1.2' >> META.yml
+	$(NOECHO) $(ECHO) '' >> META.yml
+	$(NOECHO) $(ECHO) 'distribution_type: module' >> META.yml
+	$(NOECHO) $(ECHO) 'generated_by: ExtUtils::MakeMaker version 6.17' >> META.yml
+
+
+# --- MakeMaker metafile_addtomanifest section:
+metafile_addtomanifest:
+	$(NOECHO) $(PERLRUN) -MExtUtils::Manifest=maniadd -e 'eval { maniadd({q{META.yml} => q{Module meta-data (added by MakeMaker)}}) } ' \
+	-e '    or print "Could not add META.yml to MANIFEST: $${'\''@'\''}\n"'
+
+
+# --- MakeMaker dist_basics section:
+distclean :: realclean distcheck
+	$(NOECHO) $(NOOP)
+
+distcheck :
+	$(PERLRUN) "-MExtUtils::Manifest=fullcheck" -e fullcheck
+
+skipcheck :
+	$(PERLRUN) "-MExtUtils::Manifest=skipcheck" -e skipcheck
+
+manifest :
+	$(PERLRUN) "-MExtUtils::Manifest=mkmanifest" -e mkmanifest
+
+veryclean : realclean
+	$(RM_F) *~ *.orig */*~ */*.orig
+
+
+
+# --- MakeMaker dist_core section:
+
+dist : $(DIST_DEFAULT) $(FIRST_MAKEFILE)
+	$(NOECHO) $(PERLRUN) -l -e 'print '\''Warning: Makefile possibly out of date with $(VERSION_FROM)'\''' \
+	-e '    if -e '\''$(VERSION_FROM)'\'' and -M '\''$(VERSION_FROM)'\'' < -M '\''$(FIRST_MAKEFILE)'\'';'
+
+tardist : $(DISTVNAME).tar$(SUFFIX)
+	$(NOECHO) $(NOOP)
+
+uutardist : $(DISTVNAME).tar$(SUFFIX)
+	uuencode $(DISTVNAME).tar$(SUFFIX) $(DISTVNAME).tar$(SUFFIX) > $(DISTVNAME).tar$(SUFFIX)_uu
+
+$(DISTVNAME).tar$(SUFFIX) : distdir
+	$(PREOP)
+	$(TO_UNIX)
+	$(TAR) $(TARFLAGS) $(DISTVNAME).tar $(DISTVNAME)
+	$(RM_RF) $(DISTVNAME)
+	$(COMPRESS) $(DISTVNAME).tar
+	$(POSTOP)
+
+zipdist : $(DISTVNAME).zip
+	$(NOECHO) $(NOOP)
+
+$(DISTVNAME).zip : distdir
+	$(PREOP)
+	$(ZIP) $(ZIPFLAGS) $(DISTVNAME).zip $(DISTVNAME)
+	$(RM_RF) $(DISTVNAME)
+	$(POSTOP)
+
+shdist : distdir
+	$(PREOP)
+	$(SHAR) $(DISTVNAME) > $(DISTVNAME).shar
+	$(RM_RF) $(DISTVNAME)
+	$(POSTOP)
+
+
+# --- MakeMaker distdir section:
+distdir : metafile metafile_addtomanifest
+	$(RM_RF) $(DISTVNAME)
+	$(PERLRUN) "-MExtUtils::Manifest=manicopy,maniread" \
+		-e "manicopy(maniread(),'$(DISTVNAME)', '$(DIST_CP)');"
+
+
+
+# --- MakeMaker dist_test section:
+
+disttest : distdir
+	cd $(DISTVNAME) && $(ABSPERLRUN) Makefile.PL
+	cd $(DISTVNAME) && $(MAKE) $(PASTHRU)
+	cd $(DISTVNAME) && $(MAKE) test $(PASTHRU)
+
+
+# --- MakeMaker dist_ci section:
+
+ci :
+	$(PERLRUN) "-MExtUtils::Manifest=maniread" \
+	  -e "@all = keys %{ maniread() };" \
+	  -e "print(qq{Executing $(CI) @all\n}); system(qq{$(CI) @all});" \
+	  -e "print(qq{Executing $(RCS_LABEL) ...\n}); system(qq{$(RCS_LABEL) @all});"
+
+
+# --- MakeMaker install section:
+
+install :: all pure_install doc_install
+
+install_perl :: all pure_perl_install doc_perl_install
+
+install_site :: all pure_site_install doc_site_install
+
+install_vendor :: all pure_vendor_install doc_vendor_install
+
+pure_install :: pure_$(INSTALLDIRS)_install
+
+doc_install :: doc_$(INSTALLDIRS)_install
+
+pure__install : pure_site_install
+	$(NOECHO) $(ECHO) INSTALLDIRS not defined, defaulting to INSTALLDIRS=site
+
+doc__install : doc_site_install
+	$(NOECHO) $(ECHO) INSTALLDIRS not defined, defaulting to INSTALLDIRS=site
+
+pure_perl_install ::
+	$(NOECHO) $(MOD_INSTALL) \
+		read $(PERL_ARCHLIB)/auto/$(FULLEXT)/.packlist \
+		write $(DESTINSTALLARCHLIB)/auto/$(FULLEXT)/.packlist \
+		$(INST_LIB) $(DESTINSTALLPRIVLIB) \
+		$(INST_ARCHLIB) $(DESTINSTALLARCHLIB) \
+		$(INST_BIN) $(DESTINSTALLBIN) \
+		$(INST_SCRIPT) $(DESTINSTALLSCRIPT) \
+		$(INST_MAN1DIR) $(DESTINSTALLMAN1DIR) \
+		$(INST_MAN3DIR) $(DESTINSTALLMAN3DIR)
+	$(NOECHO) $(WARN_IF_OLD_PACKLIST) \
+		$(SITEARCHEXP)/auto/$(FULLEXT)
+
+
+pure_site_install ::
+	$(NOECHO) $(MOD_INSTALL) \
+		read $(SITEARCHEXP)/auto/$(FULLEXT)/.packlist \
+		write $(DESTINSTALLSITEARCH)/auto/$(FULLEXT)/.packlist \
+		$(INST_LIB) $(DESTINSTALLSITELIB) \
+		$(INST_ARCHLIB) $(DESTINSTALLSITEARCH) \
+		$(INST_BIN) $(DESTINSTALLSITEBIN) \
+		$(INST_SCRIPT) $(DESTINSTALLSCRIPT) \
+		$(INST_MAN1DIR) $(DESTINSTALLSITEMAN1DIR) \
+		$(INST_MAN3DIR) $(DESTINSTALLSITEMAN3DIR)
+	$(NOECHO) $(WARN_IF_OLD_PACKLIST) \
+		$(PERL_ARCHLIB)/auto/$(FULLEXT)
+
+pure_vendor_install ::
+	$(NOECHO) $(MOD_INSTALL) \
+		read $(VENDORARCHEXP)/auto/$(FULLEXT)/.packlist \
+		write $(DESTINSTALLVENDORARCH)/auto/$(FULLEXT)/.packlist \
+		$(INST_LIB) $(DESTINSTALLVENDORLIB) \
+		$(INST_ARCHLIB) $(DESTINSTALLVENDORARCH) \
+		$(INST_BIN) $(DESTINSTALLVENDORBIN) \
+		$(INST_SCRIPT) $(DESTINSTALLSCRIPT) \
+		$(INST_MAN1DIR) $(DESTINSTALLVENDORMAN1DIR) \
+		$(INST_MAN3DIR) $(DESTINSTALLVENDORMAN3DIR)
+
+doc_perl_install ::
+	$(NOECHO) $(ECHO) Appending installation info to $(DESTINSTALLARCHLIB)/perllocal.pod
+	-$(NOECHO) $(MKPATH) $(DESTINSTALLARCHLIB)
+	-$(NOECHO) $(DOC_INSTALL) \
+		"Module" "$(NAME)" \
+		"installed into" "$(INSTALLPRIVLIB)" \
+		LINKTYPE "$(LINKTYPE)" \
+		VERSION "$(VERSION)" \
+		EXE_FILES "$(EXE_FILES)" \
+		>> $(DESTINSTALLARCHLIB)/perllocal.pod
+
+doc_site_install ::
+	$(NOECHO) $(ECHO) Appending installation info to $(DESTINSTALLARCHLIB)/perllocal.pod
+	-$(NOECHO) $(MKPATH) $(DESTINSTALLARCHLIB)
+	-$(NOECHO) $(DOC_INSTALL) \
+		"Module" "$(NAME)" \
+		"installed into" "$(INSTALLSITELIB)" \
+		LINKTYPE "$(LINKTYPE)" \
+		VERSION "$(VERSION)" \
+		EXE_FILES "$(EXE_FILES)" \
+		>> $(DESTINSTALLARCHLIB)/perllocal.pod
+
+doc_vendor_install ::
+	$(NOECHO) $(ECHO) Appending installation info to $(DESTINSTALLARCHLIB)/perllocal.pod
+	-$(NOECHO) $(MKPATH) $(DESTINSTALLARCHLIB)
+	-$(NOECHO) $(DOC_INSTALL) \
+		"Module" "$(NAME)" \
+		"installed into" "$(INSTALLVENDORLIB)" \
+		LINKTYPE "$(LINKTYPE)" \
+		VERSION "$(VERSION)" \
+		EXE_FILES "$(EXE_FILES)" \
+		>> $(DESTINSTALLARCHLIB)/perllocal.pod
+
+
+uninstall :: uninstall_from_$(INSTALLDIRS)dirs
+
+uninstall_from_perldirs ::
+	$(NOECHO) $(UNINSTALL) $(PERL_ARCHLIB)/auto/$(FULLEXT)/.packlist
+
+uninstall_from_sitedirs ::
+	$(NOECHO) $(UNINSTALL) $(SITEARCHEXP)/auto/$(FULLEXT)/.packlist
+
+uninstall_from_vendordirs ::
+	$(NOECHO) $(UNINSTALL) $(VENDORARCHEXP)/auto/$(FULLEXT)/.packlist
+
+
+# --- MakeMaker force section:
+# Phony target to force checking subdirectories.
+FORCE:
+	$(NOECHO) $(NOOP)
+
+
+# --- MakeMaker perldepend section:
+
+
+# --- MakeMaker makefile section:
+
+# We take a very conservative approach here, but it's worth it.
+# We move Makefile to Makefile.old here to avoid gnu make looping.
+$(FIRST_MAKEFILE) : Makefile.PL $(CONFIGDEP)
+	$(NOECHO) $(ECHO) "Makefile out-of-date with respect to $?"
+	$(NOECHO) $(ECHO) "Cleaning current config before rebuilding Makefile..."
+	$(NOECHO) $(RM_F) $(MAKEFILE_OLD)
+	$(NOECHO) $(MV)   $(FIRST_MAKEFILE) $(MAKEFILE_OLD)
+	-$(MAKE) -f $(MAKEFILE_OLD) clean $(DEV_NULL) || $(NOOP)
+	$(PERLRUN) Makefile.PL 
+	$(NOECHO) $(ECHO) "==> Your Makefile has been rebuilt. <=="
+	$(NOECHO) $(ECHO) "==> Please rerun the make command.  <=="
+	false
+
+
+
+# --- MakeMaker staticmake section:
+
+# --- MakeMaker makeaperl section ---
+MAP_TARGET    = perl
+FULLPERL      = /usr/local/bin/perl
+
+$(MAP_TARGET) :: static $(MAKE_APERL_FILE)
+	$(MAKE) -f $(MAKE_APERL_FILE) $@
+
+$(MAKE_APERL_FILE) : $(FIRST_MAKEFILE)
+	$(NOECHO) $(ECHO) Writing \"$(MAKE_APERL_FILE)\" for this $(MAP_TARGET)
+	$(NOECHO) $(PERLRUNINST) \
+		Makefile.PL DIR= \
+		MAKEFILE=$(MAKE_APERL_FILE) LINKTYPE=static \
+		MAKEAPERL=1 NORECURS=1 CCCDLFLAGS=
+
+
+# --- MakeMaker test section:
+
+TEST_VERBOSE=0
+TEST_TYPE=test_$(LINKTYPE)
+TEST_FILE = test.pl
+TEST_FILES = t/*.t
+TESTDB_SW = -d
+
+testdb :: testdb_$(LINKTYPE)
+
+test :: $(TEST_TYPE)
+
+test_dynamic :: pure_all
+	PERL_DL_NONLAZY=1 $(FULLPERLRUN) "-MExtUtils::Command::MM" "-e" "test_harness($(TEST_VERBOSE), '$(INST_LIB)', '$(INST_ARCHLIB)')" $(TEST_FILES)
+
+testdb_dynamic :: pure_all
+	PERL_DL_NONLAZY=1 $(FULLPERLRUN) $(TESTDB_SW) "-I$(INST_LIB)" "-I$(INST_ARCHLIB)" $(TEST_FILE)
+
+test_ : test_dynamic
+
+test_static :: test_dynamic
+testdb_static :: testdb_dynamic
+
+
+# --- MakeMaker ppd section:
+# Creates a PPD (Perl Package Description) for a binary distribution.
+ppd:
+	$(NOECHO) $(ECHO) '<SOFTPKG NAME="$(DISTNAME)" VERSION="2,4,1,0">' > $(DISTNAME).ppd
+	$(NOECHO) $(ECHO) '    <TITLE>$(DISTNAME)</TITLE>' >> $(DISTNAME).ppd
+	$(NOECHO) $(ECHO) '    <ABSTRACT></ABSTRACT>' >> $(DISTNAME).ppd
+	$(NOECHO) $(ECHO) '    <AUTHOR></AUTHOR>' >> $(DISTNAME).ppd
+	$(NOECHO) $(ECHO) '    <IMPLEMENTATION>' >> $(DISTNAME).ppd
+	$(NOECHO) $(ECHO) '        <DEPENDENCY NAME="GD" VERSION="1,2,0,0" />' >> $(DISTNAME).ppd
+	$(NOECHO) $(ECHO) '        <OS NAME="$(OSNAME)" />' >> $(DISTNAME).ppd
+	$(NOECHO) $(ECHO) '        <ARCHITECTURE NAME="alpha-dec_osf" />' >> $(DISTNAME).ppd
+	$(NOECHO) $(ECHO) '        <CODEBASE HREF="" />' >> $(DISTNAME).ppd
+	$(NOECHO) $(ECHO) '    </IMPLEMENTATION>' >> $(DISTNAME).ppd
+	$(NOECHO) $(ECHO) '</SOFTPKG>' >> $(DISTNAME).ppd
+
+
+# --- MakeMaker pm_to_blib section:
+
+pm_to_blib: $(TO_INST_PM)
+	$(NOECHO) $(PERLRUN) -MExtUtils::Install -e 'pm_to_blib({@ARGV}, '\''$(INST_LIB)/auto'\'', '\''$(PM_FILTER)'\'')'\
+	  Chart/Base.pm $(INST_LIB)/Chart/Base.pm \
+	  Chart.pod $(INST_LIB)/Chart.pod \
+	  Chart/Lines.pm $(INST_LIB)/Chart/Lines.pm \
+	  Chart/HorizontalBars.pm $(INST_LIB)/Chart/HorizontalBars.pm \
+	  Chart/Pareto.pm $(INST_LIB)/Chart/Pareto.pm \
+	  Chart/Composite.pm $(INST_LIB)/Chart/Composite.pm \
+	  Chart/Mountain.pm $(INST_LIB)/Chart/Mountain.pm \
+	  Chart/Direction.pm $(INST_LIB)/Chart/Direction.pm \
+	  Chart/Pie.pm $(INST_LIB)/Chart/Pie.pm \
+	  Chart/Points.pm $(INST_LIB)/Chart/Points.pm \
+	  Chart/Split.pm $(INST_LIB)/Chart/Split.pm \
+	  Chart/ErrorBars.pm $(INST_LIB)/Chart/ErrorBars.pm \
+	  Chart/Bars.pm $(INST_LIB)/Chart/Bars.pm \
+	  Chart/StackedBars.pm $(INST_LIB)/Chart/StackedBars.pm \
+	  Chart/LinesPoints.pm $(INST_LIB)/Chart/LinesPoints.pm 
+	$(NOECHO) $(TOUCH) $@
+
+# --- MakeMaker selfdocument section:
+
+
+# --- MakeMaker postamble section:
+
+
+# End.

Added: packages/libchart-perl/branches/upstream/current/Makefile.PL
===================================================================
--- packages/libchart-perl/branches/upstream/current/Makefile.PL	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/Makefile.PL	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,10 @@
+use ExtUtils::MakeMaker;
+
+#  make the samples directory
+mkdir ('samples', 00755);
+
+#  write the makefile
+WriteMakefile ( 'NAME' => 'Chart',
+		'PREREQ_PM' => { 'GD' => 1.2 },
+		'dist' => { 'COMPRESS' => 'gzip', 'SUFFIX' => 'gz' },
+		'VERSION' => '2.4.1' )

Added: packages/libchart-perl/branches/upstream/current/README
===================================================================
--- packages/libchart-perl/branches/upstream/current/README	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/README	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,208 @@
+------------------------------------------------------------------------
+Chart version 2.4
+------------------------------------------------------------------------
+
+
+----------
+INSTALLING
+----------
+
+The usual.
+
+	perl Makefile.PL
+	make
+	make test
+	make install
+
+This should install to your site_perl directory.  The test scripts also
+put samples of the different charts in the samples/ directory.
+
+
+-------------
+PREREQUISITES
+-------------
+
+Lincoln Stein's GD module version 1.20 or higher.
+
+-------
+CHANGES
+-------
+2.4  Changes done by Christine Zilker, Gerhard Stuhlpfarrer, R. Dassing
+        Added new Options:
+             ring             Draw a ring instead of a Pie
+             legend_lines     Connect Pie and the description with a line
+             stepline         Connect Lines and LinesPoints by a stepped line
+             stepline_mode    (thanks to Gerhard Stuhlpfarrer)
+             brush_size1      Define Brush Size for Composite 1 
+             brush_size2      and 2
+        Color problem in Pie fixed
+        Positioning of the description optimized in Pie
+        Division by zero problem fixed in Pie
+        Module 'Bars' checks for numeric data a input on y-axis
+        New Function added to Base:
+            minimum  - determine minimal value of an array of numeric values
+            maximum  - determine maximal value of an array of numeric values
+            arccos   - arccos
+            arcsin   - arcsin
+        Some small bugs corrected:
+            Base::_find_y_scale
+            Base::_find_y_range   : check for numeric values
+            Base::_find_x_range   : check for numeric values
+        Latex sources for documentation included 
+            (We hope to get a better documentation be a native english speaking person)
+                 
+2.3  Changes done by Christine Zilker:
+        Added new Options: 
+	     in Composite: 
+                legend_example_height    changes thickness of the lines in the legend,
+	        f_y_tick1, f_y_tick2 analog to f_y_tick 
+                                         used for right and left y-axes
+	     in Direction: 
+                pairs                    
+
+        Added the possibility to add more datasets in Chart::Direction 
+			   
+	Fixed "label space" problem in Pie
+	Fixed dataset order (in the legend) in StackedBars
+	Fixed problem of getting the right values if round2Tick is used
+	Fixed problem of datavalues in _find_y_scale
+	Some minor bugfixes	    
+
+        Update of the Documentation (Documentation.pdf)
+
+        The requested support of TruType fonts was currently dropped due to
+        missing support in GD.pm (even in new versions)
+        
+        The print out of some hints and warnings where deleted not to confuse
+        the user.
+
+2.2: Composite.pm: imagemap_dump() repaired.
+
+2.1: Changes done by Markus Brandl:
+	new Modules added: ErrorBars.pm, HorizontalBars.pm, Pareto.pm,                          
+	 
+	Pie.pm, Split.pm and Direction.pm
+
+        Subdirectory "doc" contains a Acrobat Reader Documentation.pdf file.
+
+	Function add_datafile() added. It is now possible to add a complete
+	datafile.
+
+        Added new Options: precision, xy_plot, min_x_ticks, max_x_ticks,
+	skip_y_ticks, skip_int_ticks, legend_label_value, y_axes,
+	scale, interval, start, interval_ticks, sort, same_error, point,
+	line, arrow, angle_interval, min_circles, max_circles
+	Also added: the 'title' and 'x_label' options in the colors option 
+
+	Documentation (Documentation.pdf) added.
+
+	_find_x_scale, _find_x_range and _draw_x_number_ticks added to make 
+	xy_plots possible.
+
+	_sort_data has now a body. 
+
+        Fixed integer ticks problem by adding the skip_int_ticks option
+	Fixed f_x_ticks and f_y_ticks problem in Composite
+	Fixed negative value problem in Bars
+	Fixed min_val and max_val problem in draw_data function of all modules:
+	Now, Chart plots the data only if the data is in the area of min_val and
+	max_val! The border of bars in Bars, HorizontalBars and StackedBars will
+	be plotted pink (not misccolor) if the data isn't in the min_val-max_val
+	interval.
+	Fixed custom_x_ticks problem in _draw_x_ticks
+	Some other bugfixes.
+	Updates in _find_y_scale, _round2tick, _calcTickInterval 
+	   
+
+1.1: Changes done by David Pottage:
+        Plot scales can now have any magnitude. 
+        It does not matter if the data covers a range of 100000000000 units
+        or 0.00000000001 units, the scale will be correctly calculated.
+
+        Ticks on plot scales are now plotted on 'round' numbers. 
+        The number & spacing of ticks is chosen based on the data range.
+
+        False zero graphs are now explicitly supported, and will be 
+        generated if the data range merits it. 
+        The instance field 'include_zero' should be set to zero to suppress this.
+
+        Added: include_zero, min_y_ticks, max_y_ticks, integer_ticks_only
+
+1.0.1:
+        Fixed _draw_bottom_legend in Base.pm
+
+0.99c-pre3 - 1.0:
+        Fixed _draw_data in Lines.pm: lines are limited to the frame
+        Added f_x_tick, f_y_tick
+        Added jpeg(), cgi_jpeg() to produce the format jpeg
+        Delete GIF support, added PNG and JPEG instead
+
+0.99b - 0.99c-pre3:
+	James F Miner <jfm at winternet.com>:
+	Added Mountain chart type
+	Added Patterns.  See t/mountain.t for details
+	Bugfix for drifting x tick
+	Improved internal color handling
+
+	Richard Dice  <rdice at shadnet.shad.ca>:
+	Added brush shapes for Points, LinesPoints
+	Added scalar_gif
+
+0.99a - 0.99b:
+	Fixed left legend in composite charts
+	Fixed no color problem when using composite charts w/ no legend
+	Fixed color handling for datasets
+	Added option for http header Pragma: no-cache
+		Netscape 4.5 has a bug that breaks it, but it works with
+		other browsers.  Any ideas for a workaround?
+
+0.99 - 0.99a:
+	Added use of undef() values to represent 'no data' for line breaks
+	Added ylabel*_color options
+	Added x_grid_lines, y_grid_lines & y2_grid_lines , and color options for each
+	Cache disabling in cgi header: Reiner Nippes <nippes.r at gmx.de>
+	Restored grid_lines option: Heinz-Guenter Kontny <hek at kronos.nic.dtag.de>
+	Fixed a typo that broke imagemap data storage in Lines charts
+
+0.94 - 0.99:
+	Modified the 'title' option to correctly process newlines
+	Deprecated the 'subtitle' option, will remove it in next release
+	Changed the API for specifying colors
+	Added support for printing to file handles
+	Added Chart::Composite
+	Added 'spaced_bars' to make it easy to differentiate the bars
+	Added 'grey_background' to make plot background grey
+	Added support for negative values in the datasets
+	Added methods to remember and dump imagemap pixel information
+	Included rgb.txt with distribution for WinXX users
+
+0.93 - 0.94:
+	Moved the legend down to be flush with the chart
+	Fixed the long decimal y-tick label problem
+	Fixed (for the last time, hopefully) the pre-5.004 compilation problem
+	Fixed handling of undefined data points
+	Added more colors for the default data colors
+	Added the transparent gif option
+	Added the option for user-specified colors
+	Added the grid_lines option
+
+0.92 - 0.93: 
+	Fixed the sort problem
+	Fixed the y-axis label centering problem
+	Fixed pre-5.004 compilation problem
+	Added StackedBars charts
+	
+------
+MAINTAINER
+------
+
+Chart-Group (chart at wettzell.ifag.de)
+
+---------
+COPYRIGHT
+---------
+
+Copyright(c) 1997-1998 David Bonner, 1999 Peter Clark, 2001 Chart-Group at BKG.
+All rights reserved.
+This program is free software; you can redistribute it and/or modify it under 
+the same terms as Perl itself.

Added: packages/libchart-perl/branches/upstream/current/TODO
===================================================================
--- packages/libchart-perl/branches/upstream/current/TODO	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/TODO	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,25 @@
+Short term:
+-----------
+- Composite:
+   When using bars in both, an option is necessary to define whether
+   to put the bars above each other or to put aside.
+   Add an option to start x-ticks at the left (i.e. 0 point) side and
+   end at the right side
+-  Adapt true/false also to proper Perl true/false definition
+   (i.e. false = undef || 0 || "0",
+         true  = def || 1 || "1")
+-  Reorganize the relationship between
+   autoscale, 
+   y_ticks, min_y_ticks, max_y_ticks, xy-plot, integer_ticks_only, skip_int_ticks,
+   min_val, max_val
+   and document it.
+   (At the moment the autoscale is used as the default)
+-  Include Skyplot (Direction->polar) into the distribution   
+
+Long term:
+----------
+- 3-D charts
+- include TrueType fonts as soon as GD supports it
+- include logarithmic x- and y-axis
+- Let plot arbitrary xy-functions in a defined area, like
+  y=sin(1/x)+2*x


Property changes on: packages/libchart-perl/branches/upstream/current/TODO
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/Aufbau.png
===================================================================
(Binary files differ)


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/Aufbau.png
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:mime-type
   + application/octet-stream

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/Aufbau1.png
===================================================================
(Binary files differ)


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/Aufbau1.png
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:mime-type
   + application/octet-stream

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/Documentation.dvi
===================================================================
(Binary files differ)


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/Documentation.dvi
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:mime-type
   + application/octet-stream

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/Documentation.pdf
===================================================================
(Binary files differ)


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/Documentation.pdf
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:mime-type
   + application/octet-stream

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/Documentation.tex
===================================================================
--- packages/libchart-perl/branches/upstream/current/doc/LaTeX/Documentation.tex	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/doc/LaTeX/Documentation.tex	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,78 @@
+% Documentation.tex
+%
+\documentclass[11pt]{article}
+
+\usepackage{a4}     % DIN A4
+%\usepackage{german} % Deutsche Trennung
+
+\usepackage[latin1]{inputenc}
+\usepackage[T1]{fontenc}
+
+\usepackage[pdftex]{graphicx}
+\usepackage{makeidx}
+\makeindex
+
+
+%\includeonly{definitions,base}
+%\includeonly{definitions,bars}
+%\includeonly{definitions,composite}
+%\includeonly{definitions,direction}
+%\includeonly{definitions,error}
+%\includeonly{definitions,hbars}
+%\includeonly{definitions,lines}
+%\includeonly{definitions,linespoints}
+%\includeonly{definitions,mountain}
+%\includeonly{definitions,pareto}
+%\includeonly{definitions,pie}
+%\includeonly{definitions,points}
+%\includeonly{definitions,split}
+%\includeonly{definitions,stacked}
+
+% Hyphenations
+\hyphenation{init dataref}
+
+
+\begin{document}
+
+\pagenumbering{Roman} 
+\title{Dokumentation of Perl Module \textbf{Chart}}
+
+%% Name der Autoren 
+%% Die Adressenangaben werden mit \thanks{} eingeschlossen
+%% Name des ersten Autors
+\author{Chart Group\thanks{Bundesamt für Kartographie und Geodäsie, 
+Fundamentalstation Wettzell, Sackenrieder Straße 25, 
+D-93444 Kötzting, E-mail: chart at wettzell.ifag.de}}
+
+\maketitle
+\begin{center}
+\Large Version 2.4
+\end{center}
+
+\clearpage
+\texttt{\ttfamily}
+\tableofcontents
+
+% Einleitung
+\pagenumbering{arabic}
+\include{definitions}
+\include{description}
+%\include{example}
+\include{base}
+\include{bars}
+\include{composite}
+\include{direction}
+\include{error}
+\include{hbars}
+\include{lines}
+\include{linespoints}
+\include{mountain}
+\include{pareto}
+\include{pie}
+\include{points}
+\include{split}
+\include{stacked}
+\listoffigures
+\printindex
+
+\end{document}


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/Documentation.tex
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/Elemente.png
===================================================================
(Binary files differ)


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/Elemente.png
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:mime-type
   + application/octet-stream

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/bars.tex
===================================================================
--- packages/libchart-perl/branches/upstream/current/doc/LaTeX/bars.tex	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/doc/LaTeX/bars.tex	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,92 @@
+%
+% bars.tex
+%
+\section{Chart::Bars}
+\index{Chart::Bars}
+\name{Chart::Bars}
+\file{Bars.pm}
+\requires{Chart::Base, GD, Carp, FileHandle}
+\begin{Description} 
+   \class{Bars} is a \textbf{subclass} of the module \module{Chart::Base}.
+   The class \class{Bars} creates a chart with bars.
+\end{Description}
+
+\parindent 0pt{\large Example:}
+\begin{figure}[h]
+ 	\begin{center}
+		\includegraphics[scale=0.4]{d_bars.png}
+	\end{center}
+	\caption{Bars chart}
+	\label{fig:bars}
+\end{figure}
+
+\begin{verbatim}
+use Chart::Bars;
+
+$g = Chart::Bars->new(600,500);
+
+$g->add_dataset ('Berlin', 'Paris', 'Rome', 'London', 'Munich');
+$g->add_dataset (14, 5, 4, 5, 11);
+$g->add_dataset (12, 4, 6, 7, 12);
+$g->add_dataset (18, 2, 3, 3, 9);
+$g->add_dataset (17, 5, 7, 6, 6);
+$g->add_dataset (15, 3, 4, 5, 11);
+$g->add_dataset (11, 6, 5, 6, 12);
+$g->add_dataset (12, 1, 4, 5, 15);
+$g->add_dataset (10, 4, 6, 8, 10);
+$g->add_dataset (14, 5, 4, 5, 11);
+$g->add_dataset (12, 4, 6, 6, 12);
+$g->add_dataset (18, 2, 3, 3, 9);
+$g->add_dataset (17, 5, 7, 2, 6);
+
+%hash = ('title' => 'Sold Cars in 2001',
+         'text_space' => 5,
+         'grey_background' => 'false',
+         'integer_ticks_only' => 'true',
+         'x_label' => 'City',
+         'y_label' => 'Number of Cars',
+         'legend' => 'bottom',
+         'legend_labels' => ['January' , 'February' , 'March', 'April',
+                             'May', 'June', 'July', 'August', 'September',
+                             'October', 'November', 'December'],
+         'min_val' => 0,
+         'max_val' => 20,
+         'grid_lines' =>'true',
+         'colors' => {'title' => 'red',
+                      'x_label' => 'blue',
+                      'y_label' => 'blue'} );
+
+$g->set (%hash);
+
+$g->png ("bars.png");
+
+\end{verbatim}
+
+\begin{Constructor} 
+An instance of a bars chart object can be created with the constructor new():
+\begin{quote}
+\parindent 0pt
+\fett{\$obj = Chart::Bars->new();}\\
+\fett{\$obj = Chart::Bars->new(\kursiv{width}, \kursiv{height});}\\
+\end{quote}
+
+If \textit{new()} has no arguments, 
+the constructor returns an image with the size 300x400 pixels. 
+If new has two arguments \parameter{width} and \parameter{height}, 
+it returns an image with the desired size.
+\end{Constructor}
+
+\Methods
+\method{All universally valid methods, see page \pageref{methods} of 
+class \class{Chart::Base}.}\\[\parabstand]
+%
+\Attributes
+All universal valid options, see page \pageref{options}. \\
+In addition, the following options for this class are defined:
+\begin{description}
+\item['y\_axes'] Tell chart where to place the y-axis. 
+                 Valid values are 'left', 'right' and 'both'. Defaults to 'left'.
+                 
+\item['spaced\_bars'] Leaves space between the groups of bars at each data point when set to 'true'.  
+             This just makes it easier to read a bar chart.  Default is 'true'.
+\end{description}
\ No newline at end of file


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/bars.tex
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/base.tex
===================================================================
--- packages/libchart-perl/branches/upstream/current/doc/LaTeX/base.tex	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/doc/LaTeX/base.tex	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,369 @@
+%
+% Base.tex
+%
+\section{Chart::Base}
+
+\name{Chart::Base} \index{Chart::Base}
+\file{Base.pm}
+\requires{GD, Carp, FileHandle}
+\begin{Description}
+   \class{Base} is the \textbf{abstract superclass} of the modules: \module{Bars}, 
+   \module{Composite}, \module{Direction}, \module{ErrorBars}, 
+   \module{HorizontalBars}, 
+   \module{Lines}, \module{LinesPoints}, \module{Mountain}, 
+   \module{Pareto}, \module{Pie}, \module{Points}, \module{Split}, \module{StackedBars}.
+   \index{Base} \index{Bars} \index{Composite} \index{Direction} \index{ErrorBars} 
+   \index{HorizontalBars} \index{Lines} \index{LinesPoints} \index{Mountain} \index{Pareto} 
+   \index{Pie} \index{Points} \index{Split} \index{StackedBars}
+
+   The class \class{Base} provides all public methods and most of the attributs of a chart object.
+\end{Description}
+
+
+\begin{Constructor}
+An instance of a chart object can be created with the constructor new(): \index{new()}
+\begin{quote}
+\parindent 0pt
+\fett{\$obj = Chart::\textit{Type}->new();}
+
+\fett{\$obj = Chart::\textit{Type}->new(\parameter{width}, \parameter{height});}
+\end{quote}
+\textit{Type} means the type of chart it returns, i.e. \module{Chart::Bars} 
+returns a chart with bars.
+
+If \textit{new()} has no arguments, 
+the constructor returns an object with the size 300x400 pixels. 
+If \textit{new()} has two arguments \parameter{width} and \parameter{height}, 
+it returns a chart object of the desired size. 
+\end{Constructor}
+
+\Methods\parindent 0pt
+\label{methods}
+\method{\$obj->add\_dataset(@array);}\\
+\method{\$obj->add\_dataset($\backslash$@array\_ref);}\\
+\index{\$obj->add\_datasetadd\_dataset}
+\methodexplanation{Adds a dataset to the object. 
+The parameter is an array or a reference to an array. 
+Generally, the first added array is interpreted as being the x-tick labels. 
+The following arrays include the data points. 
+For example if the first call is 
+\example{\$obj->add\_dataset('Harry', 'Sally');}  
+and the second call is
+\example{\$obj->add\_dataset(5, 8);}
+then chart will draw a picture with two bars and label them with Harry and Sally.\\[\itemabstand]
+Some modules will handle that a little bit different. 
+Have a look at the respective descriptions of the specific modules to get more information.
+There are also differences if you want to use the \fett{xy\_plot} option, to create a xy-graph.}
+
+\method{\$obj->add\_pt(@array);}\\
+\method{\$obj->add\_pt($\backslash$@array\_ref);}\\
+\index{\$obj->add\_pt(@array)}
+\methodexplanation{This is another method to add data to a chart object. 
+An argument can be an array or a reference to an array. 
+If you use this method, chart wants the complete data of one data point.\\
+For example\\
+\example{\$obj->add\_pt('Harry', 5);}\\
+\example{\$obj->add\_pt('Sally', 8);}\\
+would create the same graph as the example for \method{add\_dataset} above.}
+
+\method{\$obj->add\_datafile( "file", \kursiv{type} );}\\
+\method{\$obj->add\_datafile( \$filehandle, \kursiv{type} );}\\
+\index{\$obj->add\_datafile}
+\methodexplanation{This method adds the contents of a complete data file to the chart object.\\
+\kursiv{Type} can be '\kursiv{set}' or '\kursiv{pt}'. 
+If the parameter is '\kursiv{set}' then one line in the data file has to be a complete data set. 
+The values of the set has to be separated by whitespaces. 
+For Example, the file contents has to looks like
+\begin{quote}
+\texttt{Harry  Sally}\\
+\texttt{3      8}\\
+\texttt{2      1}\\
+\end{quote}
+
+If the parameter is '\parameter{pt}' the lines of the file 
+        have to look like the parameter arrays of the \method{add\_pt} method. 
+ Which means, the line includes all values of one data point, also separated by whitespaces. 
+For Example:
+\begin{quote}
+\small
+\texttt{Harry 3 2}\\
+\texttt{Sally 8 1}\\
+\end{quote}
+}
+
+
+\method{\$obj->get\_data();}\\
+\index{\$obj->get\_data}
+\methodexplanation{If you want a copy of the data that has been added so far, 
+      make a call to the \method{get\_data} method like \\
+      \example{\$dataref = \$obj->get\_data();}\\[\itemabstand]
+      It returns a reference to an array of references to datasets. 
+       For Example, you can get the x-tick labels by:\\ 
+      \example{@x\_labels = @\{\$dataref->[0]\};}
+}
+
+ 
+\method{\$obj->clear\_data();} \\ 
+\index{\$obj->clear\_data}
+\methodexplanation{This is the method to remove all data that may have been entered till now.}
+
+\method{\$obj->set( \kursiv{attribut 1} => \kursiv{value 1}, \ldots ,\mbox{\kursiv{attribute n} => \kursiv{value n}} );}\\
+\method{\$obj->set( \%hash );}\\
+\method{\$obj->set( \kursiv{attribut 1}, \kursiv{value 1}, \ldots ,\mbox{\kursiv{attribute n}, \kursiv{value n}} );}\\
+\method{\$obj->set( @array );}\\
+\index{\$obj->set}
+\methodexplanation{Use this method to change the attributes of the chart object. 
+   Set looks for a hash of keys and values or an array of keys and values.\\
+     For Example 
+        \example{\$obj->set( 'title' => 'The title of the image');}
+      would set the title. The same job would do:\\
+      \example{\%hash = ('title' => 'The title of the image');}\\ 
+       \example{\$obj->set( \%hash);}}
+
+\method{\$obj->png( "file" );} \\
+\method{\$obj->png( \$filehandle );} \\
+\method{\$obj->png( FILEHANDLE );} \\
+\method{\$obj->png( "file", $\backslash$@data );}\\
+\index{\$obj->png}
+\methodexplanation{
+This method creates the png file. 
+The file parameter can be the file name, a reference to a filehandle or a filehandle itself. 
+If the file doesn't exist, chart will create a file for you. 
+If there is already a file, chart will overwrite this file. In case of an error, 
+the file is not created.\\
+You can also add the data to the chart object in the png method. 
+The \parameter{@data} array should contain references to arrays of data, 
+with the first array reference pointing to an array with x-tick labels. 
+\parameter{@data} could look like
+\example{@data = (['Harry', 'Sally'], [5, 8], [50, 80]);}\\
+This would set up an graph with two datasets, and three data points in these sets.
+}
+
+\method{\$obj->jpeg( "file" );} \\
+\method{\$obj->jpeg( \$filehandle );} \\
+\method{\$obj->jpeg( FILEHANDLE );} \\
+\method{\$obj->jpeg( "file", $\backslash$@data );}\\
+\index{\$obj->jpeg}
+\methodexplanation{
+    These are the methods to create jpeg files. They work similar like the png() method.}
+    
+\method{\$obj->cgi\_png();} \\
+\method{\$obj->cgi\_jpeg();} \\
+\index{\$obj->cgi\_png}\index{\$obj->cgi\_jpeg}
+\methodexplanation{
+With the cgi methods you can create dynamic images for your web site. 
+The cgi methods will print the chart, along with the appropriate http header to stdout, 
+allowing you to call chart-generating scripts directly from your html pages 
+(ie. with a <img scr=image.pl>HTML tag).}
+
+\method{\$obj->imagemap\_dump();} \\ 
+\index{\$obj->imagemap\_dump}
+\methodexplanation{
+           Chart can also return the pixel position information 
+           so that you can create image maps from the files Chart generates. 
+           Simply set the 'imagemap' option to 'true' before you generate the file, 
+           then call the \method{imagemap\_dump} method to retrieve the information. 
+           A structure will be returned almost identical to the \parameter{@data} array 
+           described above to pass the data into Chart.
+
+           \example{\$imagemap\_data = \$obj->imagemap\_dump();}
+
+           Instead of single data values, references to arrays of pixel information is passed. 
+           For the classes \class{Bars}, \class{HorizontalBars}, 
+           \class{Pareto} and \class{StackedBars} charts, 
+           the arrays will contain two x-y pairs (specifying the upper left and the lower right corner of the bar).
+           Compare to: \\
+            \example{( \$x1, \$y1, \$x2, \$y2 ) = @\{ \$imagemap\_data->[\$dataset][\$datapoint] \};}\\[\itemabstand]
+ 
+           For the classes \class{Lines}, \class{Points}, 
+            \class{LinesPoints} and \class{Split}, the arrays will contain a single xy-pair 
+          (specifying the center of the point). 
+         Compare to:\\
+            \example{( \$x, \$y) = @\{ \$imagemap\_data->[\$dataset][\$datapoint] \};}\\[\itemabstand]
+
+           A few caveats apply here. First of all, Chart uses the GD-module by Lincoln Stein 
+         to draw lines, circles, strings, and so on. 
+GD treats the upper-left corner of the png/jpeg as the reference point, 
+therefore, positive y values are measured from the top of the png/jpeg, not from the bottom. 
+Second, these values will mostly contain long decimal values. 
+GD, of course, has to truncate these to single pixel values. 
+In a worst-case scenario, this will result in an error of one pixel on your imagemap. 
+If this is really an issue, your only option is to experiment with it, 
+or to contact Lincoln Stein and ask him. Third, 
+please remember that the 0th dataset will be empty, since that's the place for the data point labels.}
+
+   
+\label{options}
+\Attributes
+These are the options which have effects on all types of chart:
+\begin{description}
+\item ['transparent']Makes the background of the image transparent if set to 'true'. 
+                    Useful for making web page images. 
+                    It doesn't work for all browsers. 
+                    Defaults to false.
+
+\item ['png\_border']Sets the number of pixels 
+                     used as a border between the graph and the edges of the png/jpeg. 
+                     Defaults to 10.
+                     
+\item ['graph\_border']
+        Sets the number of pixels used as a border between the title/labels 
+        and the actual graph within the png/jpeg. Defaults to 10.
+
+\item['text\_space']
+       Sets the amount of space left on the sides of text, to make it more readable.  Defaults to 2.
+
+\item['title']Tells Chart what to use for the title of the graph.  
+      If empty, no title is drawn.  
+      '$\backslash$es' are treated as newline. 
+      Remember, if you want to use normal quotation marks instead of single quotation marks 
+      you have to quote "`$\backslash\backslash$n"'. Default is empty.
+
+\item['sub\_title']Writes a sub-title under the title in smaller letters.
+
+\item['x\_label']Tells Chart what to use for the x-axis label.  
+                 If empty, no label is drawn.  Default is empty.
+                 
+\item['y\_label', 'y\_label2']Tells Chart what kind of label should be used for the description
+          of the y axis on the lft or the right side accordingly.  
+          If empty, no label is drawn.  Default is empty.
+
+\item['legend']Specifies the placement of the legend.  
+             Valid values are 'left', 'right', 'top', 'bottom'.  
+             Setting this to 'none' tells chart not to draw a legend.  Default is 'right'.
+
+\item['legend\_labels']
+            Sets the values for the labels for the different datasets. 
+            Should be assigned a reference to an array of labels.  For example,\\
+            \example{@labels = ('foo', 'bar')};\\
+            \example{\$obj->set ('legend\_labels' => $\backslash$@labels);}\\
+            Default is empty, in which case 'Dataset 1', 'Dataset 2', etc.
+             are used as the labels.
+             
+\item['tick\_len']Sets the length of the x- and y-ticks in pixels.  Default is 4.
+
+\item['x\_ticks']Specifies how to draw the x-tick labels.  
+        Valid values are 'normal', 'staggered' (staggers the labels vertically), 
+        and 'vertical' (the labels are draw upwards).  Default is 'normal'.
+
+\item['y\_ticks']The number of ticks to plot on the y scale, 
+      including the end points. e.g. If the scale runs from 0 to 50,
+			with ticks every 10, y\_ticks will have the value of 6.
+
+\item['min\_y\_ticks']Sets the minimum number of y\_ticks to draw when generating a scale. 
+        Default is 6, the minimum is 2.
+        
+\item['max\_y\_ticks']Sets the maximum number of y\_ticks to draw when generating a scale. 
+       Default is 100. This limit is used to avoid plotting an unreasonably 
+       large number of ticks if non-round values are used for the min\_val and
+       max\_val.\\[\itemabstand]
+       The value for 'max\_y\_ticks' should be at least 5 times larger than 'min\_y\_ticks'.
+       
+\item['max\_x\_ticks', 'min\_x\_ticks'] Works similar as 'max\_y\_ticks' and 'min\_y\_ticks'. 
+      Of course, it works only for xy-plots! 
+
+\item['integer\_ticks\_only']Specifies how to draw the x- and y-ticks: 
+      as floating point ('false', '0') 
+      or as integer numbers ('true', 1). 
+      If you want integer ticks, it is maybe better to set the option 'precision' at zero. 
+      Default: 'false'
+
+\item['skip\_int\_ticks']If 'integer\_ticks\_only' was set to 'true' the labels and 
+          ticks at the y-axis will be drawn every nth tick. 
+          Of course in HorizontalBars it affects the x-axis. Default to 1, no skipping.
+
+\item['precision'] Sets the number of numerals after the decimal point. 
+             Affects in most cases the y-axis. 
+             But also the x-axis if 'xy\_plot' is set and the labels in a pie chart. Defaults to 3.
+
+\item['max\_val']Sets the maximum y-value on the graph, overriding the normal autoscaling.  
+            Does not work for a Split chart. Default is undef.
+
+\item['min\_val']Sets the minimum y-value on the graph, overriding the normal autoscaling.  
+           Does not work for a Split chart. Default is undef.\\
+\\
+Caution should be used when setting 'max\_val' and 'min\_val' to floating point or non-round numbers. This is because the scale must start \& end on a tick, ticks must have round-number intervals, and include round numbers.\\
+\\
+Example: Suppose your dataset has a range of 35-114 units, If you specify them as the 'min\_val' \& 'max\_val', The y\_axis will be plot with 80 ticks every 1 unit.. If no 'min\_val' \& 'max\_val', the system will autoscale the range to 30-120 with 10 ticks every 10 units.\\
+\\
+If the 'min\_val' \& 'max\_val' are specified to exesive precision, they may be overiden by the system, plotting a maximum 'max\_y\_ticks' ticks. 
+
+\item['include\_zero']If 'true', forces the y-axis to include zero if it is not in the 
+            dataset range. Default is 'false'.\\
+\\
+In general, it is better to use this, than to set the 'min\_val' if that is all you want to achieve.
+\item['skip\_x\_ticks']Sets the number of x-ticks and x-tick labels to skip.  (ie. if 'skip\_x\_ticks' was set to 4, Chart would draw every 4th x-tick and x-tick label).  Default is undef.
+
+\item['custom\_x\_ticks']This option allows you to specify exactly 
+            which x-ticks and x-tick labels should be drawn. 
+            It should be assigned a reference to an array of desired ticks.  
+            Just remember that I'm counting from the 0th element of the array.  
+            (e.g., if 'custom\_x\_ticks' is assigned [0,3,4], 
+            then the 0nd, 3rd, and 4th x-ticks will be displayed) 
+            It doesn't work for \class{Split}, \class{HorizontalBars} and \class{Pie}.
+            
+\item['f\_x\_tick'] Needs a reference to a function 
+           which uses the x-tick labels generated by the \parameter{@data->[0]} as the argument. 
+           The result of this function reformats the labels as a string. 
+           For instance\\
+           \example{\$obj -> set ('f\_x\_tick' => $\backslash$\&formatter;}\\
+           An example for the function formatter: x labels are seconds since an event. 
+           The referenced function can transform this seconds to hour, minutes and seconds.
+
+\item['f\_y\_tick']The same situation as for 'f\_x\_tick' but now used for y labels.
+
+\item['colors']This option lets you control the colors the chart will use.  
+              It takes a reference to a hash.  
+              The hash should contain keys mapped to references to arrays of rgb values.  
+              For instance,\\
+              \example{\$obj->set('colors' => {'background' => [255,255,255]});}\\
+              sets the background color to white (which is the default).  
+              Valid keys for this hash are
+              \begin{itemize}
+              \item 'background' (background color for the png)
+              \item 'title' (color of the title)
+              \item 'text' (all the text in the chart)
+              \item 'x\_label' (color of the x axis label)
+              \item 'y\_label' (color of the first y axis label)
+              \item 'y\_label2' (color of the second y axis label)
+              \item 'grid\_lines' (color of the grid lines)
+              \item 'x\_grid\_lines' (color of the x grid lines - for x axis ticks)
+              \item 'y\_grid\_lines' (color of the y grid lines - for to left y axis ticks)
+              \item 'y2\_grid\_lines' (color of the y2 grid lines - for right y axis ticks)
+              \item 'dataset0'..'dataset63' (the different datasets)
+              \item 'misc' (everything else, e.g. ticks, box around the legend)
+              \end{itemize}
+             NB. For composite charts, there is a limit of 8 datasets per component. 
+             The colors for 'dataset8' through 'dataset15' 
+             become the colors for 'dataset0' through 'dataset7' for the second component chart.
+
+\item['title\_font'] This option changes the font of the title. 
+               The key has to be a Gd font. e.g. GD::Font->Large 
+
+\item['label\_font'] This option changes the font of the labels. The key has to be a Gd font. 
+
+\item['legend\_font'] This option changes the font of the text of the legend. The key has to be a Gd font. 
+
+\item['tick\_label\_font'] This option changes the font of the ticks. The key has to be a Gd font. 
+
+\item['grey\_background']Puts a nice soft grey background on the actual data plot when set to 'true'.  Default is 'true'.
+
+\item['x\_grid\_lines']Draws grid lines matching up to x ticks if set to 'true'. Default is 'false'.
+
+\item['y\_grid\_lines']Draws grid lines matching up to y ticks if set to 'true'. Default is 'false'.
+
+\item['grid\_lines']Draws grid lines matching up to x and y ticks if set to 'true'. Default is 'false'. 
+
+\item['imagemap']Lets Chart know you're going to ask for information 
+        about the placement of the data for use in 
+         creating an image map from the png. This information can be retrieved using the imagemap\_dump() method.         NB. that the imagemap\_dump() method cannot be called until 
+         after the Chart has been generated (e.g. using the png() or cgi\_png() methods).
+
+\item['ylabel2']The label for the right y-axis (the second component chart).  Default is undef.
+
+\item['no\_cache']Adds Pragma: no-cache to the http header. 
+           Be careful with this one, as Netscape 4.5 is     unfriendly with POST using this method.
+
+\item['legend\_example\_size'] Sets the length of the example line in the legend. Defaults to 20.
+\end{description}
+


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/base.tex
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/composite.png
===================================================================
(Binary files differ)


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/composite.png
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:mime-type
   + application/octet-stream

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/composite.tex
===================================================================
--- packages/libchart-perl/branches/upstream/current/doc/LaTeX/composite.tex	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/doc/LaTeX/composite.tex	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,121 @@
+% composite.tex
+%
+\section{Chart::Composite}
+\name{Chart::Composite}
+\file{Composite.pm}
+\requires{Chart::Base, GD, Carp, FileHandle}
+\begin{Description} \class{Composite} is a subclass of \class{Chart::Base}.\\
+The class \class{Composite} creates a two component chart 
+with two types of charts which are layed 
+one above each other.
+Therefore, two similiar chart types may have a conflict in the printout.
+For example, you can create a two component chart with bars and lines. 
+Just set the option 'composite\_info'! 
+A composite chart doesn't make sense with all types of chart. 
+But it works pretty good with Lines, Points, LinesPoints and Bars.
+\end{Description}
+
+\parindent 0pt{\large Example:}
+\begin{figure}[h]
+	\begin{center}
+		\includegraphics[scale=0.6]{composite_f.png}
+	\end{center}
+	\caption{Composite chart}
+	\label{fig:composite}
+\end{figure}
+\begin{verbatim}
+use Chart::Composite;
+
+$g = Chart::Composite->new;
+
+$g->add_dataset (1 , 2, 3, 4, 5, 6);
+$g->add_dataset (0.1, 0.2, 0.3, 0.2, 0.4, 0.1);
+$g->add_dataset (0.3, 0.5, 0.2, 0.6, 0.7, 0.4);
+$g->add_dataset (10, 11, 6, 7, 7, 8);
+
+$g->set('title' => 'Composite Chart',
+        'composite_info' => [ ['Bars', [1,2]],
+                               ['LinesPoints', [3]] ] );
+$g->set( 'include_zero' => 'true');
+
+$g->png("composite.png");
+\end{verbatim}
+
+\begin{Constructor} 
+An instance of a Composite object can be created with the constructor new():
+\begin{quote}
+\parindent 0pt
+\fett{\$obj = Chart::Composite->new();}\\
+\fett{\$obj = Chart::Composite->new(\parameter{width}, \parameter{height});}
+\end{quote}
+If \textit{new()} has no arguments, 
+the constructor returns an image with the size 300x400 pixels. 
+If \textit{new()} has two arguments \parameter{width} and \parameter{height}, 
+it returns an image of the desired size.
+\end{Constructor}
+
+\Methods
+All universally valid methods, see page \pageref{methods}: \class{Chart::Base}. \\
+
+\Attributes
+All universal valid options, see page \pageref{options}. 
+
+The following options are also available:
+\begin{description}
+\item['composite\_info'] This option is only used for composite charts.  
+      It contains the information about which types to use for the two component charts, 
+      and which datasets belong to which component chart. 
+      It should be a reference to an array of array references, 
+      containing information like the following\\
+      \$obj->set ('composite\_info' => [ ['Bars', [1,2]],  ['Lines', [3,4] ] ]);\\
+\\
+      This example would set the two component charts to be a bar chart and a line chart. 
+      It would use the first two data sets for the bar chart
+      (note that the numbering starts at 1, 
+      not zero like most of the other numbered things in Chart), 
+      and the second two data sets for the line chart. The default is undef.\\
+      \\
+      NB. Chart::Composite can only do two component charts.
+      
+\item['min\_val1', 'min\_val2'] Only for composite charts, 
+     these options specify the minimum y-value for the first and second components
+     respectively. Both default to undef.
+
+\item['max\_val1', 'max\_val2'] Only for composite charts, 
+     these options specify the maximum y-value for the first and second components
+     respectively. Both default to undef.
+
+\item['y\_ticks1', 'y\_ticks2'] The number of y ticks to use on the first 
+     and second y-axis on a composite chart.  
+     Please note that if you just set the 'y\_ticks' option, 
+     both axes will use that number of y ticks. Both default to undef.
+
+\item['brush\_size1', 'brush\_size2'] If using compositite charts having
+     'brush\_size' as their attribute you can define the size of the brush
+     individually. Default is 6.
+     
+\item['f\_y\_tick1', 'f\_y\_tick2'] Needs a reference to a function which uses the y-tick
+     labels for the first and second y-axis. 
+     The result of this function reformats the labels as a string. For instance\\
+     \\
+     \$obj -> set ('f\_y\_tick1') => \verb|\|\&formatter1 ;\\
+     \$obj -> set ('f\_y\_tick2') => \verb|\|\&formatter2 ;\\
+
+\item['same\_y\_axes'] Forces both component charts in a composite chart 
+     to use the same maximum and minimum y-values if set to 'true'. 
+     This helps to keep the composite charts from being too confusing. Default is undef.
+     
+\item['legend\_example\_height'] Only for composite charts. These option changes the thickness
+     of the lines in the legend. If 'legend\_example\_height' ist set to 'true'the 
+     thickness of all 'legend-lines' can be changed. Default is false.\\
+     \\
+     \$obj -> set ('legend\_example\_height'    => 'true');\\
+     \$obj -> set ('legend\_example\_height0'   => '3');\\
+     \$obj -> set ('legned\_example\_height1..4'=> '10');\\
+     \\
+     This example would set the thickness of the first line in the legend to 3, and the 
+     thickness of the following 4 lines to 10. The Defaultvalues of the individual datasets
+     (use the same order as in 'composite\_info') are one, which means a 'normal' line
+     is drawn. It is not possible to change a 'legend\_example\_height\#'(\# means a                 datasetnumber)which was once defined. The first value remains.            
+                      
+\end{description}


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/composite.tex
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/composite_f.png
===================================================================
(Binary files differ)


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/composite_f.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/d_bars.png
===================================================================
(Binary files differ)


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/d_bars.png
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:mime-type
   + application/octet-stream

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/d_hbars4.png
===================================================================
(Binary files differ)


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/d_hbars4.png
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:mime-type
   + application/octet-stream

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/d_lines2.png
===================================================================
(Binary files differ)


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/d_lines2.png
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:mime-type
   + application/octet-stream

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/d_linesp2.png
===================================================================
(Binary files differ)


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/d_linesp2.png
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:mime-type
   + application/octet-stream

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/d_pareto2.png
===================================================================
(Binary files differ)


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/d_pareto2.png
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:mime-type
   + application/octet-stream

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/d_pie3.png
===================================================================
(Binary files differ)


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/d_pie3.png
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:mime-type
   + application/octet-stream

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/definitions.tex
===================================================================
--- packages/libchart-perl/branches/upstream/current/doc/LaTeX/definitions.tex	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/doc/LaTeX/definitions.tex	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,107 @@
+%
+% definitions.tex
+% ---------------
+
+% LENGTH
+\newlength{\parabstand}
+\setlength{\parabstand}{2ex plus1ex minus1ex}
+
+\newlength{\itemabstand}
+\setlength{\itemabstand}{1ex plus1ex minus1ex}
+
+% Commands
+
+\newcommand{\syn}[1]{
+                      {\it\large #1}
+                     } %Ende synopsis
+\newcommand{\fett}[1]{
+                       {\bf #1} 
+                     }% Ende Hervorheben
+\newcommand{\unl}[1] {
+                      {\underline #1}
+                     }%für implemet. und beschrei.
+\newcommand{\kursiv}[1]{
+                     {\it #1}
+                     }
+\newcommand{\herv}[1]{
+                     {\underline{\bf\large #1}}
+                     }
+
+%-------------- command class -------------------------
+\newcommand{\class}[1]{\textsc{\large #1}\index{Class!#1}}
+%-------------- command module -------------------------
+\newcommand{\module}[1]{\textsf{#1}}
+%-------------- command parameter -------------------------
+\newcommand{\parameter}[1]{\textit{#1}}
+
+%-------------- command name -------------------------
+\newcommand{\name}[1]{
+   \parbox{15ex}{\underline{\bf\large Name:}} #1\index{#1}\\[\itemabstand]}
+
+%-------------- command file -------------------------
+\newcommand{\file}[1]{
+   \parbox{15ex}{\underline{\bf\large File:}} #1\\[\itemabstand]}
+
+%-------------- command requires -------------------------
+\newcommand{\requires}[1]{
+   \parbox{15ex}{\underline{\bf\large Requires:}} #1\\[\itemabstand]}
+      
+%-------------- command method -------------------------
+\newcommand{\method}[1]{
+      \parindent 0pt \textbf{#1}}
+           
+%-------------- command methodexplanation -------------------------
+\newcommand{\methodexplanation}[1]{
+      \hfill\parbox{0.9\textwidth}{\small\parindent 0pt #1}}
+
+
+%-------------- command example -------------------------
+\newcommand{\example}[1]{
+      \parindent 0pt \mbox{\textbf{\footnotesize #1}}}   
+
+%-------------- command Methods -------------------------
+\newcommand{\Methods}
+     {\parindent 0pt\underline{\bf\large Methods:}\\}
+     
+%-------------- command Attributes -------------------------
+\newcommand{\Attributes}
+     {\parindent 0pt\underline{\bf\large Attributes/Options:}\\}
+     
+
+%% Environment definitons
+%  Environment Description
+\newsavebox{\descriptionsavedbox}
+\newenvironment{Description}
+{\begin{lrbox}{\descriptionsavedbox}
+ \begin{minipage}[t]{0.9\textwidth}
+}%
+{\vspace{\parabstand}
+ \end{minipage}\end{lrbox}
+ \parindent 0pt\underline{\bf\large Description:}
+ \mbox{\usebox{\descriptionsavedbox}}
+}% end Description
+
+
+%  Environment Constructor
+\newsavebox{\constructorsavedbox}
+\newenvironment{Constructor}
+{\begin{lrbox}{\constructorsavedbox}
+ \begin{minipage}[t]{0.9\textwidth}
+}%
+{\vspace{\parabstand}
+ \end{minipage}\end{lrbox}
+ \parindent 0pt\underline{\bf\large Constructor:}
+ \mbox{\usebox{\constructorsavedbox}}
+}% end Constructor
+
+%  Environment Example
+\newsavebox{\examplesavedbox}
+\newenvironment{Example}
+{\begin{lrbox}{\examplesavedbox}
+ \begin{minipage}[t]{0.9\textwidth}
+}%
+{\vspace{\parabstand}
+ \end{minipage}\end{lrbox}
+ \parindent 0pt{\large Example:}
+ \mbox{\usebox{\examplesavedbox}}
+}% end Example


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/definitions.tex
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/description.tex
===================================================================
--- packages/libchart-perl/branches/upstream/current/doc/LaTeX/description.tex	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/doc/LaTeX/description.tex	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,90 @@
+% description.tex
+%-----------------
+\clearpage
+\section{Description}
+\syn{SYNOPSIS}
+\begin{verbatim}
+	use Chart::type;     (type is one of: Bars, Composite,
+	Direction, ErrorBars, HorizontalBars, Lines, LinesPoints,
+	Mountain,	Pareto, Pie, Points, Split or StackedBars)
+		
+	$obj = Chart::type->new;
+	$obj = Chart::type->new (width, height);
+	
+	$obj->set( $key_1, $val_1, ... , $key_n, $val_n);
+	$obj->set( $key_1 => $val_1, ... , $key_n => $val_n);
+	$obj->set( %hash );
+	
+	#GifGraph.pm-style API to produce png formatted charts
+	@data = ( \@x_tick_labels, \@dataset_1, ... \@datase_n);
+	$obj->png ( "filename", \@data );
+	$obj->png ( $filehandle, \@data );
+	$obj->png ( FILEHANDLE, \@data );
+	$obj->cgi_png ();
+	
+	#Graph.pm-style API
+	$obj->add_pt ($label, $val_1, ... $val_n);
+	$obj->add_dataset ($val_1, ..., $val_n);
+	$obj->png ("filename");
+	$obj->png ($filehandle);
+	$obj->png (FILEHANDLE);
+	$obj->cgi_png();
+	The similar functions are available for jpeg	
+	
+	#Retrieve imagemap information
+	$obj->set('imagemap' => 'true' );
+	$imagemap_ref = $obj->imagemap_dump();
+	
+\end{verbatim}
+\clearpage
+The Perl module \class{Chart} creates 'png' or 'jpeg' output which can be 
+written into a file or output to 'stdout'. 
+Therefore, \class{Chart} can also create dynamic charts for web sites.
+
+It is possible to create a lot of different chart types, i.e., 
+Bars, Composite, Direction, ErrorBars, HorizontalBars, Lines, LinesPoints, 
+Mountain, Pareto, Pie, Points, Split and StackedBars.
+
+Take a look at their descriptions to see how they work. 
+All of the special types are classes by themselves. 
+All these classes have the same abstract superclass: Base.pm. 
+The hierarchy of Chart is shown in Figure~\ref{fig:Aufbau}.      
+
+\begin{figure}[h]
+	\begin{center}
+		\includegraphics[scale=0.5]{Aufbau.png}
+	\end{center}
+	\caption{The hierarchy of chart}
+	\label{fig:Aufbau}
+\end{figure}
+
+Therefore, you have to create an \emph{instance of one of the subclasses} 
+to get a chart object.
+
+All these methods and most of the options chart provides are implemented in Base. 
+But the drawing of the graph itself happens in the respective subclass. 
+Figure~\ref{fig:Elemente} shows the elements of a chart object.
+
+\begin{figure}[h]
+	\begin{center}
+		\includegraphics[scale=0.4]{Elemente.png}
+	\end{center}
+	\caption{Elements of a chart}
+	\label{fig:Elemente}
+\end{figure}
+
+The graph area in the middle is drawn by the subclass, all the other elements are drawn by Base. 
+But some classes don't need all of these elements or need special elements. 
+Those elements have to be over-written in the respective class. 
+For example, the class \class{Pie} doesn't need axes, 
+so the methods for drawing the axes in file 'Base.pm' 
+are over written by methods in class \class{Pie}; 
+in this case no axes are drawn. 
+Furthermore, the legend in a pie chart are a little bit different. Therefore Pie.pm has its
+own methods for drawing the legends. These rules are managed by Chart. 
+You don't have to attend to it. 
+
+Chart uses Lincoln Stein's GD module for all its graphics primitives calls. 
+So you need a installed version of GD.pm to use Chart. 
+This module is like Chart available in the CPAN online archive at \kursiv{http://www.cpan.org/}.
+\index{Lincoln Stein's GD module}    


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/description.tex
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/direction.png
===================================================================
(Binary files differ)


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/direction.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/direction.tex
===================================================================
--- packages/libchart-perl/branches/upstream/current/doc/LaTeX/direction.tex	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/doc/LaTeX/direction.tex	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,112 @@
+%
+% direction.tex
+%
+\section{Chart::Direction}
+
+\name{Chart::Direction}
+\file{Direction.pm}
+\requires{Chart::Base, GD, Carp, FileHandle}
+\begin{Description} 
+\class{Direction} is a \fett{subclass} of Chart::Base.\\
+The class Direction creates a diagram for polar coordinates.\\
+Direction plots data, which is specified by angle (eg. wind direction) and value (eg. wind strength).\\
+The first dataset to add is always a set of angels in degress. The second set is a set of values. The right adding of following datasets depends on the option 'pairs'.\\
+Direction will draw a point chart if no value ist set to the option 'point'. You can also get a lines chart by turning the option 'point' to 'false' and the option 'line' to 'true'. If you want a linespoint chart, then 'point' and 'line' has to be 'true'. Additionally chart plots arrows from the center to the point or to the end of the line, if the option 'arrow' is set to 'true'.
+\end{Description}
+
+\parindent 0pt{\large Example:}
+\begin{figure}[h]
+	\begin{center}
+		\includegraphics[width = 8cm, height =8cm]{direction.png}
+	\end{center}
+	\caption{Direction chart}
+	\label{fig:direction}
+\end{figure}
+\begin{verbatim}
+use Chart::Direction;
+$g = Chart::Direction->new(500,500);
+
+$g->add_dataset( 0, 100, 50, 200, 280, 310);
+$g->add_dataset(30,  40, 20,  35,  45,  20);
+
+$g->add_dataset(10, 110, 60, 210, 290, 320);
+$g->add_dataset(30,  40, 20,  35,  45,  20);
+
+$g->add_dataset(20, 120, 70, 220, 300, 330);
+$g->add_dataset(30,  40, 20,  35,  45,  20);
+
+%hash = ( 'title' => 'Direction Demo',
+          'angle_interval' => 45,
+          'precision' => 0,
+          'arrow' => 'true',
+          'point' => 'false',
+          'include_zero' => 'true',
+          'pairs' => 'true',
+          'legend' => 'none',
+          'grey_background' => 'false');
+      
+$g->set(%hash);
+$g->png("Grafiken/vector.png");
+\end{verbatim}
+
+
+\begin{Constructor} 
+An instance of a direction chart object can be created with the constructor new():\\
+\fett{\$obj = Chart::Direction->new();}\\
+\fett{\$obj = Chart::Direction->new(\parameter{width}, \parameter{height});}\\
+If \textit{new()} has no arguments, 
+the constructor returns an image with the size 300x400 pixels. 
+If new has two arguments \parameter{width} and \parameter{height}, 
+it returns an image with the desired size. \\ 
+\end{Constructor}
+
+\Methods
+All universally valid methods, see page \pageref{methods}: Chart::Base.
+
+\Attributes
+All universally valid options, see page \pageref{options}.
+Additional, you can have effects on the axes, like 'custom\_x\_ticks', 'x\_ticks' and so on. 
+Also available, these special options:
+\begin{description}
+\item['point'] Indicates to draw points, 
+               representing the data values. 
+               'true' or 'false' possible, per default 'true'.
+
+\item['line'] Connects the points with lines if set to 'true'. 
+              Defaults to 'false'.
+
+\item['arrow'] Draws an arrow from the center of the chart to the point, 
+               if set to 'true', per default 'false'.
+
+\item['pairs'] This option tells Chart how to handle more datasets. 
+               If 'pairs' is set to 'true', 
+               Chart uses the first dataset as a set of degrees and 
+               the second dataset as a set of values. 
+               Then, the third set is a set of degrees und the fourth a set of values \dots. \\
+               If 'pairs' is set to 'false', 
+               Chart uses the first dataset as a set of angels 
+               and all following datasets as sets of values. \\
+               Defaults to 'false'.
+               
+\item['angle\_interval'] This option tells Chart, how many angle lines should be drawn. 
+                         It is the difference between two angle lines. 
+                         The default value is 30, which means 
+                         that a line will be drawn every 30 degrees. 
+                         There are not all values allowed. 
+                         Valid Values are: 0, 5, 10, 15, 20, 30, 45 and 90. 
+                         If you choose 0, Chart will draw no line.
+                         
+\item['pt\_size']Sets the radius of the points in pixels. Default is 18.
+
+\item['brush\_size']Sets the width of the lines in pixels. Default is 6.
+
+\item['min\_circles'] Sets the minimum number of circles to draw when generating a scale. 
+                      Default is 4, the minimum is 2.
+
+\item['max\_circles'] Sets the maximum number of circles to draw when generating a scale. 
+                      Default is 100. 
+                      This limit is used to avoid plotting an unreasonable large number of ticks 
+                      if non-round values are used for the min\_val and max\_val.\\
+                      The value for 'max\_circles' should be at least 5 times 
+                      larger than 'min\_circles'.
+\end{description}
\ No newline at end of file


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/direction.tex
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/error.png
===================================================================
(Binary files differ)


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/error.png
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:mime-type
   + application/octet-stream

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/error.tex
===================================================================
--- packages/libchart-perl/branches/upstream/current/doc/LaTeX/error.tex	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/doc/LaTeX/error.tex	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,94 @@
+%
+% error.tex
+%
+\section{Chart::ErrorBars}
+\name{Chart::ErrorBars}
+\file{ErrorBars.pm}
+\requires{Chart::Base, GD, Carp, FileHandle}
+
+\begin{Description} 
+\class{ErrorBars} is a subclass of \class{Chart::Base}.
+The class \class{ErrorBars} creates a point chart with error bars.\\
+Chart expects the error values within the data array. 
+By use of the \method{add\_dataset()} method the error values are the next two sets after the y values. The first set after the y values has to be a set values for the upper error bars. 
+The next set is an array of the down errors.\\
+If you want to use the same value for the up and down error, then you have to set the 
+'same\_error' option to 'true'. In this case only one set after the y values is interpreted 
+as a set of errors.\\
+Of course, it's also possible to use the \method{add\_pt()} method in a respective way.
+\end{Description}
+
+\parindent 0pt{\large Example:}
+\begin{figure}[h]
+	\begin{center}
+		\includegraphics[scale=0.7]{error.png}
+	\end{center}
+	\caption{Error bars chart}
+	\label{fig:error}
+\end{figure}
+
+\begin{verbatim}
+use Chart::ErrorBars;
+$g = Chart::ErrorBars->new();
+
+#the x values
+$g->add_dataset(qw(1   1.1  1.2  1.3  1.4  1.5  1.6  1.7  1.8  1.9  2
+                   2.1 2.2  2.3  2.4  2.5));
+#the y values
+$g->add_dataset(qw(1   1.1  1.2  1.1  1.14 1.15 1.26 1.2  1.1  1.19 1.2
+                   1.4 1.6  2.0  2.5  3.1));
+#the up errors
+$g->add_dataset(qw(0.4 0.1  0.2  0.1  0.14 0.15 0.26 0.27 0.1  0.19 0.2
+                   0.1 0.1  0.2  0.1  0.3));
+#the down errors
+$g->add_dataset(qw(0.2 0.11 0.12 0.11 0.2  0.3  0.12 0.27 0.11 0.3  0.2
+                   0.2 0.2  0.1  0.1  0.2));
+                   
+$g->set( 'xy_plot' => 'true',
+         'precision' => 1,
+         'pt_size' =>10, 'brush_size' => 2,
+         'legend' => 'none',
+         'title' => 'Error Bars Demo',
+         'grid_lines' => 'true');
+
+$g->png("errorbars.png");
+\end{verbatim}
+
+\begin{Constructor}
+An instance of a error bars chart object can be created with the constructor new():
+\begin{quote}
+\parindent 0pt
+\fett{\$obj = Chart::ErrorBars->new();}\\
+\fett{\$obj = Chart::ErrorBars->new(\parameter{width}, \parameter{height});}
+\end{quote}
+
+If \textit{new()} has no arguments, the constructor returns an image with the size 300x400 pixels. If \textit{new()} has two arguments \parameter{width} and \parameter{height}, 
+it returns an image with the desired size.
+\end{Constructor}
+
+
+\Methods
+\method{All universal valid methods, see page \pageref{methods}: \class{Chart::Base}.} \\[\parabstand]
+
+
+\Attributes
+All universally valid options, see page \pageref{options}. Also available these special options:
+\begin{description}
+\item['same\_error'] Tells chart that you want to use the same error value of a data point 
+     if set to true. 
+     Then you have to add just one set of error values. Defaults to 'false'.
+     
+\item['y\_axes'] Tells chart where to place the y-axis. 
+     Valid values are 'left', 'right' and 'both'. Defaults to 'left'.
+
+\item['pt\_size']Sets the radius of the points in pixels. Default is 18.
+
+\item['brush\_size']Sets the width of the lines in pixels. Default is 6.
+
+\item['xy\_plot']Forces Chart to plot a x-y-graph, 
+      which means that the x-axis is also numeric if set to 'true'. 
+      Very useful for plots of mathematical functions. Defaults to 'false'.
+
+\item['sort']Sorts the data of a x-y-graph ascending if set to 'true'. 
+      Should be set if the added data isn't sorted. Defaults to 'false'. 
+\end{description}


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/error.tex
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/example.tex
===================================================================
--- packages/libchart-perl/branches/upstream/current/doc/LaTeX/example.tex	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/doc/LaTeX/example.tex	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1 @@
+\section{Example}


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/example.tex
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/hbars.tex
===================================================================
--- packages/libchart-perl/branches/upstream/current/doc/LaTeX/hbars.tex	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/doc/LaTeX/hbars.tex	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,71 @@
+%
+% hbars.tex
+%
+\section{Chart::HorizontalBars}
+\name{Chart::HorizontalBars}
+\file{HorizontalBars.pm}
+\requires{Chart::Base, GD, Carp, FileHandle}
+\begin{Description} 
+\class{HorizontalBars} is a subclass of \class{Chart::Base}.\\
+The class \class{HorizontalBars} creates a chart with bars, that run horizontal.
+\end{Description}
+
+\parindent 0pt{\large Example:}
+
+\begin{figure}[h]
+	\begin{center}
+		\includegraphics[scale=0.7]{d_hbars4.png}
+	\end{center}
+	\caption{Chart with horizontal bars}
+	\label{fig:hbars}
+\end{figure}
+\begin{verbatim}
+use Chart::HorizontalBars;
+
+$g = Chart::HorizontalBars->new();
+$g->add_dataset ('Foo', 'bar', 'junk', 'ding', 'bat');
+$g->add_dataset (4, 3, 4, 2, 8);
+$g->add_dataset (2, 10, 3, 8, 3);
+
+%hash = ( 'title' => 'Horizontal Bars Demo',
+          'grid_lines' => 'true',
+          'x_label' => 'x-axis',
+          'y_label' => 'y-axis',
+          'include_zero' => 'true',
+          'x_ticks' => 'vertical',
+         );
+$g->set (%hash);
+
+$g->png ("hbars.png");
+\end{verbatim}
+
+\begin{Constructor} 
+An instance of a HorizontalBars object can be created with the constructor new():
+\begin{quote}
+\parindent 0pt
+\fett{\$obj = Chart::HorizontalBars->new();}\\
+\fett{\$obj = Chart::HorizontalBars->new(\parameter{width}, \parameter{height});}
+\end{quote}
+
+If \textit{new()} has no arguments, the constructor returns an image with the size 300x400 pixels.
+If \textit{new()} has two arguments \parameter{width} and \parameter{height}, 
+it returns an image with the desired size.
+\end{Constructor}
+
+\Methods
+\method{All universal valid methods, see page \pageref{methods}: Chart::Base.}\\[\parabstand]
+%
+\Attributes
+All universally valid options, see page \pageref{options}. Also available, these special options:
+\begin{description}
+\item['y\_axes'] Tells chart where to place the y-axis. 
+      Valid values are 'left', 'right' and 'both'. Defaults to 'left'.
+
+\item['spaced\_bars'] Leaves space between the groups of bars 
+     at each data point when set to 'true'.  
+     This just makes it easier to read a bar chart.  Default is 'true'.
+
+\item['skip\_y\_ticks'] 
+     Does the same fo the y-axis at a HorizontalBars chart as 'skip\_x\_ticks' 
+     does for other charts. Defaults to 1.
+\end{description}


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/hbars.tex
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/lines.tex
===================================================================
--- packages/libchart-perl/branches/upstream/current/doc/LaTeX/lines.tex	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/doc/LaTeX/lines.tex	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,94 @@
+%
+% lines.tex
+%
+\section{Chart::Lines}
+\name{Chart::Lines}
+\file{Lines.pm}
+\requires{Chart::Base, GD, Carp, FileHandle}
+\begin{Description}
+\class{Lines} is a subclass of \class{Chart::Base}.\\
+The class Lines creates a lines chart.
+\end{Description}
+
+\parindent 0pt{\large Example:}
+
+
+\begin{figure}[h]
+	\begin{center}
+		\includegraphics[scale=0.5]{d_lines2.png}
+	\end{center}
+	\caption{Lines chart}
+	\label{fig:lines}
+\end{figure}
+\begin{verbatim}
+use Chart::Lines;
+
+$g = Chart::Lines->new();
+$g->add_dataset ('foo', 'bar', 'junk', 'ding', 'bat');
+$g->add_dataset ( -4,  3, -4, -5, -2);
+$g->add_dataset (  2, 10, -3,  8,  3);
+$g->add_dataset (-10,  2,  4, -3, -3);
+$g->add_dataset (  7, -5, -3,  4,  7);
+
+%hash = ('legend_labels' => ['1st Quarter', '2nd Quarter',
+                             '3rd Quarter', '4th Quarter'],
+         'y_axes' => 'both',
+         'title' => 'Lines Demo',
+         'grid_lines' => 'true',
+         'legend' => 'left',
+         'legend_example_size' => 20,
+         'colors' => {'text' => 'blue',
+                      'misc' => 'blue',
+                      'background' => 'grey',
+                      'grid_lines' => 'light_blue',
+                      'dataset0' => [220,0,0],
+                      'dataset1' => [200,0,100],
+                      'dataset2' => [150,50,175],
+                      'dataset3' => [170,0,255] },
+         );
+
+$g->set (%hash);
+
+$g->png ("lines.png");
+\end{verbatim}
+
+\begin{Constructor} 
+An instance of a lines chart object can be created with the constructor \textit{new()}:
+\begin{quote}
+\fett{\$obj = Chart::Lines->new();}\\
+\fett{\$obj = Chart::Lines->new(\parameter{width}, \parameter{height});}
+\end{quote}
+If \textit{new()} has no arguments, 
+the constructor returns an image with the size 300x400 pixels. If new has two arguments
+\parameter{width} and \parameter{height}, it returns an image with the desired size.
+\end{Constructor}
+
+\Methods
+\method{All universal valid methods, see page \pageref{methods} of \class{Chart::Base}.}\\[\parabstand]
+%
+\Attributes
+All universal valid options, see page \pageref{options}. 
+Special options for this type of chart are:\\
+\begin{description}
+\item['y\_axes'] Tells chart where to place the y-axis. 
+                 Valid values are 'left', 'right' and 'both'. Defaults to 'left'.
+
+\item['brush\_size'] Sets the width of the lines in pixels. Default is 6.
+
+\item['xy\_plot'] Forces Chart to plot a x-y-graph, which means that the x-axis 
+                  is also numeric if set to 'true'. 
+                  Very useful for plots of mathematical functions. Defaults to 'false'.
+
+\item['sort'] Sorts the data of a x-y-graph ascending if set to 'true'. 
+              Should be set if the added data isn't sorted. Defaults to 'false'.   
+
+\item['stepline'] The points are connected by a stepping function,
+                  instead by a direct line if set to 'true'. 
+                  Defaults to 'false'.   
+
+\item['stepline\_mode'] Determine whether to start with the first point
+                    (if set to 'begin') or end with the last point if set to 'end'.
+                    Defaults to 'begin'.   
+\end{description}
+
+


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/lines.tex
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/linespoints.tex
===================================================================
--- packages/libchart-perl/branches/upstream/current/doc/LaTeX/linespoints.tex	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/doc/LaTeX/linespoints.tex	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,108 @@
+%
+% linespoints.tex
+%
+\section{Chart::LinesPoints}
+\name{Chart::LinesPoints}
+\file{LinesPoints.pm}
+\requires{Chart::Base, GD, Carp, FileHandle}
+\begin{Description} 
+\class{LinesPoints} is a subclass of \class{Chart::Base}.
+The class \class{LinesPoints} creates a lines chart with points marking the 
+individual koordinates of the data.
+\end{Description}
+
+\parindent 0pt{\large Example:}
+
+\begin{figure}[h]
+	\begin{center}
+		\includegraphics[scale=0.6]{d_linesp2.png}
+	\end{center}
+	\caption{Linespoints chart}
+	\label{fig:d_linesp2}
+\end{figure}
+\begin{verbatim}
+use Chart::LinesPoints;
+use strict;
+
+my (@data1, @data2, @data4, @data3, @labels, %hash, $g);
+
+ at labels = qw(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17);
+ at data1 = qw (-7 -5 -6 -8 -9 -7 -5 -4 -3 -2 -4 -6 -3 -5 -3 -4 -6);
+ at data2 = qw (-1 -1 -1 -1 -2 -2 -3 -3 -4 -4 -6 -3 -2 -2 -2 -1 -1);
+ at data3 = qw (-4 -4 -3 -2 -1 -1 -1 -2 -1 -1 -3 -2 -4 -3 -4 -2 -2);
+ at data4 = qw (-6 -3 -2 -3 -3 -3 -2 -1 -2 -3 -1 -1 -1 -1 -1 -3 -3);
+
+$g = Chart::LinesPoints->new(600,300);
+$g->add_dataset(@labels);
+$g->add_dataset(@data1);
+$g->add_dataset(@data2);
+$g->add_dataset(@data3);
+$g->add_dataset(@data4);
+
+%hash =(
+          'integer_ticks_only' => 'true',
+          'title' => 'Soccer Season 2002\n ',
+          'legend_labels' => ['NY Soccer Club', 'Denver Tigers',
+                              'Houston Spacecats', 'Washington Presidents'],
+          'y_label' => 'position in the table',
+          'x_label' => 'day of play',
+          'grid_lines' => 'true',
+          'f_y_tick' => \&formatter,
+          );
+
+$g->set ( %hash);
+$g->png ("Grafiken/d_linesp2.png");
+
+#just a trick, to let the y scale start at the biggest point:
+#initiate with negative values, remove the minus sign!
+sub formatter {
+  my $label = shift;
+  $label = substr($label, 1,2);
+  return $label;
+}
+
+\end{verbatim}
+
+\begin{Constructor} 
+An instance of a linespoints chart object can be created with the constructor 
+\textit{new()}:
+\begin{quote}
+\parindent 0pt
+\fett{\$obj = Chart::LinesPoints->new();}\\
+\fett{\$obj = Chart::LinesPoints->new(\parameter{width}, \parameter{height});}
+\end{quote}
+
+If \textit{new()} has no arguments, the constructor returns an image with the size 300x400 pixels.
+If \textit{new()} has two arguments \parameter{width} and \parameter{height}, 
+it returns an image with the desired size.
+\end{Constructor}
+
+\Methods
+\method{All universal valid methods, see page \pageref{methods} of \class{Chart::Base}.} \\[\parabstand]
+%
+\Attributes
+All universal valid options, see page \pageref{options}. 
+Also available these special options:
+\begin{description}
+\item['y\_axes'] Tells chart where to place the y-axis. 
+     Valid values are 'left', 'right' and 'both'. Defaults to 'left'.
+
+\item['pt\_size'] Sets the radius of the points in pixels. Default is 18.
+
+\item['brush\_size'] Sets the width of the lines in pixels. Default is 6.
+
+\item['xy\_plot'] Forces Chart to plot a x-y-graph, 
+                  which means that the x-axis is also numeric if set to 'true'. 
+                  Very useful for plots of mathematical functions. Defaults to 'false'.
+
+\item['sort'] Sorts the data of a x-y-graph ascending if set to 'true'. 
+              Should be set if the added data isn't sorted. Defaults to 'false'.  
+              
+\item['stepline'] The points are connected by a stepping function,
+                  instead by a direct line if set to 'true'. 
+                  Defaults to 'false'.   
+
+\item['stepline\_mode'] Determine whether to start with the first point
+                    (if set to 'begin') or end with the last point if set to 'end'.
+                    Defaults to 'begin'.   
+\end{description}


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/linespoints.tex
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/mountain-1.png
===================================================================
(Binary files differ)


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/mountain-1.png
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:mime-type
   + application/octet-stream

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/mountain.png
===================================================================
(Binary files differ)


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/mountain.png
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:mime-type
   + application/octet-stream

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/mountain.tex
===================================================================
--- packages/libchart-perl/branches/upstream/current/doc/LaTeX/mountain.tex	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/doc/LaTeX/mountain.tex	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,61 @@
+%
+% mountain.tex
+%
+\section{Chart::Mountain}
+\name{Chart::Mountain}
+\file{Mountain.pm}
+\requires{Chart::Base, GD, Carp, FileHandle}
+\begin{Description} 
+\class{Mountain} is a subclass of Chart::Base.
+The class Mountain creates a mountain chart.
+\end{Description}
+
+\parindent 0pt{\large Example:}
+\begin{figure}[h]
+	\begin{center}
+		\includegraphics[scale =0.6]{mountain.png}
+	\end{center}
+	\caption{Mountain chart}
+	\label{fig:mountain}
+\end{figure}
+\begin{verbatim}
+use Chart::Mountain;
+
+$g = Chart::Mountain->new();
+
+ at data = [ [1910, 1930, 1950, 1970],
+          [1, 3, 4, 2],
+          [2, 4, 3, 3],
+          [0.5, 1, 2, 1]];
+
+$g->set('title' => 'Mountain Chart',
+        'grid_lines' => 'false',
+        'precision' => 1);
+
+$g->png("mountain.png", @data);
+\end{verbatim}
+
+\begin{Constructor} 
+An instance of a mountain chart object can be created with the constructor \textit{new()}:
+\begin{quote}
+\fett{\$obj = Chart::Mountain->new();}\\
+\fett{\$obj = Chart::Mountain->new(\kursiv{width}, \kursiv{height});}
+\end{quote}
+If \textit{new()} has no arguments, 
+the constructor returns an image with the size 300x400 pixels. If \textit{new()} 
+has two arguments \parameter{width} and \parameter{height}, 
+it returns an image with the desired size.
+\end{Constructor}
+
+
+\Methods
+\method{All universal valid methods, see page \pageref{methods}
+of \class{Chart::Base}.} \\[\parabstand]
+%
+\Attributes
+All universal valid options, see page \pageref{options}. 
+Also available, these special options:
+\begin{description}
+\item['y\_axes'] Tells chart where to place the y-axis. 
+                Valid values are 'left', 'right' and 'both'. Defaults to 'left'.
+\end{description}


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/mountain.tex
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/ort.png
===================================================================
(Binary files differ)


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/ort.png
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:mime-type
   + application/octet-stream

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/pareto.tex
===================================================================
--- packages/libchart-perl/branches/upstream/current/doc/LaTeX/pareto.tex	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/doc/LaTeX/pareto.tex	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,62 @@
+%
+% paretio.tex
+%
+\section{Chart::Pareto}
+\name{Chart::Pareto}
+\file{Pareto.pm}
+\requires{Chart::Base, GD, Carp, FileHandle}
+\begin{Description} 
+\class{Pareto} is a subclass of class \class{Chart::Base}.
+The class \class{Pareto} creates a pare-to chart. 
+Pareto plots only one dataset and its labels.
+\end{Description}
+
+\parindent 0pt{\large Example:}
+
+\begin{figure}[h]
+	\begin{center}
+		\includegraphics[scale=0.7]{d_pareto2.png}
+	\end{center}
+	\caption{Pare-to chart}
+	\label{fig:pareto}
+\end{figure}
+\begin{verbatim}
+use Chart::Pareto;
+
+$g = Chart::Pareto->new(500,400);
+$g->add_dataset ('1st week', '2nd week', '3rd week', '4th week', '5th week',
+                 '6th week', '7th week', '8th week', '9th week', '10th week');
+$g->add_dataset (37, 15, 9 , 4, 3.5,
+                  2.1, 1.2, 1.5, 6.2, 16);
+
+%hash =( 'colors' => { 'dataset0' => 'mauve',
+                       'dataset1' => 'light_blue',
+                       'title' => 'orange'},
+         'title' => 'Visitors at the Picasso Exhibition',
+         'integer_ticks_only' => 'true',
+         'skip_int_ticks' => 5,
+         'grey_background' => 'false',
+         'max_val' => 100,
+         'y_label' => 'Visitors in Thousands',
+         'x_ticks' => 'vertical',
+ 	       'spaced_bars' => 'true',
+         'legend' => 'none'
+        );
+	
+$g->set (%hash); 
+$g->png ("pareto.png");
+\end{verbatim}
+\herv{Constructor:} An instance of a pare-to chart object can be created with the constructor new():\\
+\fett{\$obj = Chart::Pareto->new();}\\
+\fett{\$obj = Chart::Pareto->new(\kursiv{width}, \kursiv{height});}\\
+\\
+If \fett{new} has no arguments, the constructor returns an image with the size 300x400 pixels. If new has two arguments \kursiv{width} and \kursiv{height}, it returns an image with the desired size. \\ 
+\\ 
+\herv{Methods:}All universally valid methods, see page \pageref{methods}: Chart::Base. \\
+\\
+\herv{Attributes/Options:} All universally valid options, see page \pageref{options}. Also available, these special options:
+\begin{description}
+\item['y\_axes'] Tells chart where to place the y-axis. Valid values are 'left', 'right' and 'both'. Defaults to 'left'.
+\item['spaced\_bars']Leaves space between bars at each data point when set to 'true'.  This just makes it easier to read a bar chart.  Default is 'true'.
+\item['sort']Sorts the data descending if set to 'true'. Defaults to 'false'.  
+\end{description}
\ No newline at end of file


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/pareto.tex
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/pie.tex
===================================================================
--- packages/libchart-perl/branches/upstream/current/doc/LaTeX/pie.tex	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/doc/LaTeX/pie.tex	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,89 @@
+%
+% pie.tex
+%
+\section{Chart::Pie}
+\name{Chart::Pie}
+\file{Pie.pm}
+\requires{Chart::Base, GD, Carp, FileHandle}
+\begin{Description} 
+\class{Pie} is a subclass of class \class{Chart::Base}.
+The class \class{Pie} creates a pie chart. The first added set are the labels. 
+The second set are the values.
+\end{Description}
+
+\parindent 0pt{\large Example:}
+
+\begin{figure}[h]
+	\begin{center}
+		\includegraphics[scale = 0.6]{d_pie3.png}
+	\end{center}
+	\caption{Pie chart}
+	\label{fig:pie}
+\end{figure}
+\begin{verbatim}
+use Chart::Pie;
+
+$g = Chart::Pie->new();
+
+$g->add_dataset ('Har', 'Sug', 'Ert', 'Her', 'Tar', 'Kure');
+$g->add_dataset (12000, 20000 , 13000, 15000, 9000, 11000  );
+
+%opt = ( 'title' => 'Another Pie Demo Chart',
+         'label_values' => 'both',
+         'legend' => 'none',
+         'text_space' => 10,
+         'png_border' => 1,
+         'graph_border' => 0,
+         'colors' => { 'x_label' => 'red',
+                       'misc' => 'plum',
+                       'background' => 'grey',
+                       'dataset0' => [120, 0, 255],
+                       'dataset1' => [120, 100, 255],
+                       'dataset2' => [120, 200, 255],
+                       'dataset3' => [255, 100, 0],
+                       'dataset4' => [255, 50, 0],
+                       'dataset5' => [255, 0, 0],
+                     },
+         'x_label' => 'The Winner is Team Blue!',
+        );
+
+$g->set (%opt);
+
+$g->png ("pie.png");
+\end{verbatim}
+
+\begin{Constructor} 
+An instance of a pie chart object can be created with the constructor \textit{new()}:
+\begin{quote}
+\fett{\$obj = Chart::Pie->new();}\\
+\fett{\$obj = Chart::Pie->new(\parameter{width}, \parameter{height});}
+\end{quote}
+
+If \textit{new()} has no arguments, 
+the constructor returns an image with the size 300x400 pixels. 
+If \textit{new()} has two arguments \parameter{width} and \parameter{height}, 
+it returns an image within the desired size.
+\end{Constructor}
+
+\Methods
+All universal valid methods, see page \pageref{methods} of class \class{Chart::Base}.\\[\parabstand]
+%
+\Attributes
+All universal valid options, see page \pageref{options}. 
+Also available, these special options:
+\begin{description}
+\item['label\_values'] 
+          Tells the pie chart what labels to draw beside the pie. 
+          Valid values are 'percent', 'value', 'both' and 'none'. Defaults to 'percent'.
+
+\item['legend\_label\_values'] 
+          Tells the pie chart what labels to draw in the legend. 
+          Valid values are 'percent', 'value', 'both' and 'none'. Defaults to 'value'.
+          
+\item['legend\_lines']
+          The labels drawn aside the pie are connected with a line to the segment.
+          
+\item['ring']
+          The pie has a ring structure.          
+
+\end{description}


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/pie.tex
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/points.png
===================================================================
(Binary files differ)


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/points.png
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:mime-type
   + application/octet-stream

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/points.tex
===================================================================
--- packages/libchart-perl/branches/upstream/current/doc/LaTeX/points.tex	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/doc/LaTeX/points.tex	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,75 @@
+%
+% points.tex
+%
+\section{Chart::Points}
+\name{Chart::Points}
+\file{Points.pm}
+\requires{Chart::Base, GD, Carp, FileHandle}
+\begin{Description} 
+\class{Points} is a subclass of class \class{Chart::Base}.\\
+The class Points creates a point chart.
+\end{Description}
+
+\parindent 0pt{\large Example:}
+
+\begin{figure}[h]
+	\begin{center}
+		\includegraphics[scale=0.5]{points.png}
+	\end{center}
+	\caption{Points chart}
+	\label{fig:points}
+\end{figure}
+\begin{verbatim}
+use Chart::Points;
+
+$g = Chart::Points->new();
+$g->add_dataset (1, 4,   3, 6, 2, 2.5);  # x-coordinates
+$g->add_dataset (1, 5,   3, 2, 3, 3.2);  # y-coordinates dataset 1
+$g->add_dataset (2, 6, 4.8, 1, 4, 4.2);  # y-coordinates dataset 2
+
+ at hash = ('title' => 'Points Chart',
+         'xy_plot' => 'true',
+         'x_ticks' => 'vertical',
+         'legend' => 'none',
+         'sort' => 'true',
+         'precision' => 3,
+         'include_zero' => 'true',
+	 );
+
+$g->set (@hash);
+
+$g->png ("Grafiken/points.png");
+\end{verbatim}
+
+\begin{Constructor} 
+An instance of a points chart object can be created with the constructor \textit{new()}:
+\begin{quote}
+\fett{\$obj = Chart::Points->new();}\\
+\fett{\$obj = Chart::Points->new(\parameter{width}, \parameter{height});}
+\end{quote}
+
+If \textit{new()} has no arguments, 
+the constructor returns an image with the size 300x400 pixels. If new has two arguments 
+\parameter{width} and \parameter{height}, 
+it returns an image with the desired size.
+\end{Constructor}
+
+\Methods
+All universal valid methods, see page \pageref{methods} of class \class{Chart::Base}. \\[\parabstand]
+%
+\Attributes
+All universal valid options, see page \pageref{options}. 
+Also available these special options:
+\begin{description}
+\item['y\_axes'] Tells chart where to place the y-axis. 
+                 Valid values are 'left', 'right' and 'both'. Defaults to 'left'.
+                 
+\item['pt\_size'] Sets the radius of the points in pixels. Default is 18.
+
+\item['sort'] Sorts the data of a x-y-graph ascending if set to 'true'. 
+              Should be set if the added data isn't sorted. Defaults to 'false'.
+              
+\item['xy\_plot'] Forces Chart to plot a x-y-graph, 
+                  which means that the x-axis is also numeric if set to 'true'. 
+                   Very useful for plots of mathematical functions. Defaults to 'false'.
+\end{description}


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/points.tex
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/split.tex
===================================================================
--- packages/libchart-perl/branches/upstream/current/doc/LaTeX/split.tex	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/doc/LaTeX/split.tex	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,106 @@
+%
+% split.tex
+%
+\section{Chart::Split}
+\name{Chart::Split}
+\file{Split.pm}
+\requires{Chart::Base, GD, Carp, FileHandle}
+\begin{Description} 
+\class{Split} is a subclass of class \class{Chart::Base}.\\
+The class \class{Split} creates a lines chart. 
+Split makes always an xy-plot, which means that both axes are numeric. 
+The x-axis will be split in several parts of a same interval (option 'interval' has to be set!).
+These intervals will be drawn one upon the other. 
+The top interval starts at the start point, 
+which has to be set by the programmer (option 'start'). \\
+The first passed dataset are the x coordinates. 
+The following added sets are the y coordinates of the sets.\\
+Split draws only positive x-coordinates.\\
+The y-axis is a numbering of the intervals.\\
+The Split module is useful if you have a lot of data points to plot. An example is to plot
+weather or seismic data.
+\end{Description}
+
+\parindent 0pt{\large Example:} 
+
+\begin{figure}[h]
+	\begin{center}
+		\includegraphics[width = 10cm, height =10cm]{stunde.png}
+	\end{center}
+	\caption{Split chart}
+	\label{fig:split}
+\end{figure}
+\begin{verbatim}
+use Chart::Split;
+
+$g = Chart::Split->new(650 ,900);
+
+#get the data that are in a file and push them in arrays
+open( FILE , "data.dat") or die 'Can't open the data file!\n';
+while (defined ($line = <FILE>) ) {
+  ($x, $y,) = unpack("a11 x1 a8" , $line);
+   push (@y, $y);
+   push (@x, $x);
+}
+close (FILE);
+
+#add the data
+$g->add_dataset(@x);
+$g->add_dataset(@y);
+
+#set the options
+$g->set('xy_plot' => 'true');
+$g->set('legend' => 'none');
+$g->set('title' => 'Split Demo');
+$g->set('interval' => 1/288);
+$g->set('interval_ticks' => 10);
+$g->set('start' => 260.5);
+$g->set('brush_size' => 1);
+$g->set('precision' => 4);
+$g->set('y_label' => '5 minutes interval');
+
+#give me a nice picture
+$g->png("split.png");
+\end{verbatim}
+
+\begin{Constructor} 
+An instance of a split chart object can be created with the constructor \textit{new()}:
+\begin{quote}
+\fett{\$obj = Chart::Split->new();}\\
+\fett{\$obj = Chart::Split->new(\parameter{width}, \parameter{height});}
+\end{quote}
+
+If \textit{new()} has no arguments, 
+the constructor returns an image with the size 300x400 pixels. If new has two arguments 
+\parameter{width} and \parameter{height}, it returns an image with the desired size.
+\end{Constructor}
+
+\Methods
+All universal valid methods, see page \pageref{methods} of class
+\class{Chart::Base}.\\[\parabstand]
+%
+\Attributes
+All universal valid options, see page \pageref{options}. 
+Also available, these special options:
+\begin{description}
+\item['start'] \emph{Required} value for a split chart. \\
+               If the x coordinate of the first data point is zero, 
+               you should set start to zero. 
+               Sets the start value of the first interval. Defaults to undef.
+               
+\item['interval'] \emph{Required} value of a split chart.\\
+                Sets the interval of one line to plot. Defaults to undef.
+                
+\item['interval\_ticks'] Sets the number of ticks for the x-axis. Defaults to 5.
+
+\item['scale'] Every y-value of a split chart will be multiplied by that value, 
+               but the scale won't be changed. This means you may overdraw certain rows! 
+               Only useful if you want to give prominence to the maximal amplitudes of the data.
+               Defaults to 1.
+               
+\item['sort'] Sorts the data ascending if set to 'true'. 
+              Should be set if the added data isn't sorted. Defaults to 'false'.  
+              
+\item['y\_axes'] Tells chart where to place the y-axis. 
+                 Valid values are 'left', 'right' and 'both'. Defaults to 'left'.
+\end{description}


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/split.tex
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/stacked.tex
===================================================================
--- packages/libchart-perl/branches/upstream/current/doc/LaTeX/stacked.tex	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/doc/LaTeX/stacked.tex	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,63 @@
+%
+% stacked.tex
+%
+\section{Chart::StackedBars}
+\name{Chart::StackedBars}
+\file{StackedBars.pm}
+\requires{Chart::Base, GD, Carp, FileHandle}
+\begin{Description} 
+\class{StackedBars} is a \fett{subclass} of class \class{Chart::Base}.
+The class StackedBars creates a chart with stacked bars.
+\end{Description}
+
+\parindent 0pt{\large Example:}
+
+\begin{figure}[h]
+	\begin{center}
+		\includegraphics[scale=0.6]{stackedbars.png}
+	\end{center}
+	\caption{Chart with stacked bars}
+	\label{fig:stackedbars}
+\end{figure}
+\begin{verbatim}
+use Chart::StackedBars;
+
+$g = Chart::StackedBars->new;
+
+$g->add_dataset ('foo', 'bar', 'junk', 'taco', 'karp');
+$g->add_dataset (3, 4, 9, 10, 11);
+$g->add_dataset (8, 6, 1, 12, 1);
+$g->add_dataset (5, 7, 2, 13, 4);
+
+$g->set ('title' => 'Stacked Bar Chart');
+$g->set('y_grid_lines' => 'true');
+$g->set('legend' => 'bottom');
+
+$g->png ("Grafiken/stackedbars.png");
+\end{verbatim}
+
+\begin{Constructor} An instance of a stacked bars object can be created with the constructor
+\textit{new()}:
+\begin{quote}
+\fett{\$obj = Chart::StackedBars->new();}\\
+\fett{\$obj = Chart::StackedBars->new(\parameter{width}, \parameter{height});}
+\end{quote}
+If \textit{new()} has no arguments, 
+the constructor returns an image with the size 300x400 pixels. 
+If \textit{new()} has two arguments \parameter{width} and \parameter{height},
+it returns an image with the desired size.
+\end{Constructor}
+
+\Methods
+All universal valid methods, see page \pageref{methods}
+of class \class{Chart::Base}.\\[\parabstand]
+%
+\Attributes
+All universal valid options, see page \pageref{options}. Also available, these special options:
+\begin{description}
+\item['y\_axes'] Tells chart where to place the y-axis. 
+                 Valid values are 'left', 'right' and 'both'. Defaults to 'left'.
+\item['spaced\_bars'] Leaves space between the groups of bars at each data point 
+                      when set to 'true'.  
+                      This just makes it easier to read a bar chart.  Default is 'true'.
+\end{description}


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/stacked.tex
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/stackedbars.png
===================================================================
(Binary files differ)


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/stackedbars.png
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:mime-type
   + application/octet-stream

Added: packages/libchart-perl/branches/upstream/current/doc/LaTeX/stunde.png
===================================================================
(Binary files differ)


Property changes on: packages/libchart-perl/branches/upstream/current/doc/LaTeX/stunde.png
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:mime-type
   + application/octet-stream

Added: packages/libchart-perl/branches/upstream/current/patterns/PATTERN0.GIF
===================================================================
(Binary files differ)


Property changes on: packages/libchart-perl/branches/upstream/current/patterns/PATTERN0.GIF
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: packages/libchart-perl/branches/upstream/current/patterns/PATTERN0.PNG
===================================================================
(Binary files differ)


Property changes on: packages/libchart-perl/branches/upstream/current/patterns/PATTERN0.PNG
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: packages/libchart-perl/branches/upstream/current/patterns/PATTERN1.GIF
===================================================================
(Binary files differ)


Property changes on: packages/libchart-perl/branches/upstream/current/patterns/PATTERN1.GIF
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: packages/libchart-perl/branches/upstream/current/patterns/PATTERN1.PNG
===================================================================
(Binary files differ)


Property changes on: packages/libchart-perl/branches/upstream/current/patterns/PATTERN1.PNG
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: packages/libchart-perl/branches/upstream/current/patterns/PATTERN2.GIF
===================================================================
(Binary files differ)


Property changes on: packages/libchart-perl/branches/upstream/current/patterns/PATTERN2.GIF
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: packages/libchart-perl/branches/upstream/current/patterns/PATTERN2.PNG
===================================================================
(Binary files differ)


Property changes on: packages/libchart-perl/branches/upstream/current/patterns/PATTERN2.PNG
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: packages/libchart-perl/branches/upstream/current/patterns/PATTERN3.GIF
===================================================================
(Binary files differ)


Property changes on: packages/libchart-perl/branches/upstream/current/patterns/PATTERN3.GIF
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: packages/libchart-perl/branches/upstream/current/patterns/PATTERN3.PNG
===================================================================
(Binary files differ)


Property changes on: packages/libchart-perl/branches/upstream/current/patterns/PATTERN3.PNG
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: packages/libchart-perl/branches/upstream/current/patterns/PATTERN4.GIF
===================================================================
(Binary files differ)


Property changes on: packages/libchart-perl/branches/upstream/current/patterns/PATTERN4.GIF
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: packages/libchart-perl/branches/upstream/current/patterns/PATTERN4.PNG
===================================================================
(Binary files differ)


Property changes on: packages/libchart-perl/branches/upstream/current/patterns/PATTERN4.PNG
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: packages/libchart-perl/branches/upstream/current/patterns/PATTERN5.GIF
===================================================================
(Binary files differ)


Property changes on: packages/libchart-perl/branches/upstream/current/patterns/PATTERN5.GIF
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: packages/libchart-perl/branches/upstream/current/patterns/PATTERN5.PNG
===================================================================
(Binary files differ)


Property changes on: packages/libchart-perl/branches/upstream/current/patterns/PATTERN5.PNG
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: packages/libchart-perl/branches/upstream/current/pm_to_blib
===================================================================

Added: packages/libchart-perl/branches/upstream/current/rgb.txt
===================================================================
--- packages/libchart-perl/branches/upstream/current/rgb.txt	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/rgb.txt	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,753 @@
+255 250 250		snow
+248 248 255		ghost white
+248 248 255		GhostWhite
+245 245 245		white smoke
+245 245 245		WhiteSmoke
+220 220 220		gainsboro
+255 250 240		floral white
+255 250 240		FloralWhite
+253 245 230		old lace
+253 245 230		OldLace
+250 240 230		linen
+250 235 215		antique white
+250 235 215		AntiqueWhite
+255 239 213		papaya whip
+255 239 213		PapayaWhip
+255 235 205		blanched almond
+255 235 205		BlanchedAlmond
+255 228 196		bisque
+255 218 185		peach puff
+255 218 185		PeachPuff
+255 222 173		navajo white
+255 222 173		NavajoWhite
+255 228 181		moccasin
+255 248 220		cornsilk
+255 255 240		ivory
+255 250 205		lemon chiffon
+255 250 205		LemonChiffon
+255 245 238		seashell
+240 255 240		honeydew
+245 255 250		mint cream
+245 255 250		MintCream
+240 255 255		azure
+240 248 255		alice blue
+240 248 255		AliceBlue
+230 230 250		lavender
+255 240 245		lavender blush
+255 240 245		LavenderBlush
+255 228 225		misty rose
+255 228 225		MistyRose
+255 255 255		white
+  0   0   0		black
+ 47  79  79		dark slate gray
+ 47  79  79		DarkSlateGray
+ 47  79  79		dark slate grey
+ 47  79  79		DarkSlateGrey
+105 105 105		dim gray
+105 105 105		DimGray
+105 105 105		dim grey
+105 105 105		DimGrey
+112 128 144		slate gray
+112 128 144		SlateGray
+112 128 144		slate grey
+112 128 144		SlateGrey
+119 136 153		light slate gray
+119 136 153		LightSlateGray
+119 136 153		light slate grey
+119 136 153		LightSlateGrey
+190 190 190		gray
+190 190 190		grey
+211 211 211		light grey
+211 211 211		LightGrey
+211 211 211		light gray
+211 211 211		LightGray
+ 25  25 112		midnight blue
+ 25  25 112		MidnightBlue
+  0   0 128		navy
+  0   0 128		navy blue
+  0   0 128		NavyBlue
+100 149 237		cornflower blue
+100 149 237		CornflowerBlue
+ 72  61 139		dark slate blue
+ 72  61 139		DarkSlateBlue
+106  90 205		slate blue
+106  90 205		SlateBlue
+123 104 238		medium slate blue
+123 104 238		MediumSlateBlue
+132 112 255		light slate blue
+132 112 255		LightSlateBlue
+  0   0 205		medium blue
+  0   0 205		MediumBlue
+ 65 105 225		royal blue
+ 65 105 225		RoyalBlue
+  0   0 255		blue
+ 30 144 255		dodger blue
+ 30 144 255		DodgerBlue
+  0 191 255		deep sky blue
+  0 191 255		DeepSkyBlue
+135 206 235		sky blue
+135 206 235		SkyBlue
+135 206 250		light sky blue
+135 206 250		LightSkyBlue
+ 70 130 180		steel blue
+ 70 130 180		SteelBlue
+176 196 222		light steel blue
+176 196 222		LightSteelBlue
+173 216 230		light blue
+173 216 230		LightBlue
+176 224 230		powder blue
+176 224 230		PowderBlue
+175 238 238		pale turquoise
+175 238 238		PaleTurquoise
+  0 206 209		dark turquoise
+  0 206 209		DarkTurquoise
+ 72 209 204		medium turquoise
+ 72 209 204		MediumTurquoise
+ 64 224 208		turquoise
+ 64 160 192		SunBlue
+  0 255 255		cyan
+224 255 255		light cyan
+224 255 255		LightCyan
+ 95 158 160		cadet blue
+ 95 158 160		CadetBlue
+102 205 170		medium aquamarine
+102 205 170		MediumAquamarine
+127 255 212		aquamarine
+  0 100   0		dark green
+  0 100   0		DarkGreen
+ 85 107  47		dark olive green
+ 85 107  47		DarkOliveGreen
+143 188 143		dark sea green
+143 188 143		DarkSeaGreen
+ 46 139  87		sea green
+ 46 139  87		SeaGreen
+ 60 179 113		medium sea green
+ 60 179 113		MediumSeaGreen
+ 32 178 170		light sea green
+ 32 178 170		LightSeaGreen
+152 251 152		pale green
+152 251 152		PaleGreen
+  0 255 127		spring green
+  0 255 127		SpringGreen
+124 252   0		lawn green
+124 252   0		LawnGreen
+  0 255   0		green
+127 255   0		chartreuse
+  0 250 154		medium spring green
+  0 250 154		MediumSpringGreen
+173 255  47		green yellow
+173 255  47		GreenYellow
+ 50 205  50		lime green
+ 50 205  50		LimeGreen
+154 205  50		yellow green
+154 205  50		YellowGreen
+ 34 139  34		forest green
+ 34 139  34		ForestGreen
+107 142  35		olive drab
+107 142  35		OliveDrab
+189 183 107		dark khaki
+189 183 107		DarkKhaki
+240 230 140		khaki
+238 232 170		pale goldenrod
+238 232 170		PaleGoldenrod
+250 250 210		light goldenrod yellow
+250 250 210		LightGoldenrodYellow
+255 255 224		light yellow
+255 255 224		LightYellow
+255 255   0		yellow
+255 215   0 		gold
+238 221 130		light goldenrod
+238 221 130		LightGoldenrod
+218 165  32		goldenrod
+184 134  11		dark goldenrod
+184 134  11		DarkGoldenrod
+188 143 143		rosy brown
+188 143 143		RosyBrown
+205  92  92		indian red
+205  92  92		IndianRed
+139  69  19		saddle brown
+139  69  19		SaddleBrown
+160  82  45		sienna
+205 133  63		peru
+222 184 135		burlywood
+245 245 220		beige
+245 222 179		wheat
+244 164  96		sandy brown
+244 164  96		SandyBrown
+210 180 140		tan
+210 105  30		chocolate
+178  34  34		firebrick
+165  42  42		brown
+233 150 122		dark salmon
+233 150 122		DarkSalmon
+250 128 114		salmon
+255 160 122		light salmon
+255 160 122		LightSalmon
+255 165   0		orange
+255 140   0		dark orange
+255 140   0		DarkOrange
+255 127  80		coral
+240 128 128		light coral
+240 128 128		LightCoral
+255  99  71		tomato
+255  69   0		orange red
+255  69   0		OrangeRed
+255   0   0		red
+255 105 180		hot pink
+255 105 180		HotPink
+255  20 147		deep pink
+255  20 147		DeepPink
+255 192 203		pink
+255 182 193		light pink
+255 182 193		LightPink
+219 112 147		pale violet red
+219 112 147		PaleVioletRed
+176  48  96		maroon
+199  21 133		medium violet red
+199  21 133		MediumVioletRed
+208  32 144		violet red
+208  32 144		VioletRed
+255   0 255		magenta
+238 130 238		violet
+221 160 221		plum
+218 112 214		orchid
+186  85 211		medium orchid
+186  85 211		MediumOrchid
+153  50 204		dark orchid
+153  50 204		DarkOrchid
+148   0 211		dark violet
+148   0 211		DarkViolet
+138  43 226		blue violet
+138  43 226		BlueViolet
+160  32 240		purple
+147 112 219		medium purple
+147 112 219		MediumPurple
+216 191 216		thistle
+255 250 250		snow1
+238 233 233		snow2
+205 201 201		snow3
+139 137 137		snow4
+255 245 238		seashell1
+238 229 222		seashell2
+205 197 191		seashell3
+139 134 130		seashell4
+255 239 219		AntiqueWhite1
+238 223 204		AntiqueWhite2
+205 192 176		AntiqueWhite3
+139 131 120		AntiqueWhite4
+255 228 196		bisque1
+238 213 183		bisque2
+205 183 158		bisque3
+139 125 107		bisque4
+255 218 185		PeachPuff1
+238 203 173		PeachPuff2
+205 175 149		PeachPuff3
+139 119 101		PeachPuff4
+255 222 173		NavajoWhite1
+238 207 161		NavajoWhite2
+205 179 139		NavajoWhite3
+139 121	 94		NavajoWhite4
+255 250 205		LemonChiffon1
+238 233 191		LemonChiffon2
+205 201 165		LemonChiffon3
+139 137 112		LemonChiffon4
+255 248 220		cornsilk1
+238 232 205		cornsilk2
+205 200 177		cornsilk3
+139 136 120		cornsilk4
+255 255 240		ivory1
+238 238 224		ivory2
+205 205 193		ivory3
+139 139 131		ivory4
+240 255 240		honeydew1
+224 238 224		honeydew2
+193 205 193		honeydew3
+131 139 131		honeydew4
+255 240 245		LavenderBlush1
+238 224 229		LavenderBlush2
+205 193 197		LavenderBlush3
+139 131 134		LavenderBlush4
+255 228 225		MistyRose1
+238 213 210		MistyRose2
+205 183 181		MistyRose3
+139 125 123		MistyRose4
+240 255 255		azure1
+224 238 238		azure2
+193 205 205		azure3
+131 139 139		azure4
+131 111 255		SlateBlue1
+122 103 238		SlateBlue2
+105  89 205		SlateBlue3
+ 71  60 139		SlateBlue4
+ 72 118 255		RoyalBlue1
+ 67 110 238		RoyalBlue2
+ 58  95 205		RoyalBlue3
+ 39  64 139		RoyalBlue4
+  0   0 255		blue1
+  0   0 238		blue2
+  0   0 205		blue3
+  0   0 139		blue4
+ 30 144 255		DodgerBlue1
+ 28 134 238		DodgerBlue2
+ 24 116 205		DodgerBlue3
+ 16  78 139		DodgerBlue4
+ 99 184 255		SteelBlue1
+ 92 172 238		SteelBlue2
+ 79 148 205		SteelBlue3
+ 54 100 139		SteelBlue4
+  0 191 255		DeepSkyBlue1
+  0 178 238		DeepSkyBlue2
+  0 154 205		DeepSkyBlue3
+  0 104 139		DeepSkyBlue4
+135 206 255		SkyBlue1
+126 192 238		SkyBlue2
+108 166 205		SkyBlue3
+ 74 112 139		SkyBlue4
+176 226 255		LightSkyBlue1
+164 211 238		LightSkyBlue2
+141 182 205		LightSkyBlue3
+ 96 123 139		LightSkyBlue4
+198 226 255		SlateGray1
+185 211 238		SlateGray2
+159 182 205		SlateGray3
+108 123 139		SlateGray4
+202 225 255		LightSteelBlue1
+188 210 238		LightSteelBlue2
+162 181 205		LightSteelBlue3
+110 123 139		LightSteelBlue4
+191 239 255		LightBlue1
+178 223 238		LightBlue2
+154 192 205		LightBlue3
+104 131 139		LightBlue4
+224 255 255		LightCyan1
+209 238 238		LightCyan2
+180 205 205		LightCyan3
+122 139 139		LightCyan4
+187 255 255		PaleTurquoise1
+174 238 238		PaleTurquoise2
+150 205 205		PaleTurquoise3
+102 139 139		PaleTurquoise4
+152 245 255		CadetBlue1
+142 229 238		CadetBlue2
+122 197 205		CadetBlue3
+ 83 134 139		CadetBlue4
+  0 245 255		turquoise1
+  0 229 238		turquoise2
+  0 197 205		turquoise3
+  0 134 139		turquoise4
+  0 255 255		cyan1
+  0 238 238		cyan2
+  0 205 205		cyan3
+  0 139 139		cyan4
+151 255 255		DarkSlateGray1
+141 238 238		DarkSlateGray2
+121 205 205		DarkSlateGray3
+ 82 139 139		DarkSlateGray4
+127 255 212		aquamarine1
+118 238 198		aquamarine2
+102 205 170		aquamarine3
+ 69 139 116		aquamarine4
+193 255 193		DarkSeaGreen1
+180 238 180		DarkSeaGreen2
+155 205 155		DarkSeaGreen3
+105 139 105		DarkSeaGreen4
+ 84 255 159		SeaGreen1
+ 78 238 148		SeaGreen2
+ 67 205 128		SeaGreen3
+ 46 139	 87		SeaGreen4
+154 255 154		PaleGreen1
+144 238 144		PaleGreen2
+124 205 124		PaleGreen3
+ 84 139	 84		PaleGreen4
+  0 255 127		SpringGreen1
+  0 238 118		SpringGreen2
+  0 205 102		SpringGreen3
+  0 139	 69		SpringGreen4
+  0 255	  0		green1
+  0 238	  0		green2
+  0 205	  0		green3
+  0 139	  0		green4
+127 255	  0		chartreuse1
+118 238	  0		chartreuse2
+102 205	  0		chartreuse3
+ 69 139	  0		chartreuse4
+192 255	 62		OliveDrab1
+179 238	 58		OliveDrab2
+154 205	 50		OliveDrab3
+105 139	 34		OliveDrab4
+202 255 112		DarkOliveGreen1
+188 238 104		DarkOliveGreen2
+162 205	 90		DarkOliveGreen3
+110 139	 61		DarkOliveGreen4
+255 246 143		khaki1
+238 230 133		khaki2
+205 198 115		khaki3
+139 134	 78		khaki4
+255 236 139		LightGoldenrod1
+238 220 130		LightGoldenrod2
+205 190 112		LightGoldenrod3
+139 129	 76		LightGoldenrod4
+255 255 224		LightYellow1
+238 238 209		LightYellow2
+205 205 180		LightYellow3
+139 139 122		LightYellow4
+255 255	  0		yellow1
+238 238	  0		yellow2
+205 205	  0		yellow3
+139 139	  0		yellow4
+255 215	  0		gold1
+238 201	  0		gold2
+205 173	  0		gold3
+139 117	  0		gold4
+255 193	 37		goldenrod1
+238 180	 34		goldenrod2
+205 155	 29		goldenrod3
+139 105	 20		goldenrod4
+255 185	 15		DarkGoldenrod1
+238 173	 14		DarkGoldenrod2
+205 149	 12		DarkGoldenrod3
+139 101	  8		DarkGoldenrod4
+255 193 193		RosyBrown1
+238 180 180		RosyBrown2
+205 155 155		RosyBrown3
+139 105 105		RosyBrown4
+255 106 106		IndianRed1
+238  99	 99		IndianRed2
+205  85	 85		IndianRed3
+139  58	 58		IndianRed4
+255 130	 71		sienna1
+238 121	 66		sienna2
+205 104	 57		sienna3
+139  71	 38		sienna4
+255 211 155		burlywood1
+238 197 145		burlywood2
+205 170 125		burlywood3
+139 115	 85		burlywood4
+255 231 186		wheat1
+238 216 174		wheat2
+205 186 150		wheat3
+139 126 102		wheat4
+255 165	 79		tan1
+238 154	 73		tan2
+205 133	 63		tan3
+139  90	 43		tan4
+255 127	 36		chocolate1
+238 118	 33		chocolate2
+205 102	 29		chocolate3
+139  69	 19		chocolate4
+255  48	 48		firebrick1
+238  44	 44		firebrick2
+205  38	 38		firebrick3
+139  26	 26		firebrick4
+255  64	 64		brown1
+238  59	 59		brown2
+205  51	 51		brown3
+139  35	 35		brown4
+255 140 105		salmon1
+238 130	 98		salmon2
+205 112	 84		salmon3
+139  76	 57		salmon4
+255 160 122		LightSalmon1
+238 149 114		LightSalmon2
+205 129	 98		LightSalmon3
+139  87	 66		LightSalmon4
+255 165	  0		orange1
+238 154	  0		orange2
+205 133	  0		orange3
+139  90	  0		orange4
+255 127	  0		DarkOrange1
+238 118	  0		DarkOrange2
+205 102	  0		DarkOrange3
+139  69	  0		DarkOrange4
+255 114	 86		coral1
+238 106	 80		coral2
+205  91	 69		coral3
+139  62	 47		coral4
+255  99	 71		tomato1
+238  92	 66		tomato2
+205  79	 57		tomato3
+139  54	 38		tomato4
+255  69	  0		OrangeRed1
+238  64	  0		OrangeRed2
+205  55	  0		OrangeRed3
+139  37	  0		OrangeRed4
+255   0	  0		red1
+238   0	  0		red2
+205   0	  0		red3
+139   0	  0		red4
+255  20 147		DeepPink1
+238  18 137		DeepPink2
+205  16 118		DeepPink3
+139  10	 80		DeepPink4
+255 110 180		HotPink1
+238 106 167		HotPink2
+205  96 144		HotPink3
+139  58  98		HotPink4
+255 181 197		pink1
+238 169 184		pink2
+205 145 158		pink3
+139  99 108		pink4
+255 174 185		LightPink1
+238 162 173		LightPink2
+205 140 149		LightPink3
+139  95 101		LightPink4
+255 130 171		PaleVioletRed1
+238 121 159		PaleVioletRed2
+205 104 137		PaleVioletRed3
+139  71	 93		PaleVioletRed4
+255  52 179		maroon1
+238  48 167		maroon2
+205  41 144		maroon3
+139  28	 98		maroon4
+255  62 150		VioletRed1
+238  58 140		VioletRed2
+205  50 120		VioletRed3
+139  34	 82		VioletRed4
+255   0 255		magenta1
+238   0 238		magenta2
+205   0 205		magenta3
+139   0 139		magenta4
+255 131 250		orchid1
+238 122 233		orchid2
+205 105 201		orchid3
+139  71 137		orchid4
+255 187 255		plum1
+238 174 238		plum2
+205 150 205		plum3
+139 102 139		plum4
+224 102 255		MediumOrchid1
+209  95 238		MediumOrchid2
+180  82 205		MediumOrchid3
+122  55 139		MediumOrchid4
+191  62 255		DarkOrchid1
+178  58 238		DarkOrchid2
+154  50 205		DarkOrchid3
+104  34 139		DarkOrchid4
+155  48 255		purple1
+145  44 238		purple2
+125  38 205		purple3
+ 85  26 139		purple4
+171 130 255		MediumPurple1
+159 121 238		MediumPurple2
+137 104 205		MediumPurple3
+ 93  71 139		MediumPurple4
+255 225 255		thistle1
+238 210 238		thistle2
+205 181 205		thistle3
+139 123 139		thistle4
+  0   0   0		gray0
+  0   0   0		grey0
+  3   3   3		gray1
+  3   3   3		grey1
+  5   5   5		gray2
+  5   5   5		grey2
+  8   8   8		gray3
+  8   8   8		grey3
+ 10  10  10 		gray4
+ 10  10  10 		grey4
+ 13  13  13 		gray5
+ 13  13  13 		grey5
+ 15  15  15 		gray6
+ 15  15  15 		grey6
+ 18  18  18 		gray7
+ 18  18  18 		grey7
+ 20  20  20 		gray8
+ 20  20  20 		grey8
+ 23  23  23 		gray9
+ 23  23  23 		grey9
+ 26  26  26 		gray10
+ 26  26  26 		grey10
+ 28  28  28 		gray11
+ 28  28  28 		grey11
+ 31  31  31 		gray12
+ 31  31  31 		grey12
+ 33  33  33 		gray13
+ 33  33  33 		grey13
+ 36  36  36 		gray14
+ 36  36  36 		grey14
+ 38  38  38 		gray15
+ 38  38  38 		grey15
+ 41  41  41 		gray16
+ 41  41  41 		grey16
+ 43  43  43 		gray17
+ 43  43  43 		grey17
+ 46  46  46 		gray18
+ 46  46  46 		grey18
+ 48  48  48 		gray19
+ 48  48  48 		grey19
+ 51  51  51 		gray20
+ 51  51  51 		grey20
+ 54  54  54 		gray21
+ 54  54  54 		grey21
+ 56  56  56 		gray22
+ 56  56  56 		grey22
+ 59  59  59 		gray23
+ 59  59  59 		grey23
+ 61  61  61 		gray24
+ 61  61  61 		grey24
+ 64  64  64 		gray25
+ 64  64  64 		grey25
+ 66  66  66 		gray26
+ 66  66  66 		grey26
+ 69  69  69 		gray27
+ 69  69  69 		grey27
+ 71  71  71 		gray28
+ 71  71  71 		grey28
+ 74  74  74 		gray29
+ 74  74  74 		grey29
+ 77  77  77 		gray30
+ 77  77  77 		grey30
+ 79  79  79 		gray31
+ 79  79  79 		grey31
+ 82  82  82 		gray32
+ 82  82  82 		grey32
+ 84  84  84 		gray33
+ 84  84  84 		grey33
+ 87  87  87 		gray34
+ 87  87  87 		grey34
+ 89  89  89 		gray35
+ 89  89  89 		grey35
+ 92  92  92 		gray36
+ 92  92  92 		grey36
+ 94  94  94 		gray37
+ 94  94  94 		grey37
+ 97  97  97 		gray38
+ 97  97  97 		grey38
+ 99  99  99 		gray39
+ 99  99  99 		grey39
+102 102 102 		gray40
+102 102 102 		grey40
+105 105 105 		gray41
+105 105 105 		grey41
+107 107 107 		gray42
+107 107 107 		grey42
+110 110 110 		gray43
+110 110 110 		grey43
+112 112 112 		gray44
+112 112 112 		grey44
+115 115 115 		gray45
+115 115 115 		grey45
+117 117 117 		gray46
+117 117 117 		grey46
+120 120 120 		gray47
+120 120 120 		grey47
+122 122 122 		gray48
+122 122 122 		grey48
+125 125 125 		gray49
+125 125 125 		grey49
+127 127 127 		gray50
+127 127 127 		grey50
+130 130 130 		gray51
+130 130 130 		grey51
+133 133 133 		gray52
+133 133 133 		grey52
+135 135 135 		gray53
+135 135 135 		grey53
+138 138 138 		gray54
+138 138 138 		grey54
+140 140 140 		gray55
+140 140 140 		grey55
+143 143 143 		gray56
+143 143 143 		grey56
+145 145 145 		gray57
+145 145 145 		grey57
+148 148 148 		gray58
+148 148 148 		grey58
+150 150 150 		gray59
+150 150 150 		grey59
+153 153 153 		gray60
+153 153 153 		grey60
+156 156 156 		gray61
+156 156 156 		grey61
+158 158 158 		gray62
+158 158 158 		grey62
+161 161 161 		gray63
+161 161 161 		grey63
+163 163 163 		gray64
+163 163 163 		grey64
+166 166 166 		gray65
+166 166 166 		grey65
+168 168 168 		gray66
+168 168 168 		grey66
+171 171 171 		gray67
+171 171 171 		grey67
+173 173 173 		gray68
+173 173 173 		grey68
+176 176 176 		gray69
+176 176 176 		grey69
+179 179 179 		gray70
+179 179 179 		grey70
+181 181 181 		gray71
+181 181 181 		grey71
+184 184 184 		gray72
+184 184 184 		grey72
+186 186 186 		gray73
+186 186 186 		grey73
+189 189 189 		gray74
+189 189 189 		grey74
+191 191 191 		gray75
+191 191 191 		grey75
+194 194 194 		gray76
+194 194 194 		grey76
+196 196 196 		gray77
+196 196 196 		grey77
+199 199 199 		gray78
+199 199 199 		grey78
+201 201 201 		gray79
+201 201 201 		grey79
+204 204 204 		gray80
+204 204 204 		grey80
+207 207 207 		gray81
+207 207 207 		grey81
+209 209 209 		gray82
+209 209 209 		grey82
+212 212 212 		gray83
+212 212 212 		grey83
+214 214 214 		gray84
+214 214 214 		grey84
+217 217 217 		gray85
+217 217 217 		grey85
+219 219 219 		gray86
+219 219 219 		grey86
+222 222 222 		gray87
+222 222 222 		grey87
+224 224 224 		gray88
+224 224 224 		grey88
+227 227 227 		gray89
+227 227 227 		grey89
+229 229 229 		gray90
+229 229 229 		grey90
+232 232 232 		gray91
+232 232 232 		grey91
+235 235 235 		gray92
+235 235 235 		grey92
+237 237 237 		gray93
+237 237 237 		grey93
+240 240 240 		gray94
+240 240 240 		grey94
+242 242 242 		gray95
+242 242 242 		grey95
+245 245 245 		gray96
+245 245 245 		grey96
+247 247 247 		gray97
+247 247 247 		grey97
+250 250 250 		gray98
+250 250 250 		grey98
+252 252 252 		gray99
+252 252 252 		grey99
+255 255 255 		gray100
+255 255 255 		grey100
+169 169 169		dark grey
+169 169 169		DarkGrey
+169 169 169		dark gray
+169 169 169		DarkGray
+0     0 139		dark blue
+0     0 139		DarkBlue
+0   139 139		dark cyan
+0   139 139		DarkCyan
+139   0 139		dark magenta
+139   0 139		DarkMagenta
+139   0   0		dark red
+139   0   0		DarkRed
+144 238 144		light green
+144 238 144		LightGreen

Added: packages/libchart-perl/branches/upstream/current/t/Humidity.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/Humidity.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/Humidity.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,239 @@
+#!/usr/bin/perl -w
+#
+# Testprogram for lines
+#
+#======================================================================
+
+use strict;
+use Chart::Lines;
+
+print "1..1\n";
+
+my @messwerte = ();
+my @zeit = ();
+
+my $graphic;
+my $gif_name;
+my $titel_name;
+my $einheit;
+my $min_y;
+my $max_y;
+
+
+#------------------------------------------------------------------------------------
+# Start
+#------------------------------------------------------------------------------------
+
+$gif_name = "Humidity";
+$titel_name = "Examples of Humidity";
+$einheit = "% rH";
+ at zeit = (
+         '12:00','12:01','12:02','12:03','12:04','12:05','12:06','12:07','12:08','12:09',    #1
+         '12:10','12:11','12:12','12:13','12:14','12:15','12:16','12:17','12:18','12:19',    #2
+	 '12:20','12:21','12:22','12:23','12:24','12:25','12:26','12:27','12:28','12:29',    #3
+	 '12:30','12:31','12:32','12:33','12:34','12:35','12:36','12:37','12:38','12:39',    #4
+	 '12:40','12:41','12:42','12:43','12:44','12:45','12:46','12:47','12:48','12:49',    #5
+	 '12:50','12:51','12:52','12:53','12:54','12:55','12:56','12:57','12:58','12:59',    #6
+	 '13:00','13:01','13:02','13:03','13:04','13:05','13:06','13:07','13:08','13:09',    #7
+	 '13:10','13:11','13:12','13:13','13:14','13:15','13:16','13:17','13:18','13:19',    #8
+	 '13:20','13:21','13:22','13:23','13:24','13:25','13:26','13:27','13:28','13:29',    #9
+	 '13:30','13:31','13:32','13:33','13:34','13:35','13:36','13:37','13:38','13:39',    #10
+	 '13:40','13:41','13:42','13:43','13:44','13:45','13:46','13:47','13:48','13:49',    #11
+	 '13:50','13:51','13:52','13:53','13:54','13:55','13:56','13:57','13:58','13:59',    #12
+	 '14:00','14:01','14:02','14:03','14:04','14:05','14:06','14:07','14:08','14:09',    #13
+	 '14:10','14:11','14:12','14:13','14:14','14:15','14:16','14:17','14:18','14:19',    #14
+	 '14:20','14:21','14:22','14:23','14:24','14:25','14:26','14:27','14:28','14:29',    #15
+	 '14:30','14:31','14:32','14:33','14:34','14:35','14:36','14:37','14:38','14:39',    #16
+	 '14:40','14:41','14:42','14:43','14:44','14:45','14:46','14:47','14:48','14:49',    #17
+	 '14:50','14:51','14:52','14:53','14:54','14:55','14:56','14:57','14:58','14:59',    #18
+	 '15:00','15:01','15:02','15:03','15:04','15:05','15:06','15:07','15:08','15:09',    #19
+	 '15:10','15:11','15:12','15:13','15:14','15:15','15:16','15:17','15:18','15:19',    #20
+	 '15:20','15:21','15:22','15:23','15:24','15:25','15:26','15:27','15:28','15:29',    #21
+	 '15:30','15:31','15:32','15:33','15:34','15:35','15:36','15:37','15:38','15:39',    #22
+	 '15:40','15:41','15:42','15:43','15:44','15:45','15:46','15:47','15:48','15:49',    #23
+	 '15:50','15:51','15:52','15:53','15:54','15:55','15:56','15:57','15:58','15:59',    #24
+	 '16:00','16:01','16:02','16:03','16:04','16:05','16:06','16:07','16:08','16:09',    #25
+	 '16:10','16:11','16:12','16:13','16:14','16:15','16:16','16:17','16:18','16:19',    #26
+	 '16:20','16:21','16:22','16:23','16:24','16:25','16:26','16:27','16:28','16:29',    #27
+	 '16:30','16:31','16:32','16:33','16:34','16:35','16:36','16:37','16:38','16:39',    #28
+	 '16:40','16:41','16:42','16:43','16:44','16:45','16:46','16:47','16:48','16:49',    #29
+	 '16:50','16:51','16:52','16:53','16:54','16:55','16:56','16:57','16:58','16:59',    #30
+	 '17:00','17:01','17:02','17:03','17:04','17:05','17:06','17:07','17:08','17:09',    #31
+	 '17:10','17:11','17:12','17:13','17:14','17:15','17:16','17:17','17:18','17:19',    #32
+	 '17:20','17:21','17:22','17:23','17:24','17:25','17:26','17:27','17:28','17:29',    #33
+	 '17:30','17:31','17:32','17:33','17:34','17:35','17:36','17:37','17:38','17:39',    #34
+	 '17:40','17:41','17:42','17:43','17:44','17:45','17:46','17:47','17:48','17:49',    #35
+	 '17:50','17:51','17:52','17:53','17:54','17:55','17:56','17:57','17:58','17:59',    #36
+	 '18:00','18:01','18:02','18:03','18:04','18:05','18:06','18:07','18:08','18:09',    #37
+	 '18:10','18:11','18:12','18:13','18:14','18:15','18:16','18:17','18:18','18:19',    #38
+	 '18:20','18:21','18:22','18:23','18:24','18:25','18:26','18:27','18:28','18:29',    #39
+	 '18:30','18:31','18:32','18:33','18:34','18:35','18:36','18:37','18:38','18:39',    #40
+	 '18:41','18:42','18:43','18:44','18:45','18:46','18:47','18:48','18:49','18:50',    #41
+	 '18:51','18:52','18:53','18:54','18:55','18:56','18:57','18:58','18:59','19:00',    #42
+	 '19:01','19:02','19:03','19:04','19:05','19:06','19:07','19:08','19:09','19:10',    #43
+	 '19:11','19:12','19:13','19:14','19:15','19:16','19:17','19:18','19:19','19:20',    #44
+	 '19:21','19:22','19:23','19:24','19:25','19:26','19:27','19:28','19:29','19:30',    #45
+	 '19:31','19:32','19:33','19:34','19:35','19:36','19:37','19:38','19:39','19:40',    #46
+	 '19:41','19:42','19:43','19:44','19:45','19:46','19:47','19:48','19:49','19:50',    #47
+	 '19:51','19:52','19:53','19:54','19:55','19:56','19:57','19:58','19:59','20:00',    #48
+	 '20:01','20:02','20:03','20:04','20:05','20:06','20:07','20:08','20:09','20:10',    #49
+	 '20:11','20:12','20:13','20:14','20:15','20:16','20:17','20:18','20:19','20:20',    #50
+	 '20:21','20:22','20:23','20:24','20:25','20:26','20:27','20:28','20:29','20:30',    #51
+	 '20:31','20:32','20:33','20:34','20:35','20:36','20:37','20:38','20:39','20:40',    #52
+	 '20:41','20:42','20:43','20:44','20:45','20:46','20:47','20:48','20:49','20:50',    #53
+	 '20:51','20:52','20:53','20:54','20:55','20:56','20:57','20:58','20:59','21:00',    #54
+	 '21:01','21:02','21:03','21:04','21:05','21:06','21:07','21:08','21:09','21:10',    #55
+	 '21:11','21:12','21:13','21:14','21:15','21:16','21:17','21:18','21:19','21:20',    #56
+	 '21:21','21:22','21:23','21:24','21:25','21:26','21:27','21:28','21:29','21:30',    #57
+	 '21:31','21:32','21:33','21:34','21:35','21:36','21:37','21:38','21:39','21:40',    #58
+	 '21:41','21:42','21:43','21:44','21:45','21:46','21:47','21:48','21:49','21:50',    #59
+	 '21:51','21:52','21:53','21:54','21:55','21:56','21:57','21:58','21:59','22:00',    #60
+	 '22:01','22:02','22:03','22:04','22:05','22:06','22:07','22:08','22:09','22:10',    #61
+	 '22:11','22:12','22:13','22:14','22:15','22:16','22:17','22:18','22:19','22:20',    #62
+	 '22:21','22:22','22:23','22:24','22:25','22:26','22:27','22:28','22:29','22:30',    #63
+	 '22:31','22:32','22:33','22:34','22:35','22:36','22:37','22:38','22:39','22:40',    #64
+	 '22:41','22:42','22:43','22:44','22:45','22:46','22:47','22:48','22:49','22:50',    #65
+	 '22:51','22:52','22:53','22:54','22:55','22:56','22:57','22:58','22:59','23:00',    #66
+	 '23:01','23:02','23:03','23:04','23:05','23:06','23:07','23:08','23:09','23:10',    #67
+	 '23:11','23:12','23:13','23:14','23:15','23:16','23:17','23:18','23:19','23:20',    #68
+	 '23:21','23:22','23:23','23:24','23:25','23:26','23:27','23:28','23:29','23:30',    #69
+	 '23:31','23:32','23:33','23:34','23:35','23:36','23:37','23:38','23:39','23:40',    #70
+	 '23:41','23:42','23:43','23:44','23:45','23:46','23:47','23:48','23:49','23:50',    #71
+	 '23:51','23:52','23:53','23:54','23:55','23:56','23:57','23:58','23:59');           #72
+
+ at messwerte = (
+         36.3, 36.2, 36.2, 36.3, 36.4, 36.4, 36.3, 36.4, 36.4, 36.3, #1
+	 36.1, 36.3, 36.2, 36.3, 36.4, 36.3, 36.3, 36.1, 36.2, 36.2, #2
+	 36.3, 36.2, 36.2, 36.2, 36.1, 36.3, 36.3, 36.2, 36.2, 36.2, #3
+	 36.2, 36.1, 36.5, 36.4, 36.3, 36.2, 36.2, 36.3, 36.4, 36.4, #4
+	 36.3, 36.3, 36.3, 36.4, 36.5, 36.4, 36.4, 36.5, 36.5, 36.5, #5
+	 36.3, 36.4, 36.3, 36.2, 36.2, 36.3, 36.2, 36.3, 36.4, 36.2, #6
+	 36.2, 36.4, 36.3, 36.2, 36.4, 36.4, 36.4, 36.2, 36.4, 36.3, #7
+	 36.3, 36.4, 36.4, 36.5, 36.3, 36.5, 36.5, 36.4, 36.5, 36.4, #8
+	 36.5, 36.3, 36.4, 36.4, 36.4, 36.4, 36.5, 36.5, 36.3, 36.3, #9
+	 36.3, 36.4, 36.4, 36.3, 36.3, 36.2, 36.3, 36.3, 36.2, 36.2, #10
+	 36.2, 36.2, 36.2, 36.2, 36.3, 36.3, 36.2, 36.2, 36.2, 36.3, #11
+	 36.1, 36.2, 36.2, 36.2, 36.2, 36.4, 36.2, 36.1, 36.2, 36.2, #12
+	 36.3, 36.2, 36.3, 36.2, 36.1, 36.2, 36.2, 36.2, 36.2, 36.2, #13
+	 36.2, 36.1, 36.2, 36.2, 36.2, 36.2, 36.2, 36.3, 36.2, 36.2, #14
+	 36.3, 36.2, 36.3, 36.2, 36.3, 36.1, 36.2, 36.2, 36.2, 36.2, #15
+	 36.2, 36.2, 36.2, 36.2, 36.2, 36.3, 36.2, 36.2, 36.2, 36.2, #16
+	 36.2, 36.2, 36.3, 36.2, 36.3, 36.2, 36.3, 36.2, 36.2, 36.2, #17
+	 36.2, 36.2, 36.2, 36.2, 36.1, 36.2, 36.2, 36.2, 36.2, 36.2, #18
+	 36.3, 36.1, 36.2, 36.2, 36.3, 36.2, 36.3, 36.3, 36.2, 36.2, #19
+	 36.2, 36.3, 36.2, 36.3, 36.2, 36.2, 36.2, 36.3, 36.2, 36.2, #20
+	 36.2, 36.2, 36.2, 36.1, 36.2, 36.2, 36.2, 36.2, 36.2, 36.2, #21
+	 36.1, 36.2, 36.2, 36.2, 36.3, 36.2, 36.2, 36.1, 36.2, 36.2, #22
+	 36.2, 36.2, 36.2, 36.2, 36.1, 36.3, 36.2, 36.3, 36.2, 36.3, #23
+	 36.2, 36.2, 36.3, 36.2, 36.2, 36.3, 36.2, 36.2, 36.2, 36.2, #24
+	 36.2, 36.2, 36.2, 36.2, 36.1, 36.2, 36.36,36.36,36.2, 36.1, #25
+	 36.2, 36.2, 36.2, 36.3, 36.2, 36.3, 36.2, 36.3, 36.1, 36.1, #26
+	 36.2, 36.2, 36.2, 36.1, 36.2, 36.2, 36.1, 36.1, 36.2, 36.2, #27
+	 36.2, 36.2, 36.2, 36.2, 36.1, 36.1, 36.0, 36.2, 36.2, 36.2, #28
+	 36.2, 36.2, 36.2, 36.1, 36.1, 36.1, 36.1, 36.1, 36.2, 36.2, #29
+	 36.1, 36.2, 36.1, 36.1, 36.2, 36.2, 36.2, 36.2, 36.2, 36.2, #30
+	 36.2, 36.2, 36.3, 36.2, 36.1, 36.2, 36.2, 36.2, 36.2, 36.2, #31
+	 36.2, 36.3, 36.3, 36.2, 36.1, 36.2, 36.2, 36.2, 36.1, 36.3, #32
+	 36.3, 36.2, 36.3, 36.2, 36.2, 36.4, 36.3, 36.3, 36.2, 36.1, #33
+	 36.1, 36.1, 36.1, 36.1, 36.1, 36.0, 36.1, 36.2, 36.1, 36.1, #34
+	 36.1, 35.9, 36.2, 36.3, 36.5, 36.5, 36.5, 36.4, 36.1, 36.3, #35
+	 36.4, 36.1, 36.2, 36.4, 36.0, 36.2, 36.1, 36.0, 36.1, 36.1, #36
+	 36.2, 36.3, 36.4, 36.4, 36.5, 36.5, 36.5, 36.3, 36.0, 36.2, #37
+	 36.4, 36.4, 36.3, 36.4, 36.2, 36.3, 36.2, 36.3, 36.4, 36.2, #38
+	 36.4, 36.5, 36.4, 36.2, 36.2, 36.3, 36.1, 36.1, 36.3, 36.2, #39
+	 36.3, 36.3, 36.2, 36.2, 36.3, 36.4, 36.3, 36.3, 36.3, 36.4, #40
+	 36.3, 36.2, 36.3, 36.3, 36.3, 36.4, 36.3, 36.2, 36.1, 36.2, #41
+	 36.2, 36.1, 36.2, 36.1, 36.1, 36.2, 36.2, 36.1, 36.0, 36.1, #42
+	 36.1, 36.2, 36.2, 36.1, 36.2, 36.1, 36.1, 36.1, 36.1, 36.2, #43
+	 36.1, 36.1, 36.2, 36.0, 36.0, 36.1, 36.1, 35.9, 35.9, 35.8, #44
+	 36.1, 36.2, 36.2, 36.2, 36.1, 36.1, 35.9, 35.9, 35.9, 36.1, #45
+	 36.1, 35.9, 36.1, 36.2, 36.1, 36.1, 36.1, 36.1, 36.0, 36.1, #46
+	 36.2, 36.2, 36.1, 36.2, 36.0, 36.0, 35.9, 36.0, 36.0, 36.1, #47
+	 36.2, 36.0, 36.0, 36.0, 36.1, 36.0, 36.0, 35.9, 36.0, 35.8, #48
+	 35.9, 35.9, 35.9, 35.9, 35.8, 35.9, 35.7, 35.9, 35.9, 35.8, #49
+	 35.9, 35.9, 35.7, 35.8, 36.0, 36.1, 36.2, 36.2, 36.0, 36.1, #50
+	 36.2, 36.1, 36.2, 36.2, 36.1, 36.1, 36.0, 36.0, 35.9, 36.0, #51
+	 36.2, 36.1, 36.1, 36.2, 36.2, 36.1, 36.1, 36.3, 36.2, 36.2, #52
+	 36.1, 36.1, 36.1, 36.1, 36.1, 36.3, 36.4, 36.3, 36.2, 36.3, #53
+	 36.2, 36.2, 36.2, 36.3, 36.3, 36.3, 36.2, 36.3, 36.3, 36.4, #54
+	 36.3, 36.3, 36.4, 36.3, 36.3, 36.4, 36.4, 36.4, 36.4, 36.4, #55
+	 36.3, 36.3, 36.4, 36.3, 36.3, 36.2, 36.3, 36.1, 36.1, 36.1, #56
+	 36.2, 36.2, 36.2, 36.1, 36.1, 36.2, 36.2, 36.1, 36.2, 36.2, #57
+	 36.2, 36.2, 36.2, 36.1, 36.1, 36.2, 36.1, 36.2, 36.2, 36.2, #58
+	 36.1, 36.2, 36.2, 36.1, 36.2, 36.2, 36.2, 36.2, 36.2, 36.2, #59
+	 36.1, 36.1, 36.2, 36.2, 36.2, 36.2, 36.2, 36.1, 36.2, 36.2, #60
+	 36.2, 36.2, 36.1, 36.2, 36.1, 36.1, 36.2, 36.2, 36.2, 36.2, #61
+	 36.3, 36.1, 36.2, 36.2, 36.2, 36.3, 36.2, 36.2, 36.1, 36.2, #62
+	 36.3, 36.2, 36.3, 36.3, 36.3, 36.3, 36.3, 36.5, 36.3, 36.4, #63
+	 36.3, 36.3, 36.3, 36.2, 36.3, 36.3, 36.3, 36.3, 36.3, 36.2, #64
+	 36.2, 36.2, 36.2, 36.2, 36.2, 36.2, 36.2, 36.1, 36.1, 36.2, #65
+	 36.2, 36.2, 36.2, 36.2, 36.1, 36.1, 36.2, 36.1, 36.1, 36.1, #66
+	 36.2, 36.1, 36.2, 36.2, 36.2, 36.5, 36.3, 36.2, 36.3, 36.4, #67
+	 36.4, 36.4, 36.4, 36.4, 36.3, 36.3, 36.4, 36.4, 36.4, 36.4, #68
+	 36.4, 36.4, 36.3, 36.4, 36.4, 36.4, 36.3, 36.4, 36.3, 36.2, #69
+	 36.2, 36.2, 36.3, 36.1, 36.2, 36.1, 36.1, 36.1, 36.1, 36.2, #70
+	 36.1, 36.2, 36.1, 36.1, 36.1, 36.1, 36.1, 36.1, 36.2, 36.2, #71
+	 36.2, 36.1, 36.2, 36.2, 36.2, 36.2, 36.2, 36.2, 36.2);      #72
+	 
+#------------------------------------------------------------------------------------
+# Zeitarray aufbauen , Minimal- und Maximalwert bestimmen und X - Achse berechnen
+#------------------------------------------------------------------------------------
+
+#------------------------------------------------------------------------------------
+# Graphic_objekt erstellen
+#------------------------------------------------------------------------------------
+
+        $min_y = $max_y = $messwerte[0];
+	foreach (@messwerte ) {
+	   if ( $_ < $min_y ) { $min_y = $_;}
+	   if ( $_ > $max_y ) { $max_y = $_; }
+	}
+	$min_y = int($min_y)-1;
+	$max_y = int($max_y)+1;
+	
+	$graphic = Chart::Lines -> new (750,400);
+	$graphic -> set ('brush_size' => 2 );
+		
+	$graphic -> add_dataset ( @zeit );
+	
+	$graphic -> add_dataset ( @messwerte );
+
+#------------------------------------------------------------------------------------
+# Diagramm Y-Achse berechnen
+#------------------------------------------------------------------------------------
+
+	
+	$graphic -> set ('min_val' => $min_y );
+	$graphic -> set ('max_val' => $max_y);
+	#$graphic -> set ('y_ticks' => 11 );
+	$graphic -> set ('x_ticks' => 'vertical' );
+	$graphic -> set ('skip_x_ticks' => 30);
+
+	$graphic -> set ('grey_background' => 'false' );		
+	$graphic -> set ('graph_border' => 18 );
+	$graphic -> set ('title' => $titel_name );
+	$graphic -> set ('sub_title' => "over Time");
+	$graphic -> set ('y_grid_lines' => 'true' );
+	$graphic -> set ('x_grid_lines' => 'true' );
+	$graphic -> set ('x_ticks'	=> 'vertical' );
+	$graphic -> set ('colors' => {'y_grid_lines' => [127,127,0], 'x_grid_lines' => [127,127,0], 'dataset0' => [0,0,200]});
+	$graphic -> set ('legend' => 'none' );
+	$graphic -> set ('x_label' => 'Time (UTC)' );
+	$graphic -> set ('y_label' => $einheit );
+
+
+	if ( $graphic -> can ('gif') ){
+		my $wettgif = "samples/".$gif_name.".gif";
+		$graphic -> gif ($wettgif);
+	}
+	elsif ( $graphic -> can ('png') ) {
+		my $wettgif = "samples/".$gif_name.".png";
+		$graphic -> png ($wettgif);
+	}
+	
+
+print "ok 1\n";
+
+exit (0);
+
+ 

Added: packages/libchart-perl/branches/upstream/current/t/Math_1_over_x.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/Math_1_over_x.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/Math_1_over_x.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,93 @@
+#!/usr/bin/perl -w
+#
+# Testprogram for lines
+# Math expressions 1/x
+#
+#======================================================================
+
+use strict;
+use Chart::Lines;
+
+print "1..1\n";
+
+my @x_values = ();     # x axis
+my @y1_values = ();    # 1/x for x<0
+my @y2_values = ();    # 1/x for x>0
+
+my $graphic;
+my $min_x = -5;
+my $max_x = 5;
+my $min_y = -10;
+my $max_y = 10;
+
+
+my $x;
+my $y;
+
+#------------------------------------------------------------------------------------
+# Start
+#------------------------------------------------------------------------------------
+
+$x = $min_x;
+for ( my $x_idx = 0; $x < $max_x; $x_idx++ ) {
+   $x = $min_x + $x_idx*0.1;
+   $x_values[$x_idx] = $x;
+}
+
+for ( my $x_idx = 0; $x_idx <= $#x_values; $x_idx++ ) {
+   if ( $x_values[$x_idx] < 0 ) {
+      $y1_values[$x_idx] = 1/$x_values[$x_idx];
+      $y2_values[$x_idx] = $max_y + 10;
+   } elsif ( $x_values[$x_idx] > 0 ) {
+      $y1_values[$x_idx] = $min_y - 10;
+      $y2_values[$x_idx] = 1/$x_values[$x_idx];
+   } else {
+      $y2_values[$x_idx] = $max_y + 10;
+      $y1_values[$x_idx] = $min_y - 10;
+   }
+}   
+   
+#------------------------------------------------------------------------------------
+# Make it
+#------------------------------------------------------------------------------------
+
+	$graphic = Chart::Lines -> new (750,600);
+	$graphic -> set ('brush_size' => 2 );
+		
+	$graphic -> add_dataset ( @x_values );
+	
+	$graphic -> add_dataset ( @y1_values );
+	$graphic -> add_dataset ( @y2_values );
+
+	$graphic -> set ('min_val' => $min_y );
+	$graphic -> set ('max_val' => $max_y);
+	#$graphic -> set ('y_ticks' => 11 );
+	$graphic -> set ('x_ticks' => 'vertical' );
+	$graphic -> set ('skip_x_ticks' => 10);
+
+	$graphic -> set ('grey_background' => 'true' );		
+	$graphic -> set ('graph_border' => 18 );
+	$graphic -> set ('title' => "1/x" );
+	$graphic -> set ('y_grid_lines' => 'true' );
+	$graphic -> set ('x_grid_lines' => 'true' );
+	$graphic -> set ('x_ticks'	=> 'vertical' );
+	$graphic -> set ('legend' => 'none' );
+	$graphic -> set ('x_label' => 'x' );
+	$graphic -> set ('y_label' => 'f = 1/x' );
+
+
+	if ( $graphic -> can ('gif') ){
+		my $picture_file = "samples/Math_1_over_x.gif";
+		$graphic -> gif ($picture_file);
+	}
+	if ( $graphic -> can ('png') ) {
+		my $picture_file = "samples/Math_1_over_x.png";
+		$graphic -> png ($picture_file);
+	}
+	
+
+print "ok 1\n";
+
+exit (0);
+
+ 

Added: packages/libchart-perl/branches/upstream/current/t/bars.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/bars.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/bars.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,49 @@
+#!/usr/bin/perl -w
+
+use Chart::Bars;
+
+print "1..1\n";
+
+$g = Chart::Bars->new(600,600);
+$g->add_dataset ('foo', 'bar', 'junk', 'ding', 'bat');
+$g->add_dataset (30000, 40000, 80000, 50000, 90000);
+$g->add_dataset (80000, 60000, 30000, 30000, 40000);
+$g->add_dataset (50000, 70000, 20200, 80000.8, 40000);
+
+%hash = ('transparent' => 'true',
+	 'precision' => 1,
+	 'title' => 'Bars\nChartmodul',
+	 'y_grid_lines' => 'true',
+	 'graph_border' => '4',
+	 'min_val' => '0',
+	 'text_space' => '2',
+	 'sub_title' => 'Untertitel',
+	 'x_label' => 'X-Achse',  
+	 'y_label' => 'Y-Achse',  
+	 'y_label2' => 'Y-Achse2',
+	 'legend' => 'none',
+	 'tick_len' => '3',
+	 'x_ticks' => 'vertical',
+	 'include_zero' => 'true',
+	 'pt_size' => '7',
+	 'skip_x_ticks' => '1',
+	 'grid_lines' =>'true',
+	 'colors' => {
+	 	      'text' => [100,0,200],
+	 	      'y_label' => [2,255,2],
+	 	      'y_label2' => [2,255,2],
+		      'y_grid_lines' => 'black',
+	 	      'x_grid_lines' => 'black',
+	 	      'dataset0' => [255,20,147],
+	 	   	 	      
+	 	      },
+	  'y_ticks' => '20' ,
+	 
+	 );
+$g->set (%hash);
+
+$g->png ("samples/bars.png");
+
+print "ok 1\n";
+
+exit (0);

Added: packages/libchart-perl/branches/upstream/current/t/bars_10.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/bars_10.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/bars_10.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,48 @@
+#!/usr/bin/perl -w
+
+use Chart::Bars;
+
+print "1..1\n";
+
+$g = Chart::Bars->new(600,500);
+
+$g->add_dataset ('Berlin', 'Paris', 'Rome', 'London', 'Munich');
+
+$g->add_dataset (0, 0, 0, 0, 0);
+$g->add_dataset (0, 0, 0, 0, 0);
+$g->add_dataset (0, 0, 0, 0, 0);
+$g->add_dataset (0, 0, 0, 0, 0);
+$g->add_dataset (0, 0, 0, 0, 0);
+$g->add_dataset (0, 0, 0, 0, 0);
+$g->add_dataset (0, 0, 0, 0, 0);
+
+
+
+
+%hash = (
+ 	 'title' => 'Only a demo chart with zero data',
+         'legend' => 'bottom',
+         'grid_lines' =>'true',
+      	  'include_zero' => 'true',
+      	  'max_val' => '20',
+          'min_val' => '-20',
+	  'colors' => {'title' => 'red',
+	 	      'x_label' => 'blue',
+                      'y_label' => 'blue',
+		      'background' => 'grey',
+		      'text'    => 'blue',
+	 	      },
+          
+	 );
+
+$g->set (%hash);
+
+$g->png ("samples/bars_10.png");
+
+print "ok 1\n";
+
+exit (0);
+
+
+
+

Added: packages/libchart-perl/branches/upstream/current/t/bars_2.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/bars_2.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/bars_2.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,52 @@
+#!/usr/bin/perl -w
+
+use Chart::Bars;
+
+print "1..1\n";
+
+$g = Chart::Bars->new(600,500);
+
+$g->add_dataset ('Berlin', 'Paris', 'Rome', 'London', 'Munich');
+$g->add_dataset (14, 5, 4, 5, 11);
+$g->add_dataset (12, 4, 6, 7, 12);
+$g->add_dataset (18, 2, 3, 3, 9);
+$g->add_dataset (17, 5, 7, 6, 6);
+$g->add_dataset (15, 3, 4, 5, 11);
+$g->add_dataset (11, 6, 5, 6, 12);
+$g->add_dataset (12, 1, 4, 5, 15);
+$g->add_dataset (10, 4, 6, 8, 10);
+$g->add_dataset (14, 5, 4, 5, 11);
+$g->add_dataset (12, 4, 6, 6, 12);
+$g->add_dataset (18, 2, 3, 3, 9);
+$g->add_dataset (17, 5, 7, 2, 6);
+
+%hash = (
+ 	 'title' => 'Sold Cars in 2001',
+         'x_label' => 'City',
+	 'y_label' => 'Number of Cars',
+         'legend' => 'bottom',
+         'legend_labels'  => ['January' , 'February' , 'March', 'April', 'May', 'June',
+                              'July', 'August' , 'September' , 'October', 'November', 'December'],
+         'grid_lines' =>'true',
+	 'include_zero' => 'true',
+	 'max_val' => '20',
+	 'colors' => {'title' => 'red',
+	 	      'x_label' => 'blue',
+                      'y_label' => 'blue',
+		      'background' => 'grey',
+		      'text'    => 'blue',
+	 	      },
+          
+	 );
+
+$g->set (%hash);
+
+$g->png ("samples/bars_2.png");
+
+print "ok 1\n";
+
+exit (0);
+
+
+
+


Property changes on: packages/libchart-perl/branches/upstream/current/t/bars_2.t
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/t/bars_3.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/bars_3.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/bars_3.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,32 @@
+#!/usr/bin/perl -w
+
+use Chart::Bars;
+print "1..1\n";
+$g = Chart::Bars->new(500,500);
+
+$g->add_dataset ('Reds', 'Blacks', 'Greens', 'Yellows', 'Browns', 'Others');
+$g->add_dataset (-2.4, 3.4, 1.9, 1.2, -1.1, -2.9);
+
+%hash = (
+ 	 'title' => 'Selection 2002:\nWins and Losses in percent',
+         'text_space' => 5,
+         'y_grid_lines' => 'true',
+         'grey_background' => 'false',
+         'legend' => 'none',
+         'min_val' => -4,
+         'max_val' => 4,
+         'min_y_ticks' => 10,
+         'y_axes' => 'both',
+         'spaced_bars' => 'false',
+	 'colors' => {'background' => [230,255,230],
+                      'title' =>'plum',
+                      'dataset0' => 'mauve',
+                     },
+         );
+$g->set (%hash);
+
+$g->png ("samples/bars_3.png");
+
+print "ok 1\n";
+
+exit (0);


Property changes on: packages/libchart-perl/branches/upstream/current/t/bars_3.t
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/t/bars_4.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/bars_4.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/bars_4.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,86 @@
+#!/usr/bin/perl -w
+
+# The Integral of the mathematical function 1/x
+
+use strict;
+use Chart::Bars;
+
+print "1..1\n";
+
+my @x_values = ();     # x axis
+my @y_values = ();
+
+my $graphic;
+my $picture_file = "samples/bars_4.png";
+my $min_y = -5;    # max. y-values
+my $max_y = 5;
+
+my $x;
+my $y;
+
+#------------------------------------------------------------------------------------
+# Start
+#------------------------------------------------------------------------------------
+
+#calculate the values
+for ( my $x = -5; $x <= 5; ($x = $x+0.0005)  ) {
+   push (@x_values , $x);
+   if ($x != 0) {             # division by zero!
+     $y = 1 / $x;
+
+      if ($y > $max_y ){
+      push(@y_values, $max_y)
+     }
+     elsif ( $y < $min_y) {
+      push(@y_values, $min_y)
+     }
+     else {
+       push (@y_values , $y) ;
+     }
+   }
+   else {
+     push (@y_values, 0);
+   }
+}
+
+#------------------------------------------------------------------------------------
+# Make it
+#------------------------------------------------------------------------------------
+
+	$graphic = Chart::Bars-> new (600,600);
+
+	$graphic -> add_dataset ( @x_values );
+	$graphic -> add_dataset ( @y_values );
+
+	$graphic -> set ('min_val' => $min_y );
+	$graphic -> set ('max_val' => $max_y);
+        $graphic -> set ('min_y_ticks' => 20);
+    	$graphic -> set ('skip_x_ticks' => 1000);
+	$graphic -> set ('graph_border' => 18 );
+	$graphic -> set ('title' => "The Integral of 1/x" );
+	$graphic -> set ('grid_lines' => 'true' );
+	$graphic -> set ('x_ticks' => 'vertical' );
+	$graphic -> set ('legend' => 'none' );
+ 	$graphic -> set ('y_label' => 'f = 1 / x' );
+ 	$graphic -> set ('xy_plot' => 'true' );
+        # use a special function to convert the y values to something special
+        $graphic -> set ('f_y_tick' => \&formatter);
+        $graphic -> set ('f_x_tick' => \&formatter);
+
+	$graphic -> png ($picture_file);
+
+	
+
+
+sub formatter {
+   my $y_value = shift;
+   my $label = sprintf "%1.2f",$y_value;
+   if ($label == '-0.00') {
+     $label = '0';
+   }
+   
+   return $label;
+}
+print "ok 1\n";
+
+exit (0);


Property changes on: packages/libchart-perl/branches/upstream/current/t/bars_4.t
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/t/bars_5.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/bars_5.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/bars_5.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,42 @@
+#!/usr/bin/perl -w
+
+use Chart::Bars;
+use strict;
+
+print "1..1\n";
+
+my (@data, @labels, %hash, $g, $hits);
+
+# create an array of labels
+for (1..49) {
+  push (@labels, $_);
+}
+
+# create an array of data
+for (1..49) {
+  srand(time() /$_ );
+  $hits = int(rand(100)+401)  ;
+  push (@data, $hits);
+}
+
+
+$g = Chart::Bars->new(700,300);
+$g->add_dataset(@labels);
+$g->add_dataset(@data);
+
+%hash =(
+          'legend' => 'none',
+          'precision' => 0,
+          'x_ticks' => 'vertical',
+          'title' => 'Lottozahlenverteilung',
+          'y_label' => 'Häufigkeit',
+          'y_grid_lines' => 'true',
+          
+          );
+
+$g->set ( %hash);
+$g->png ("samples/bars_5.png");
+print "ok 1\n";
+
+exit (0);
+


Property changes on: packages/libchart-perl/branches/upstream/current/t/bars_5.t
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/t/bars_6.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/bars_6.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/bars_6.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,48 @@
+#!/usr/bin/perl -w
+
+use Chart::Bars;
+use strict;
+
+print "1..1\n";
+
+my $g = Chart::Bars->new(580,300);
+
+my @data = (200202, 200203,200204,200205,200206,200207,200208,200209,200210,200211,200212,200301);
+my @data1 =(  6626,   7662,  7580,  7671,  8064,  8664,  6343,  5518,  6257,  5391,  5401,  6002);
+ 
+
+$g->add_dataset(@data);
+$g->add_dataset(@data1);
+ 
+my @legend_keys  = ( "Actual ","Goal" );
+ 
+$g->set(
+           colors              => {
+                                       dataset0   => [25,220,147],
+                                   },
+            graph_border       => 0,
+            grey_background    => 'false',
+            grid_lines         => 'true',
+         #   integer_ticks_only => 'true',
+            legend             => 'none',
+         #   min_val            => 0,
+	 #   include_zero       =>  'true',
+            png_border         => 4,
+            precision          => 1,
+            skip_int_ticks     => 1000,
+            spaced_bars        => 'true',
+            text_space         => 3,
+            title              => "Tickets",
+            title_font         => GD::Font->Giant,
+            transparent        => 'false',
+            x_ticks            => 'vertical',
+            y_axes             => 'both',
+            y_label            => '# Tickets',
+        #    max_val            => 9000,
+            );
+
+$g->png ("samples/bars_6.png");
+print "ok 1\n";
+
+exit (0);
+

Added: packages/libchart-perl/branches/upstream/current/t/bars_7.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/bars_7.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/bars_7.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,53 @@
+#!/usr/bin/perl -w
+
+use Chart::Bars;
+use strict;
+use POSIX;
+
+my $a;
+
+
+$a = 10**(-12);            
+
+print "1..1\n";
+
+my $g = Chart::Bars->new(580,300);
+
+my @data = (200202, 200203,200204,200205,200206,200207,200208,200209,200210,200211,200212,200301);
+my @data1 =(  6626*$a,   -790*$a,  7580*$a,  7671*$a,  8764*$a,  8664*$a,  6343*$a,  5518*$a, 
+           6257*$a,  5391*$a,  5401*$a,  6002*$a);
+ 
+#my @data1 =(6626,-790,7580,7671,8764,8664,6343,5518,6257,5391,5401,6002);
+
+
+$g->add_dataset(@data);
+$g->add_dataset(@data1);
+ 
+$g->set(
+           colors              => {
+                                       dataset0   => [25,220,147],
+                                   },
+            graph_border       => 0,
+            grey_background    => 'false',
+            grid_lines         => 'true',
+            include_zero       => 'true',
+            legend             => 'none',
+            png_border         => 4,
+            precision          => 9,
+	    spaced_bars        => 'true',
+            text_space         => 3,
+            title              => "Tickets",
+            title_font         => GD::Font->Giant,
+            transparent        => 'false',
+            x_ticks            => 'vertical',
+            y_axes             => 'both',
+            y_label            => '# Tickets',
+            x_label            => 'Date',
+            );
+
+
+$g->png ("samples/bars_7.png");  
+print "ok 1\n";
+
+exit (0);
+

Added: packages/libchart-perl/branches/upstream/current/t/bars_8.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/bars_8.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/bars_8.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,54 @@
+#!/usr/bin/perl -w
+
+use Chart::Bars;
+use strict;
+use POSIX;
+
+my $a;
+$a = 10**(-30);
+
+print "1..1\n";
+
+my $g = Chart::Bars->new(600,400);
+
+my @data = (200202, 200203,200204,200205,200206,200207,200208,200209,200210,200211,200212,200301);
+my @data1 =(  6626*$a,   -790*$a,  7580*$a,  7671*$a,  8764*$a,  8664*$a,  6343*$a,  5518*$a, 
+           6257*$a,  5391*$a,  5401*$a,  6002*$a);
+ 
+#my @data1 =(6626,-790,7580,7671,8764,8664,6343,5518,6257,5391,5401,6002);
+
+
+$g->add_dataset(@data);
+$g->add_dataset(@data1);
+ 
+my @legend_keys  = ( "Actual ","Goal" );
+ 
+$g->set(
+           colors              => {
+                                       dataset0   => [25,220,147],
+                                   },
+            graph_border       => 0,
+            grey_background    => 'false',
+            grid_lines         => 'true',
+            include_zero       => 'true',
+          #  integer_ticks_only => 'true',
+            legend             => 'none',
+	    png_border         => 4,
+        #    precision          => 27,
+	#    skip_int_ticks     => 1.0e-27,
+	    text_space         => 3,
+            title              => "Tickets",
+            title_font         => GD::Font->Giant,
+            transparent        => 'false',
+            x_ticks            => 'vertical',
+            y_axes             => 'both',
+            y_label            => '# Tickets',
+            x_label            => 'Date',
+            );
+
+
+$g->png ("samples/bars_8.png");
+print "ok 1\n";
+
+exit (0);
+

Added: packages/libchart-perl/branches/upstream/current/t/bars_9.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/bars_9.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/bars_9.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,49 @@
+#!/usr/bin/perl -w
+
+use Chart::Bars;
+use strict;
+use POSIX;
+
+print "1..1\n";
+
+my $g = Chart::Bars->new(600,400);
+
+my @data = (200202, 200203,200204,200205,200206,200207,200208,200209,200210,200211,200212,200301);
+ 
+my @data1 =(6626,7090,7580,7671,8764,8664,6343,5518,6257,5391,5401,6002);
+
+
+$g->add_dataset(@data);
+$g->add_dataset(@data1);
+ 
+my @legend_keys  = ( "Actual ","Goal" );
+ 
+$g->set(
+           colors              => {
+                                       dataset0   => [25,220,147],
+                                   },
+            graph_border       => 0,
+            grey_background    => 'false',
+            grid_lines         => 'true',
+            include_zero       => 'true',
+           # integer_ticks_only => 'true',
+            legend             => 'none',
+	    png_border         => 4,
+            precision          => 1,
+	    skip_int_ticks     => 1000,
+	    text_space         => 3,
+            title              => "Tickets",
+            title_font         => GD::Font->Giant,
+            transparent        => 'false',
+            x_ticks            => 'vertical',
+            y_axes             => 'both',
+            y_label            => '# Tickets',
+            x_label            => 'Date',
+            );
+
+
+$g->png ("samples/bars_9.png");
+print "ok 1\n";
+
+exit (0);
+

Added: packages/libchart-perl/branches/upstream/current/t/composite.png
===================================================================
(Binary files differ)


Property changes on: packages/libchart-perl/branches/upstream/current/t/composite.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: packages/libchart-perl/branches/upstream/current/t/composite.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/composite.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/composite.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,31 @@
+#!/usr/bin/perl -w
+
+use Chart::Composite;
+
+print "1..1\n";
+
+$g = Chart::Composite->new();
+
+$g->add_dataset ('foo', 'bar', 'junk','whee');
+$g->add_dataset (3, 4, 9,10);
+$g->add_dataset (8, 6, 1,11);
+$g->add_dataset (5, 7, 2,12);
+$g->add_dataset (2, 5, 7,2);
+
+
+$g->set ('legend' => 'left');
+$g->set ('title' => 'Composite Chart',
+	 'composite_info' => [ ['Bars', [1,2]],
+	 		       ['LinesPoints', [3,4]] ]);
+
+$g->set ('y_label' => 'y label 1', 'y_label2' => 'y label 2');
+$g->set ('colors' => {'y_label' => [0,0,255], y_label2 => [0,255,0], 
+	'dataset0' => [0,127,0], 'dataset1' => [0,0,127], 'dataset8', => [0,255,0],
+        'dataset9' => [ 255,0,0 ] });
+$g->set('brush_size2' => 1);
+$g->png("samples/composite.png");
+
+print "ok 1\n";
+
+exit(0);
+

Added: packages/libchart-perl/branches/upstream/current/t/composite_1.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/composite_1.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/composite_1.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,74 @@
+#!/usr/bin/perl -w
+
+
+use Chart::Composite;
+print "1..1\n";
+
+my $obj = Chart::Composite->new(600, 500);   
+my @legend_ary;
+my ($legend, @zeile)    ;
+my @all_aryref;
+open(OUT, ">samples/composite_1.png") or die "cannot write file samples/composite_1.png\n";
+
+my $i =0;
+my $e = 0;
+my $max_val = 0;
+while(<DATA>) {
+        if ($_ =~ /EOF/i){
+            last;
+      }
+      chomp;
+       $i++;
+       ($legend, @zeile) = split/\|/,$_;
+       $obj->add_dataset(@zeile);
+       if ( $i != 1 ){
+              push @legend_ary ,$legend ;    # Erste Zeile ist die x-Achsenbezeichnung und gehört nicht zur Legende
+              for (0..$#zeile) { $zeile[$_] > $max_val  ? $max_val = $zeile [$_]  : 1 ;}  # den Maximalen Wert ermitteln
+       }
+       $all_aryref[$e++] = [@zeile];
+
+}
+
+if ( $max_val =~ /^\d+$/ ) {
+
+      $max_val = 100 * int( 1 + $max_val/100);
+} # den Scalenwert die nächste 100er Stellen setzen
+
+# Der zweite Charttyp überdeckt immer den ersten
+$obj->set(  'legend'        => "top",
+            'legend_labels' => \@legend_ary ,
+            'x_ticks'       => "vertical",
+            'composite_info'=> [ ['StackedBars', [8,7,6,5]  ],
+                                 ['Bars',[1,2,3,4,9] ],
+                                ],
+	    'same_y_axes'  => "true",
+            'y_label'      => "Anzahl",
+            'min_val1'     =>  0 ,
+            'max_val1'     =>  $max_val ,
+            'max_val2'     =>  $max_val,
+            'space_bars'   =>  1 ,
+            'brush_size'   =>  10,
+	    'legend'       => 'bottom',
+	    'title'        => 'Composite Demo Chart',
+	    'legend_example_height'  => 'true',
+	    'legend_example_height0..3' => '50',
+	    'legend_example_height4..9' => '4',
+	     );
+$obj->png(\*OUT);
+close OUT;
+print "ok 1\n";
+exit 0;
+
+__END__
+Datum|01.09.2003|02.09.2003|03.09.2003|04.09.2003
+Anzahl gesamt|322|244|227|223
+Anzahl  Stufe 1 bis 4 gesamt|226|173|159|145
+Anzahl JL|77|46|44|61
+Anzahl  DL|19|25|24|17            
+Anzahl  1. Stufe|28|22|11|27
+Anzahl  2. Stufe|12|11|4|7
+Anzahl  3. Stufe|50|39|55|34
+Anzahl  4. Stufe|136|101|89|77
+Anzahl Formulare|547|352|249|174
+EOF
+

Added: packages/libchart-perl/branches/upstream/current/t/composite_2.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/composite_2.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/composite_2.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,66 @@
+#!/usr/bin/perl -w
+
+use strict;
+use Chart::Composite;
+
+print "1..1\n";
+
+my ($g) = Chart::Composite->new(788,435);
+
+# 0 = X-Achse
+$g->add_dataset('0:00', '1:00', '2:00', '3:00', '4:00', '5:00', '6:00', '7:00',
+                '8:00', '9:00', '10:00', '11:00');
+# 1 = BZ-Werte - linie
+$g->add_dataset( 222,     211,    306,    175,   216,    216,    168,     161,
+                 153,     170,    92,     134);
+# 2 = Basas - stacked bar
+$g->add_dataset( 0.8,     0.8,   0.9,    1.1,   1.8,     2.1,     1.8,    1.4, 
+                 1.0,     1.0,   1.0,    1.0);  
+# 3 = Bolus - stacked bar
+$g->add_dataset( 4.4,     1.8,   6.5,    5.6,   2.4,     4.7,     6.0,    5.4,
+                 8.9,     9.5,   8.7,    9.2);
+# 4 = KHE - stacked bar
+$g->add_dataset( 3.0,     2.8,   2.5,    0.6,   2.4,     4.7,     5.0,    5.4,
+                 1.9,     3.5,   4.7,    3.2);
+		 
+		 	 
+
+$g->set ('composite_info' => [ [ 'StackedBars', [2, 3, 4 ]], ['Lines', [1]] ]);
+
+$g->set ('legend_labels'  => ['BZ', 'KHE', 'Bolus', 'Basal'],
+         'legend'         => 'bottom',
+	 'title'          => '',
+	 'precision'      => 0,
+	 'spaced_bars'    => 'false',
+	 'include_zero'   => 'true',
+	 'legend_example_size' => 100,
+	 'skip_int_ticks' => 3,
+	 'min_val2'       => 0,
+         #'max_val2'       => 400,
+	 'legend_example_height' => 'true',
+	 'legend_example_height0..2' => 10,               # Reihenfolge durch composite info
+	 'legend_example_height3' => 2,
+	 'y_label'       => 'IE/KHE',
+	 'y_label2'       => 'mg/dl (mmol/l)',
+	 'grey_background' => 'false',
+	  );
+	 
+$g->set( 'colors' => {'y_label'  => [51, 255, 0],
+                      'y_label2' => [255, 0, 0],
+		      'dataset2' => [0, 0, 244],       # Reihenfolge durch composite info!!!
+		      'dataset1' => [0, 204, 0],
+		      'dataset0' => [255, 255, 51],
+		      'dataset3' => [204, 0, 0],
+		     
+		     		      });
+		      
+$g->set ( 'f_y_tick' => sub { return($_[0] .'('.sprintf("%.1f", $_[0]/18.0182).')') });
+
+
+
+
+$g->png("samples/composite_2.png"); 
+
+print "ok 1\n";
+
+exit 0;

Added: packages/libchart-perl/branches/upstream/current/t/composite_3.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/composite_3.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/composite_3.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,73 @@
+#!/usr/bin/perl -w
+use strict;
+use Chart::Composite;   #(type is one of: Points, Lines, Bars, LinesPoints, Composite, StackedBars, Mountain)
+
+print "1..1\n";
+my $obj = Chart::Composite->new(800, 600);   #Breite, Höhe
+my @legend_ary;
+my ($legend, @zeile)    ;
+my @all_aryref;
+open(OUT, ">samples/composite_3.png") or die "kann Datei nicht schreiben\n";
+
+my $i =0;
+my $e = 0;
+my $max_val = 0;
+while(<DATA>) {
+        if ($_ =~ /EOF/i){
+            last;
+      }
+      chomp;
+       $i++;
+       ($legend, @zeile) = split/\|/,$_;
+       $obj->add_dataset(@zeile);
+       if ( $i != 1 ){
+              push @legend_ary ,$legend ;    # Erste Zeile ist die x-Achsenbezeichnung und gehört nicht zur Legende
+              for (0..$#zeile) { $zeile[$_] > $max_val  ? $max_val = $zeile [$_]  : 1 ;}  # den Maximalen Wert ermitteln
+       }
+       $all_aryref[$e++] = [@zeile];
+
+}
+
+if ( $max_val =~ /^\d+$/ ) {
+
+      $max_val = 100 * int( 1 + $max_val/100);
+} # den Scalenwert die nächste 100er Stellen setzen
+
+# Der zweite Charttyp überdeckt immer den ersten
+$obj->set(  'legend'        => "top",
+            'legend_labels' => \@legend_ary ,
+            'x_ticks'       => "vertical",
+            'composite_info'=> [ ['StackedBars', [8,7,6,5]  ],
+                                 ['Bars',[1,2,3,4,9] ],
+                                ],
+	    'same_y_axes'  => "true",
+            'y_label'      => "Anzahl",
+            'max_val1'     =>  $max_val ,
+            'max_val2'     =>  $max_val,
+            'space_bars'   =>  1 ,
+            'brush_size'   =>  10,
+	    'legend_example_height'  => 'true',
+	    'legend_example_height0..3' => '50',
+	    'legend_example_height4..8' => '4',
+	                                     );
+
+$obj->png(\*OUT);
+print "ok 1\n";
+close OUT;
+
+exit 0;
+
+
+__END__
+Datum|01.09.2003|02.09.2003|03.09.2003|04.09.2003|05.09.2003|06.09.2003|07.09.2003|08.09.2003|09.09.2003|10.09.2003|11.09.2003|12.09.2003|13.09.2003|14.09.2003|15.09.2003|16.09.2003|17.09.2003|18.09.2003|19.09.2003|20.09.2003|21.09.2003|22.09.2003
+Anzahl gesamt|322|244|227|223|167|216|290|277|206|237|256|214|192|228|218|225|146|172|140|123|174|173
+Anzahl  Stufe 1 bis 4 gesamt|226|173|159|145|109|148|204|188|133|184|176|137|132|157|139|155|106|115|93|76|107|106
+Anzahl JL|77|46|44|61|41|54|69|63|63|38|71|68|54|59|71|61|34|40|42|38|56|57
+Anzahl  DL|19|25|24|17|17|14|17|26|10|15|9|9|6|12|8|9|6|17|5|9|11|10
+Anzahl  1.  Stufe|28|22|11|27|15|23|28|23|17|24|24|20|19|24|23|30|20|18|12|10|14|29
+Anzahl  2. Stufe|12|11|4|7|8|6|16|12|8|11|10|8|4|8|3|6|7|6|5|7|8|13
+Anzahl  3.  Stufe|50|39|55|34|16|33|38|40|36|38|48|29|35|42|36|42|28|25|20|19|24|19
+Anzahl  4.  Stufe|136|101|89|77|70|86|122|113|72|111|94|80|74|83|77|77|51|66|56|40|61|45
+Anzahl Formulars|547|352|249|174|138|157|262|180|136|132|94|72|59|129|88|60|61|51|42|44|79|57
+EOF
+

Added: packages/libchart-perl/branches/upstream/current/t/composite_4.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/composite_4.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/composite_4.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,25 @@
+#!usr/bin/perl -w
+
+use Chart::Composite;
+
+print "1..1\n";
+
+$g = Chart::Composite->new(750, 600);
+
+$g->add_dataset (1,2,3);
+$g->add_dataset (10,20,30);
+$g->add_dataset (15,25,32);
+$g->add_dataset (7,24,23);
+$g->add_dataset (0.1,0.5,0.9);
+
+$g->set ('title' => 'Composite Chart Test 2',
+	 'composite_info' => [ ['Bars', [1,2]],
+	 		       ['LinesPoints', [3,4]] ],
+	'include_zero' => 'true',
+	      );
+
+$g->png("samples/composite_4.png");
+
+print "ok 1\n";
+
+exit(0);

Added: packages/libchart-perl/branches/upstream/current/t/composite_5.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/composite_5.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/composite_5.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,24 @@
+#!/usr/bin/perl -w
+
+use Chart::Composite;
+
+print "1..1\n";
+
+$g = Chart::Composite->new(750, 600);
+
+$g->add_dataset (1,2,3);
+$g->add_dataset (10,20,30);
+$g->add_dataset (15,25,32);
+$g->add_dataset (7,24,23);
+$g->add_dataset (0.1,0.5,0.9);
+
+$g->set ('title' => 'Composite Chart Test 2',
+	 'composite_info' => [ ['Bars', [1..3]],
+	 		       ['LinesPoints', [4]] ]);
+
+$g->png("samples/composite_5.png");
+
+print "ok 1\n";
+
+exit(0);
+

Added: packages/libchart-perl/branches/upstream/current/t/composite_6.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/composite_6.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/composite_6.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,36 @@
+#!/usr/bin/perl -w
+
+use Chart::Composite;
+use strict;
+
+print "1..1\n";
+
+my @labels         = qw (06:00-10:00 10:00-14:00 14:00-18:00 18:00-22:00 22:00-02:00 02:00-06:00);
+my @chart_data     = qw (0 140 160 155 150 145);
+my @chart_lowlimit = qw (120 120 120 120 120 120);
+my @chart_hilimit  = qw (180 180 180 180 180 180);
+
+my $chart = Chart::Composite->new(500,300);
+$chart->add_dataset(@labels);
+$chart->add_dataset(@chart_data);
+$chart->add_dataset(@chart_lowlimit);
+$chart->add_dataset(@chart_hilimit);
+
+my %chart_settings = ('precision' => 0,
+                      'legend' => 'none', 
+                      'graph_border' => 0,'png_border' => 1,
+                      'brush_size1' => 2, 
+                      'brush_size2' => 10, 
+                      'grid_lines' => 'false',
+                      'y_grid_lines' => 'true',
+                      'composite_info' => [ ['LinesPoints', [1]], ['Lines', [2,3]] ],
+                      'colors' => { dataset0 => 'black', dataset1 => 'red', dataset2 => 'red' },
+                      'sub_title' => 'Average Chart', 'min_val' => 0, 'max_val' => 200);
+
+$chart->set(%chart_settings);
+$chart->png("samples/composite_6.png");
+
+print "ok 1\n";
+
+exit(0);
+

Added: packages/libchart-perl/branches/upstream/current/t/composite_f.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/composite_f.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/composite_f.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,41 @@
+#!/usr/bin/perl -w
+
+use Chart::Composite;
+use strict;
+
+print "1..1\n";
+
+my $g = Chart::Composite->new;
+
+$g->add_dataset (1 , 2, 3, 7, 5, 6);
+$g->add_dataset (0.1, 0.2, 0.3, 0.2, 0.4, 0.1);
+$g->add_dataset (0.3, 0.5, 0.2, 0.6, 0.7, 0.4);
+$g->add_dataset (10, 11, 6, 7, 7, 8);
+
+$g->set ('title' => 'Composite Chart',
+	 'composite_info' => [ ['Bars', [1,2]],
+	 		       ['LinesPoints', [3]] ]);
+$g->set( 'include_zero' => 'true');	 		       
+$g->set( 'legend' => 'top');
+$g->set( 'legend_example_height' => 'true',);
+$g->set( 'legend_example_height0..1' => '10');
+$g->set( 'legend_example_height2' => '3');
+$g -> set ('f_y_tick' => \&multiply);
+$g -> set ('f_x_tick' => \&int_quadrat);
+$g->png("samples/composite_f.png");
+	 		      
+
+print "ok 1\n";
+
+exit(0);
+
+sub multiply {
+ my $y = shift;
+
+ return ($y*10);
+ }
+
+sub int_quadrat {
+ my $x = shift;
+ return $x*$x; 
+ }		      


Property changes on: packages/libchart-perl/branches/upstream/current/t/composite_f.t
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/t/direction_1.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/direction_1.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/direction_1.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,29 @@
+#!/usr/bin/perl -w
+
+use Chart::Direction;
+
+print "1..1\n";
+
+$g = Chart::Direction->new(500,500);
+ my @labels = ('eins', 'zwei', 'drei',);
+
+  $g->add_dataset(0, 10, 30, 100, 110, 200, 250, 300, 350);
+  $g->add_dataset(10, 4, 11,  40,  20,  35,  5,   45,  20);
+  $g->add_dataset(29, 49, 20, 17,  30,  42,  45,  25,  30); 
+  $g->add_dataset(40,  35, 25, 30,  42,  20,  32,  16, 5);
+  $g->set( 'title' => 'Direction Demo',
+	 'grey_background' => 'false',
+	 'line' => 'true',
+         'precision' => 0,
+	 'legend_labels' => \@labels,
+	 'legend' => 'bottom',
+	# 'polar' => 'true',
+         );
+
+$g->png("samples/direction_1.png");
+
+print "ok 1\n";
+
+
+exit (0);
+


Property changes on: packages/libchart-perl/branches/upstream/current/t/direction_1.t
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/t/direction_2.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/direction_2.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/direction_2.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,27 @@
+#!/usr/bin/perl -w
+
+use Chart::Direction;
+
+print "1..1\n";
+
+$g = Chart::Direction->new(450,450);
+
+$g->add_dataset(0, 10, 30, 100, 110, 200, 250, 300, 350);
+$g->add_dataset(10, 4, 11,  40,  20,  35,  5,   45,  20);
+$g->add_dataset(20, 8, 22, 80,   40,  70,  10,  90,  40);
+$g->add_dataset(30, 18, 32, 85, 45, 60, 20, 50, 25);
+
+$g->set( 'title' => 'Direction Demo',
+	 'angle_interval' => 15,
+         'precision' => 0,
+	 'grey_background' => 'false',
+	 'legend' => 'top',
+
+        );
+
+$g->png("samples/direction_2.png");
+
+print "ok 1\n";
+
+exit (0);
+


Property changes on: packages/libchart-perl/branches/upstream/current/t/direction_2.t
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/t/direction_3.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/direction_3.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/direction_3.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,35 @@
+#!/usr/bin/perl -w
+
+use Chart::Direction;
+
+print "1..1\n";
+
+$g = Chart::Direction->new(500,500);
+
+$g->add_dataset(0,  100,  50, 200,  280, 310);
+$g->add_dataset(30,  40,  20,  35,   45,  20);
+
+$g->add_dataset(10,  110, 60, 210,  290, 320);
+$g->add_dataset(30,  40,  20,  35,   45,  20);
+
+$g->add_dataset(20,  120, 70, 220,  300, 330);
+$g->add_dataset(30,  40,  20,  35,   45,  20);
+
+
+$g->set( 'title' => 'Direction Demo',
+	 'angle_interval' => 45,
+         'precision' => 0,
+         'arrow' => 'true',
+         'point' => 'false',
+	 'include_zero' => 'true',
+	 'pairs' => 'true',
+	 'legend' => 'none',
+         'grey_background' => 'false',
+        );
+
+$g->png("samples/direction_3.png");
+
+print "ok 1\n";
+
+exit (0);
+


Property changes on: packages/libchart-perl/branches/upstream/current/t/direction_3.t
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/t/direction_4.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/direction_4.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/direction_4.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,39 @@
+#!/usr/bin/perl -w
+
+use Chart::Direction;
+
+print "1..1\n";
+
+$g = Chart::Direction->new(500,500);
+
+$g->add_dataset(210, 220, 200, 215, 225, 200); 
+$g->add_dataset(30,  40,  20,  35,   45,  20);
+
+$g->add_dataset(30,  40,  20,  35,   45,  20);
+$g->add_dataset(30,  40,  20,  35,   45,  20);
+
+$g->add_dataset(120, 130, 110, 125, 135, 110);
+$g->add_dataset(30,  40,  20,  35,   45,  20);
+
+$g->add_dataset(300, 310, 290, 305, 315, 290);
+$g->add_dataset(30,  40,  20,  35,   45,  20); 
+
+
+
+$g->set( 'title' => 'Direction Demo',
+	 'angle_interval' => 45,
+         'precision' => 0,
+         'arrow' => 'true',
+         'point' => 'false',
+	 'include_zero' => 'true',
+	 'pairs' => 'true',
+	 'legend' => 'none',
+         'grey_background' => 'false',
+        );
+
+$g->png("samples/direction_4.png");
+
+print "ok 1\n";
+
+exit (0);
+

Added: packages/libchart-perl/branches/upstream/current/t/error_1.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/error_1.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/error_1.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,29 @@
+#!/usr/bin/perl -w
+
+use Chart::ErrorBars;
+
+print "1..1\n";
+
+$g = Chart::ErrorBars->new();
+
+$g->add_dataset(qw(1   1.1  1.2  1.3  1.4  1.5  1.6  1.7  1.8  1.9  2   2.1 2.2 2.3 2.4 2.5));
+$g->add_dataset(qw(1   1.1  1.2  1.1  1.14 1.15 1.26 1.2 1.1  1.19 1.2 1.4 1.6 2.0 2.5 3.1));
+$g->add_dataset(qw(0.4 0.1  0.2  0.1  0.14 0.15 0.26 0.27 0.1  0.19 0.2 0.1 0.1 0.2 0.1 0.3));
+$g->add_dataset(qw(0.2 0.11 0.12 0.11 0.2  0.3  0.12 0.27 0.11 0.3  0.2 0.2 0.2 0.1 0.1 0.2));
+$g->set('xy_plot' => 'true',
+         'precision' => 1,
+         'pt_size' =>12,
+         'brush_size' => 2,
+         'legend' => 'none',
+         'title' => 'Error Bars Demo',
+         'grid_lines' => 'true',
+         'y_axes' => 'both',
+         'custom_x_ticks' => [0,1,2],
+	 
+         );
+
+$g->png ("samples/error_1.png");
+
+print "ok 1\n";
+
+exit (0);


Property changes on: packages/libchart-perl/branches/upstream/current/t/error_1.t
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/t/error_2.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/error_2.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/error_2.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,29 @@
+#!usr/bin/perl -w
+
+use Chart::ErrorBars;
+
+print "1..1\n";
+
+$g = Chart::ErrorBars->new();
+
+$g->add_dataset(qw(1   1.1  1.2  1.3  1.4  1.5  1.6  1.7  1.8  1.9  2   2.1 2.2 2.3 2.4 2.5));
+$g->add_dataset(qw(1   1.1  1.2  1.1  1.14 1.15 1.26 1.2 1.1  1.19 1.2 1.4 1.6 2.0 2.5 3.1));
+$g->add_dataset(qw(0.4 0.1  0.2  0.1  0.14 0.15 0.26 0.27 0.1  0.19 0.2 0.1 0.1 0.2 0.1 0.3));
+
+$g->set( 'xy_plot' => 'true',
+         'precision' => 2,
+	 'same_error' => 'true',
+         'pt_size' =>12,
+         'brush_size' => 2,
+         'legend' => 'none',
+         'title' => 'Error Bars Demo',
+         'include_zero' => 'true',
+	 'max_val' => 3,
+	 'custom_x_ticks' => [0,1],
+         );
+
+$g->png ("samples/error_2.png");
+
+print "ok 1\n";
+
+exit (0);


Property changes on: packages/libchart-perl/branches/upstream/current/t/error_2.t
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/t/f_ticks.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/f_ticks.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/f_ticks.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,109 @@
+#!/usr/bin/perl -w
+#
+# Testprogram for lines
+# converting seconds since 0 o'clock to HH:MM:SS on x
+# converting -1 .. +1 to -100 ... +100 on y
+#
+#======================================================================
+
+use strict;
+use Chart::Points;
+
+print "1..1\n";
+
+my @x_values = ();     # x axis
+my @y_values = ();
+
+my $graphic;
+my $min_x = 600;     # random start
+my $max_x = 86400;   # number of seconds of a day
+my $min_y;
+my $max_y;
+
+
+my $x;
+my $y;
+
+#------------------------------------------------------------------------------------
+# Start
+#------------------------------------------------------------------------------------
+
+$x = $min_x;
+for ( my $x_idx = 0; $x < $max_x; $x_idx++ ) {
+   $x = $min_x + $x_idx*23;
+   $x_values[$x_idx] = $x;
+   $y_values[$x_idx] = cos(($x - $min_x)/3000);
+}
+
+   
+#------------------------------------------------------------------------------------
+# Make it
+#------------------------------------------------------------------------------------
+
+	$graphic = Chart::Points -> new (750,600);
+	$graphic -> set ('brush_size' => 2 );
+		
+	$graphic -> add_dataset ( @x_values );
+	
+	$graphic -> add_dataset ( @y_values );
+	
+
+	
+	
+	
+	$graphic -> set ('min_val' => $min_y );
+	$graphic -> set ('max_val' => $max_y);
+	#$graphic -> set ('y_ticks' => 11 );
+	
+	
+	
+	
+	
+	$graphic -> set ('skip_x_ticks' => 100);
+	$graphic -> set ('pt_size' => 2);
+	$graphic -> set ('grey_background' => 'true' );		
+	$graphic -> set ('graph_border' => 18 );
+	$graphic -> set ('title' => "f_tick example for x and y values" );
+	$graphic -> set ('y_grid_lines' => 'false' );
+	$graphic -> set ('x_grid_lines' => 'false' );
+	$graphic -> set ('x_ticks'	=> 'vertical' );
+	$graphic -> set ('legend' => 'none' );
+	$graphic -> set ('x_label' => 'Time of the day' );
+	$graphic -> set ('y_label' => 'f = sin(x)' );
+
+        # use a special function to convert the x values to HH:MM:SS
+        $graphic -> set ('f_x_tick' => \&seconds_to_hour_minute);
+        
+        # use a special function to convert the y values to something special
+        $graphic -> set ('f_y_tick' => \&formatter);
+
+	if ( $graphic -> can ('gif') ){
+		my $picture_file = "samples/f_ticks.gif";
+		$graphic -> gif ($picture_file);
+	}
+	if ( $graphic -> can ('png') ) {
+		my $picture_file = "samples/f_ticks.png";
+		$graphic -> png ($picture_file);
+	}
+	
+
+print "ok 1\n";
+
+exit (0);
+
+
+sub seconds_to_hour_minute {
+   my $seconds = shift;
+   
+   my $hour = int($seconds / 3600); 
+   my $minute = int(($seconds - $hour*3600)/60);
+   my $sec  = $seconds - $hour*3600 - $minute*60;
+   
+   sprintf "%02d:%02d:%02d",$hour,$minute,$sec;
+}
+
+sub formatter {
+   my $y_value = shift;
+   
+   sprintf "%02d",int($y_value*10);
+}

Added: packages/libchart-perl/branches/upstream/current/t/hbars_1.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/hbars_1.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/hbars_1.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,42 @@
+#!/usr/bin/perl -w
+
+use Chart::HorizontalBars;
+
+print "1..1\n";
+
+$g = Chart::HorizontalBars->new(600 ,500);
+
+$g->add_dataset ('January' , 'February' , 'March', 'April', 'May', 'June',
+                 'July', 'August' , 'September' , 'October', 'November', 'December');
+$g->add_dataset (14, 12, 18, 17, 15, 11, 12, 10, 14, 12, 18, 17);
+$g->add_dataset (11, 13, 14, 15, 11, 10, 9, 8, 11, 13, 11, 12);
+$g->add_dataset (4, 8, 7, 4, 5, 4, 6, 4, 6, 10, 7, 4);
+$g->add_dataset (5, 7, 6, 5, 6, 6, 7, 8, 6, 9, 8, 7);
+$g->add_dataset (5, 4, 2, 5, 3, 6, 1, 4, 5, 4, 2, 5);
+
+%hash = (
+         'y_axes' => 'both',
+ 	 'title' => 'Sold Cars in 2001',
+         'integer_ticks_only' => 'true',
+         'legend' => 'bottom',
+	 'y_label' => 'month',
+         'y_label2' => 'month',
+	 'x_label' => 'number of cars',
+         'legend_labels'  => ['Berlin', 'Munich', 'Rome', 'London', 'Paris'],
+         'min_val' => 0,
+         'max_val' => 20,
+	 'grid_lines' =>'true',
+	 'colors' => {'title' => 'red',
+	 	      'x_label' => 'blue',
+                      'y_label' => 'blue',
+                      'y_label2' => 'blue',
+                      'dataset4' => 'yellow'},
+	 );
+
+$g->set (%hash);
+
+$g->png ("samples/hbars_1.png");
+
+print "ok 1\n";
+
+exit (0);


Property changes on: packages/libchart-perl/branches/upstream/current/t/hbars_1.t
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/t/hbars_2.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/hbars_2.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/hbars_2.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,39 @@
+#!/usr/bin/perl -w
+
+use Chart::HorizontalBars;
+
+print "1..1\n";
+
+$g = Chart::HorizontalBars->new(500,400);
+$g->add_dataset ('Foo', 'bar', 'junk', 'ding', 'bat');
+$g->add_dataset (-4, 3, -4, -5.4, -2);
+$g->add_dataset (2.2, 10, -3, 8, 3);
+$g->add_dataset (-10, 2, 4, -3, -3);
+$g->add_dataset (7, -5, -3, 4, 7);
+
+%hash = ('transparent' => 'true',
+         'y_axes' => 'both',
+	 'title' => 'Hirizontal Bars Demo',
+	 'y_grid_lines' => 'true',
+	 'x_label' => 'x-axis',
+	 'y_label' => 'y-axis',
+	 'y_label2' => 'y-axis',
+         'tick_len' => '5',
+	 'x_ticks' => 'vertical',
+	 'grid_lines' =>'true',
+	 'colors' => {
+	 	      'text' => [100,0,200],
+	 	      'y_label' => [2,255,2],
+	 	      'y_label2' => [2,255,2],
+	 	      'y_grid_lines' => [255 ,255,255],
+	 	      'x_grid_lines' => [255,255,255],
+   	 	      },
+	 );
+
+$g->set (%hash);
+
+$g->png ("samples/hbars_2.png");
+
+print "ok 1\n";
+
+exit (0);


Property changes on: packages/libchart-perl/branches/upstream/current/t/hbars_2.t
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/t/hbars_3.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/hbars_3.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/hbars_3.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,29 @@
+#!/usr/bin/perl -w
+
+use Chart::HorizontalBars;
+
+print "1..1\n";
+
+$g = Chart::HorizontalBars->new(500,400);
+$g->add_dataset ('Foo', 'bar', 'junk', 'ding', 'bat');
+$g->add_dataset (-4, -3, -4, -5, -2);
+$g->add_dataset (-2, -10, -3, -8, -3);
+
+%hash = (
+         'y_axes' => 'right',
+	 'title' => 'Horizontal Bars Demo',
+	 'x_grid_lines' => 'true',
+	 'x_label' => 'x-axis',
+	 'y_label' => 'y-axis',
+  	 'x_ticks' => 'staggered',
+         'include_zero' => 'true',
+         'spaced_bars' => 'false',
+	 );
+
+$g->set (%hash);
+
+$g->png ("samples/hbars_3.png");
+
+print "ok 1\n";
+
+exit (0);


Property changes on: packages/libchart-perl/branches/upstream/current/t/hbars_3.t
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/t/hbars_4.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/hbars_4.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/hbars_4.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,24 @@
+#!usr/bin/perl -w
+
+use Chart::HorizontalBars;
+
+print "1..1\n";
+
+$g = Chart::HorizontalBars->new();
+$g->add_dataset ('Foo', 'bar', 'junk', 'ding', 'bat');
+$g->add_dataset (4, 3, 4, 2, 8);
+$g->add_dataset (2, 10, 3, 8, 3);
+
+%hash = (
+	 'title' => 'Horizontal Bars Demo',
+	 'grid_lines' => 'true',
+	 'x_label' => 'x-axis',
+	 'y_label' => 'y-axis',
+	 'include_zero' => 'true',
+  	 );
+
+$g->set (%hash);
+$g->png ("samples/hbars_4.png");
+
+print "ok 1\n";
+exit (0);


Property changes on: packages/libchart-perl/branches/upstream/current/t/hbars_4.t
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/t/lines.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/lines.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/lines.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,28 @@
+#!/usr/bin/perl -w
+
+
+use Chart::Lines;
+
+print "1..1\n";
+
+$g = Chart::Lines->new;
+$g->add_dataset ('foo', 'bar', 'whee', 'ding','bat',);
+$g->add_dataset (3.2, 4.1, 9.8, 10, 11,);
+$g->add_dataset (8, 5.3, 3, 4, 5.1,);
+$g->add_dataset (5, 7, 2.3, 10, 12,);
+
+
+
+%hash =( 'title' => 'Lines Chart',
+	 'legend_example_size' => 10,
+	 'grid_lines' => 'true',
+	'grey_background' => 'false',
+	 'colors' => { 'text' => [255,0,0],
+	 		'grid_lines' => [240,0,0]}
+	);
+$g->set ( %hash); 
+$g->png ("samples/lines.png");
+print "ok 1\n";
+
+exit (0);
+

Added: packages/libchart-perl/branches/upstream/current/t/lines_1.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/lines_1.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/lines_1.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,31 @@
+#!/usr/bin/perl -w
+
+use Chart::Lines;
+use strict;
+my $g;
+
+print "1..1\n";
+
+$g = Chart::Lines->new(600,400);
+$g->add_dataset ('foo', 'bar', 'whee', 'ding','bat', 'bit');
+$g->add_dataset (3.2, 4.34, 9.456, 10.459, 11.24234, 14.0234);
+$g->add_dataset (-1.3, 8.4, 5.34, 3.234, 4.33, 13.09);
+$g->add_dataset (5, 7, 2, 10, 12, 2.3445);
+
+
+$g->set ('title' => 'LINES');
+$g->set ('sub_title' => 'Lines Chart');
+$g->set ('colors' => {'y_label' => [0,0,255], y_label2 => [0,255,0], 
+	'y_grid_lines' => [127,127,0], 'dataset0' => [127,0,0],
+	'dataset1' => [0,127,0], 'dataset2' => [0,0,127]});
+$g->set ('y_label' => 'y label 1');
+$g->set ('y_label2' => 'y label 2');
+$g->set ('y_grid_lines' => 'true');
+$g->set ('legend' => 'bottom');
+
+$g->png ("samples/lines_1.png");
+
+print "ok 1\n";
+
+exit (0);
+

Added: packages/libchart-perl/branches/upstream/current/t/lines_2.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/lines_2.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/lines_2.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,29 @@
+use Chart::Lines;
+use strict;
+my $g;
+
+print "1..1\n";
+
+$g = Chart::Lines->new;
+$g->add_dataset ('foo', 'bar', 'whee', 'ding','bat', 'bit');
+$g->add_dataset (3.2, 4.34, 9.456, 10.459, 11.24234, 14.0234);
+$g->add_dataset (-1.3, 8.4, 5.34, 3.234, 4.33, 13.09);
+$g->add_dataset (5, 7, 2, 10, 12, 2.3445);
+$g->add_dataset (8, 4, 5, 12, 3, 9);
+
+$g->set ('title' => 'LINES');
+$g->set ('sub_title' => 'Lines Chart');
+$g->set ('colors' => {'y_label' => [0,0,255], y_label2 => [0,255,0], 
+	'y_grid_lines' => [127,127,0], 'dataset0' => [127,0,0],
+	'dataset1' => [0,127,0], 'dataset2' => [0,0,127]});
+$g->set ('y_label' => 'y label 1');
+$g->set ('y_label2' => 'y label 2');
+$g->set ('y_grid_lines' => 'true');
+$g->set ('legend' => 'left');
+
+$g->png ("samples/lines_2.png");
+
+print "ok 1\n";
+
+exit (0);
+

Added: packages/libchart-perl/branches/upstream/current/t/lines_3.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/lines_3.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/lines_3.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,28 @@
+use Chart::Lines;
+use strict;
+my $g;
+
+print "1..1\n";
+
+$g = Chart::Lines->new;
+$g->add_dataset ('foo', 'bar', 'whee', 'ding','bat', 'bit');
+$g->add_dataset (3.2, 4.34, 9.456, 10.459, 11.24234, 14.0234);
+$g->add_dataset (-1.3, 8.4, 5.34, 3.234, 4.33, 13.09);
+$g->add_dataset (5, 7, 2, 10, 12, 2.3445);
+
+$g->set ('title' => 'LINES');
+$g->set ('sub_title' => 'Lines Chart');
+$g->set ('colors' => {'y_label' => [0,0,255], y_label2 => [0,255,0], 
+	'y_grid_lines' => [127,127,0], 'dataset0' => [127,0,0],
+	'dataset1' => [0,127,0], 'dataset2' => [0,0,127]});
+$g->set ('y_label' => 'y label 1');
+$g->set ('y_label2' => 'y label 2');
+$g->set ('y_grid_lines' => 'true');
+$g->set ('legend' => 'right');
+
+$g->png ("samples/lines_3.png");
+
+print "ok 1\n";
+
+exit (0);
+

Added: packages/libchart-perl/branches/upstream/current/t/lines_4.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/lines_4.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/lines_4.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,31 @@
+#!/usr/bin/perl -w
+
+
+use Chart::Lines;
+use strict;
+my $g;
+
+print "1..1\n";
+
+$g = Chart::Lines->new;
+$g->add_dataset ('foo', 'bar', 'whee', 'ding','bat', 'bit');
+$g->add_dataset (3.2, 4.34, 9.456, 10.459, 11.24234, 14.0234);
+$g->add_dataset (-1.3, 8.4, 5.34, 3.234, 4.33, 13.09);
+$g->add_dataset (5, 7, 2, 10, 12, 2.3445);
+
+$g->set ('title' => "LINES");
+$g->set ('sub_title' => 'Lines Chart');
+$g->set ('colors' => {'y_label' => [0,0,255], y_label2 => [0,255,0], 
+	'y_grid_lines' => [127,127,0], 'dataset0' => [127,0,0],
+	'dataset1' => [0,127,0], 'dataset2' => [0,0,127]});
+$g->set ('y_label' => 'y label 1');
+$g->set ('y_label2' => 'y label 2');
+$g->set ('y_grid_lines' => 'true');
+$g->set ('legend' => 'top');
+
+$g->png ("samples/lines_4.png");
+
+print "ok 1\n";
+
+exit (0);
+

Added: packages/libchart-perl/branches/upstream/current/t/lines_5.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/lines_5.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/lines_5.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,52 @@
+#!/usr/bin/perl -w
+
+
+use Chart::Lines;
+print "1..1\n";
+
+$g = Chart::Lines->new(600,300);
+
+ at x_values = ( );
+ at y_values = ( );
+for ( $i = 0 ; $i <= 16; $i += 0.05) {
+  $j = sin($i);
+  $j2 = cos ($i);
+  push (@x_values, $i);
+  push (@y_values, $j);
+  push (@y2_values, $j2);
+}
+
+$g->add_dataset (@x_values);
+$g->add_dataset (@y_values);
+$g->add_dataset (@y2_values);
+
+%hash = (
+ 	 'title' => 'The trigonometric functions sinus and cosinus',
+         'grid_lines' => 'true',
+         'legend' => 'left',
+         'xy_plot' => 'true',
+         'skip_x_ticks' => 20,
+         'legend_labels' => ['y = sin x', 'y = cos x'],
+         'precision' => 2,
+	 'integer_ticks_only' => 'true',
+	 #'custom_x_ticks' => [0,3],
+	 'colors' => {
+                      'title' =>'plum',
+                      'dataset0' => 'mauve',
+                     },
+         'f_x_tick' => \&formatter,
+   	 );
+
+$g->set (%hash);
+
+$g->png ("samples/lines_5.png");
+
+sub formatter {
+   my $d = shift;
+   $d = sprintf "%1.2f",$d;
+   if ( $d =~ /^0.00/) {return 0}
+   return $d;
+}
+print "ok 1\n";
+
+exit (0);


Property changes on: packages/libchart-perl/branches/upstream/current/t/lines_5.t
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/t/lines_6.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/lines_6.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/lines_6.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,40 @@
+#!/usr/bin/perl -w
+
+use Chart::Lines;
+print "1..1\n";
+
+$g = Chart::Lines->new();
+$g->add_dataset ('foo', 'bar', 'junk', 'ding', 'bat');
+$g->add_dataset (-4, 3, -4, -5, -2);
+$g->add_dataset (2, 10, -3, 8, 3);
+$g->add_dataset (-10, 2, 4, -3, -3);
+$g->add_dataset (7, -5, -3, 4, 7);
+
+%hash = (
+         'legend_labels' => ['1st Quarter', '2nd Quarter','3rd Quarter', '4th Quarter'],
+         'y_axes' => 'both',
+	 'title' => 'Lines Demo',
+	 'grid_lines' => 'true',
+       	 'grid_lines' =>'true',
+         'legend' => 'left',
+         'legend_example_size' => 20,
+	 'colors' => {
+	 	      'text' => 'blue',
+	 	      'misc' => 'blue',
+                      'background' => 'grey',
+                      'grid_lines' => 'light_blue',
+                      'dataset0' => [220,0,0],
+                      'dataset1' => [200,0,100],
+                      'dataset2' => [150,50,175],
+                      'dataset3' => [170,0,255],
+   	 	      },
+         );
+
+$g->set (%hash);
+
+$g->png ("samples/lines_6.png");
+
+print "ok 1\n";
+
+exit (0);
+


Property changes on: packages/libchart-perl/branches/upstream/current/t/lines_6.t
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/t/lines_7.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/lines_7.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/lines_7.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,31 @@
+#!/usr/bin/perl -w
+
+
+use Chart::Lines;
+use strict;
+my $g;
+
+print "1..1\n";
+
+$g = Chart::Lines->new;
+$g->add_dataset ('one', 'two', 'three', 'four','five', 'six');
+$g->add_dataset (3, 11, 5, 10, 12, 4);
+$g->add_dataset (-1, 3, 6, -2, -8, 0);
+$g->add_dataset (5, 5, 6, 2, 12, 9);
+$g->add_dataset (0, 0, 0, 0, 0, 0);
+$g->add_dataset (-12, -18, 0, 0, 0, 1);
+
+
+$g->set ('title' => "Lines Chart");
+$g->set ('sub_title' => 'Lines Chart');
+$g->set ('y_grid_lines' => 'true');
+$g->set ('legend' => 'bottom');
+$g->set ('precision' => '0');
+$g->set ('include_zero' => 'true');
+
+$g->png ("samples/lines_7.png");
+
+print "ok 1\n";
+
+exit (0);
+

Added: packages/libchart-perl/branches/upstream/current/t/lines_8.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/lines_8.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/lines_8.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,29 @@
+#!/usr/bin/perl -w
+
+
+use Chart::Lines;
+use strict;
+my $g;
+
+print "1..1\n";
+
+$g = Chart::Lines->new;
+$g->add_dataset ('one', 'two', 'three', 'four','five', 'six');
+$g->add_dataset (3, 11, 5, 10, 12, 4);
+
+
+$g->set ('title' => "Timing");
+$g->set ('sub_title' => 'Example for stepline');
+$g->set ('y_grid_lines' => 'true');
+$g->set ('legend' => 'none');
+$g->set ('precision' => '0');
+$g->set ('include_zero' => 'true');
+$g->set ('stepline' => 'true');
+$g->set ('stepline_mode' => 'begin');
+
+$g->png ("samples/lines_8.png");
+
+print "ok 1\n";
+
+exit (0);
+

Added: packages/libchart-perl/branches/upstream/current/t/linespoints.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/linespoints.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/linespoints.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,19 @@
+use Chart::LinesPoints;
+
+print "1..1\n";
+
+$g = Chart::LinesPoints->new;
+$g->add_dataset ('foo', 'bar', 'junk', 'ding', 'bat');
+$g->add_dataset (3, 4, 9, 3, 4);
+$g->add_dataset (8, 4, 3, 4, 6);
+$g->add_dataset (5, 7, 2, 7, 9);
+
+$g->set ('title' => 'Lines and Points Chart');
+$g->set ('legend' => 'bottom');
+
+$g->png ("samples/linespoints.png");
+
+print "ok 1\n";
+
+exit (0);
+

Added: packages/libchart-perl/branches/upstream/current/t/linespoints_1.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/linespoints_1.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/linespoints_1.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,26 @@
+use Chart::LinesPoints;
+
+print "1..1\n";
+
+$g = Chart::LinesPoints->new;
+$g->add_dataset ('foo', 'bar', 'junk', 'ding', 'bat');
+$g->add_dataset (3, 4, 9, 3, 4);
+$g->add_dataset (8, 4, 3, 4, 6);
+$g->add_dataset (5, 7, 2, 7, 9);
+
+$g->set ('title' => 'Lines and Points Chart');
+$g->set ('sub_title' => 'Change color for grid_lines');
+
+$g->set ('colors' => {'x_grid_lines' => [250, 0, 125]});
+$g->set ('colors' => {'y_grid_lines' => [250, 0, 125]});
+#$g->set ('colors' => {'y2_grid_lines' => [250, 0, 125]});
+$g->set ('grid_lines' => 'true');
+$g->set ('grey_background' => 'false');
+$g->set ('legend' => 'bottom');
+
+$g->png ("samples/linespoints_1.png");
+
+print "ok 1\n";
+
+exit (0);
+

Added: packages/libchart-perl/branches/upstream/current/t/linespoints_2.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/linespoints_2.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/linespoints_2.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,46 @@
+#!/usr/bin/perl -w
+
+use Chart::LinesPoints;
+use strict;
+
+print "1..1\n";
+
+my (@data, @data2, @labels, %hash, $g, $hits);
+
+# create an array of labels
+for (0..30) {
+  push (@labels, $_);
+}
+
+# create two arrays of data
+for (0..30) {
+  #first array
+  $hits = 2 * $_ ;
+  if ( $_ % 2 == 0) {
+    $hits = $_ ;
+  }
+  push (@data, $hits);
+
+  #second array
+  $hits = 40 - $_ + 10*cos ($_);
+  push (@data2, $hits);
+}
+
+$g = Chart::LinesPoints->new(600,300);
+$g->add_dataset(@labels);
+$g->add_dataset(@data);
+$g->add_dataset(@data2);
+
+%hash =(  'title' => 'Lines with Points Demo',
+          'y_axes' => 'both',
+          'legend' => 'none',
+          'precision' => 0,
+          'xy_plot' => 'true',
+          );
+
+$g->set ( %hash);
+$g->png ("samples/linespoints_2.png");
+print "ok 1\n";
+
+exit (0);
+


Property changes on: packages/libchart-perl/branches/upstream/current/t/linespoints_2.t
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/t/linespoints_3.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/linespoints_3.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/linespoints_3.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,46 @@
+use Chart::LinesPoints;
+use strict;
+
+print "1..1\n";
+
+my (@data1, @data2, @data4, @data3, @labels, %hash, $g, $hits);
+
+ at labels = qw(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17);
+ at data1 = qw (-7 -5 -6 -8 -9 -7 -5 -4 -3 -2 -4 -6 -3 -5 -3 -4 -6);
+ at data2 = qw (-1 -1 -1 -1 -2 -2 -3 -3 -4 -4 -6 -3 -2 -2 -2 -1 -1);
+ at data3 = qw (-4 -4 -3 -2 -1 -1 -1 -2 -1 -1 -3 -2 -4 -3 -4 -2 -2);
+ at data4 = qw (-6 -3 -2 -3 -3 -3 -2 -1 -2 -3 -1 -1 -1 -1 -1 -3 -3);
+
+$g = Chart::LinesPoints->new(600,300);
+$g->add_dataset(@labels);
+$g->add_dataset(@data1);
+$g->add_dataset(@data2);
+$g->add_dataset(@data3);
+$g->add_dataset(@data4);
+
+%hash =(
+          'integer_ticks_only' => 'true',
+          'title' => 'Soccer Season 2002\n ',
+          'legend_labels' => ['NY Soccer Club', 'Denver Tigers',
+                              'Houston Spacecats', 'Washington Presidents'],
+          'y_label' => 'position in the table',
+          'x_label' => 'day of play',
+          'grid_lines' => 'true',
+          'f_y_tick' => \&formatter,
+          );
+
+$g->set ( %hash);
+$g->png ("samples/linespoints_3.png");
+
+
+#just a trick, to let the y scale start at the biggest point:
+#initiate with negativ values, remove the minus sign!
+sub formatter {
+  my $label = shift;
+  $label = substr($label, 1,2);
+  return $label;
+}
+print "ok 1\n";
+
+exit (0);
+


Property changes on: packages/libchart-perl/branches/upstream/current/t/linespoints_3.t
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/t/linespoints_4.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/linespoints_4.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/linespoints_4.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,46 @@
+#!/usr/bin/perl -w
+
+use strict;
+use Chart::LinesPoints;
+
+print "1..1\n";
+
+
+my $g = Chart::LinesPoints->new (700, 350);
+
+my @bezugszeitraum = ('2005-04-02','2005-04-03','2005-04-04','2005-04-05',
+                   '2005-04-06','2005-04-07','2005-04-08','2005-04-09',
+		   '2005-04-10','2005-04-11','2005-04-12','2005-04-13',
+		   '2005-04-14','2005-04-15','2005-04-16','2005-04-17',
+		   '2005-04-18','2005-04-19','2005-04-20','2005-04-21',
+		   '2005-04-22','2005-04-23','2005-04-24','2005-04-25');
+
+
+
+my @clock_reset = (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+#my @clock_reset = (10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10);
+
+
+          $g-> add_dataset ( @bezugszeitraum );
+          $g-> add_dataset ( @clock_reset );
+     
+          $g-> set ('x_ticks' => 'vertical');
+          $g-> set ('x_label' => ' Time');
+	  $g-> set ('y_label' => 'Number of clock resets');
+          $g-> set ('legend' => 'none');
+          $g-> set ('precision' => 1 );
+          $g-> set ('title' => 'AURI');
+	  $g-> set ('sub_title' => '2005-04-01 - 2005-04-25');
+	#  $g-> set ('title_font' => 'gdGiantFont');
+	#  $g-> set ('sub_title_font' => 'gdMediumBoldFont');
+	  $g-> set ('grey_background' => 'false');
+        #  $g-> set ('include_zero' => 'true');
+	#  $g-> set ('min_val' => '0');
+	  $g-> set ('pt_size' => '10');
+	  $g-> set ('brush_size' => '4');
+	#  $g-> set ('skip_x_ticks' => $skip_x);
+	#   $g-> set ('integer_ticks_only' => 'true');
+     
+          $g-> png ("samples/linespoints_4.png");
+          print "ok 1\n\n";
+ 

Added: packages/libchart-perl/branches/upstream/current/t/linespoints_5.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/linespoints_5.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/linespoints_5.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,74 @@
+#!/usr/bin/perl -w
+
+use strict;
+use Chart::Composite;
+
+print "1..1\n";
+
+
+my $g = Chart::Composite->new (700, 350);
+
+my @bezugszeitraum = ('2005-04-02','2005-04-03','2005-04-04',
+                      '2005-04-05','2005-04-06','2005-04-07',
+		      '2005-04-08','2005-04-09','2005-04-10',
+		      '2005-04-18','2005-04-19','2005-04-20',
+		      '2005-04-21','2005-04-22','2005-04-23',
+		      '2005-04-24','2005-04-25');
+
+my @nr_of_sats = (27,29,28,26,27,23,29,29,23,26,29,29,29,29,29,29,29);
+
+my @obsinterval_abs = (0.555555555555556,0.999652777777778,
+                       0.673611111111111,0.607291666666667,
+		       0.638888888888889,0.361111111111111,
+		       0.999652777777778,0.999652777777778,
+		       0.377083333333333,0.51875,
+		       0.84375,          0.977777777777778,
+		       0.999652777777778,0.999652777777778,
+		       0.999652777777778,0.999652777777778,
+		       0.999652777777778);
+		       
+#my @obsinterval_abs = (0.555555555555556,0.999652777777778,
+#                       0.673611111111111,500,
+#		       0.638888888888889,0.361111111111111,
+#		       0.999652777777778,0.999652777777778,
+#		       0.377083333333333,0.51875,
+#		       -500,          0.977777777777778,
+#		       0.999652777777778,0.999652777777778,
+#		       0.999652777777778,0.999652777777778,
+#		       0.999652777777778);		       
+		       
+		       
+		       
+ # Chart::Composite
+     
+
+        #  $g = Chart::LinesPoints->new (800, 350);
+	#  $g = Chart::LinesPoints->new (700, 350);
+	  $g = Chart::Composite->new (700, 350);
+
+          $g-> add_dataset ( @bezugszeitraum );
+          $g-> add_dataset ( @nr_of_sats );
+	  $g-> add_dataset ( @obsinterval_abs );
+     
+          $g-> set ('composite_info' => [ ['LinesPoints', [1]], ['LinesPoints', [2]] ]);
+          $g-> set ('x_ticks' => 'vertical');
+          $g-> set ('x_label' => ' Time');
+	  $g-> set ('y_label' => 'red: Nr_of_sats');
+	#  $g-> set ('y_axes' => 'both');
+	  $g-> set ('y_label2' => 'green: obs_interval (absolut)');
+          $g-> set ('legend' => 'none');
+          $g-> set ('precision' => 1);
+	  $g-> set ('grey_background' => 'false');
+          $g-> set ('title' => 'ANKR');
+	  $g-> set ('sub_title' => '2005-04-02 - 2005-04-25');
+	 # $g-> set ('title_font' => gdGiantFont);
+	 # $g-> set ('sub_title_font' => gdMediumBoldFont);
+          $g-> set ('include_zero' => 'true');
+	  $g-> set ('pt_size' => '10');
+	  $g-> set ('brush_size' => '4');
+	 # $g-> set ('skip_x_ticks' => $skip_x);
+     
+          $g-> png ("samples/linespoints_5.png");
+          print "ok 1\n\n";
+	  
+	  

Added: packages/libchart-perl/branches/upstream/current/t/linespoints_6.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/linespoints_6.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/linespoints_6.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,36 @@
+#!/usr/bin/perl -w
+
+use strict;
+use Chart::LinesPoints;
+use Chart::Lines;
+
+print "1..1\n";
+
+
+my @bezugszeitraum = ('2004-06-13 00:00:00+00',       '2004-06-14 00:00:00+00',       '2004-06-15 00:00:00+00',      '2004-06-16 00:00:00+00',        '2004-06-17 00:00:00+00',       '2004-06-18 00:00:00+00',      '2004-06-19 00:00:00+00',        '2004-06-20 00:00:00+00',       '2004-06-21 00:00:00+00',      '2004-06-22 00:00:00+00',        '2004-06-23 00:00:00+00',       '2004-06-24 00:00:00+00',      '2004-06-25 00:00:00+00',        '2004-06-26 00:00:00+00',       '2004-06-27 00:00:00+00',      '2004-06-28 00:00:00+00',        '2004-06-29 00:00:00+00',       '2004-06-30 00:00:00+00',      '2004-07-01 00:00:00+00',        '2004-07-02 00:00:00+00',       '2004-07-03 00:00:00+00',      '2004-07-04 00:00:00+00',        '2004-07-05 00:00:00+00',       '2004-07-06 00:00:00+00',      '2004-07-07 00:00:00+00',        '2004-07-08 00:00:00+00',       '2004-07-09 00:00:00+00',      '2004-07-10 00:00:00+00',        '2004-07-11 00:00:00+00',       '2004-07-12 00:00:00+00',      '2004-07-13 00:00:00+00',        '2004-07-14 00:00:00+00',       '2004-07-15 00:00:00+00',      '2004-07-16 00:00:00+00',        '2004-07-17 00:00:00+00',       '2004-07-18 00:00:00+00',      '2004-07-19 00:00:00+00',        '2004-07-20 00:00:00+00',       '2004-07-21 00:00:00+00',      '2004-07-22 00:00:00+00',        '2004-07-23 00:00:00+00',       '2004-07-24 00:00:00+00',      '2004-07-25 00:00:00+00',        '2004-07-26 00:00:00+00',       '2004-07-27 00:00:00+00',      '2004-07-28 00:00:00+00',        '2004-07-29 00:00:00+00',       '2004-07-30 00:00:00+00',      '2004-07-31 00:00:00+00',        '2004-08-01 00:00:00+00',       '2004-08-02 00:00:00+00',      '2004-08-03 00:00:00+00',        '2004-08-04 00:00:00+00',       '2004-08-05 00:00:00+00',      '2004-08-06 00:00:00+00',        '2004-08-07 00:00:00+00',       '2004-08-08 00:00:00+00',      '2004-08-09 00:00:00+00',        '2004-08-10 00:00:00+00',       '2004-08-11 00:00:00+00',      '2004-08-12 00:00:00+00',        '2004-08-13 00:00:00+00',       '2004-08-14 00:00:00+00',      '2004-08-15 00:00:00+00',        '2004-08-16 00:00:00+00',       '2004-08-17 00:00:00+00',      '2004-08-18 00:00:00+00',        '2004-08-19 00:00:00+00',       '2004-08-20 00:00:00+00',      '2004-08-21 00:00:00+00',        '2004-08-22 00:00:00+00',       '2004-08-23 00:00:00+00',      '2004-08-24 00:00:00+00',        '2004-08-25 00:00:00+00',       '2004-08-26 00:00:00+00',      '2004-08-27 00:00:00+00',        '2004-08-28 00:00:00+00',       '2004-08-29 00:00:00+00',      '2004-08-30 00:00:00+00',        '2004-08-31 00:00:00+00',       '2004-09-01 00:00:00+00',      '2004-09-02 00:00:00+00',        '2004-09-03 00:00:00+00',       '2004-09-04 00:00:00+00',      '2004-09-05 00:00:00+00',        '2004-09-06 00:00:00+00',       '2004-09-07 00:00:00+00',      '2004-09-08 00:00:00+00',        '2004-09-09 00:00:00+00',       '2004-09-10 00:00:00+00',      '2004-09-11 00:00:00+00',        '2004-09-12 00:00:00+00',       '2004-09-13 00:00:00+00',      '2004-09-14 00:00:00+00',        '2004-09-15 00:00:00+00',       '2004-09-16 00:00:00+00',      '2004-09-17 00:00:00+00',        '2004-09-18 00:00:00+00',       '2004-09-19 00:00:00+00',      '2004-09-20 00:00:00+00',        '2004-09-21 00:00:00+00',       '2004-09-22 00:00:00+00',      '2004-09-23 00:00:00+00',        '2004-09-24 00:00:00+00',       '2004-09-25 00:00:00+00',      '2004-09-26 00:00:00+00',        '2004-09-27 00:00:00+00',       '2004-09-28 00:00:00+00',      '2004-09-29 00:00:00+00',        '2004-09-30 00:00:00+00',       '2004-10-01 00:00:00+00',      '2004-10-02 00:00:00+00',        '2004-10-03 00:00:00+00',       '2004-10-04 00:00:00+00',      '2004-10-05 00:00:00+00',        '2004-10-06 00:00:00+00',       '2004-10-07 00:00:00+00',      '2004-10-08 00:00:00+00',        '2004-10-09 00:00:00+00',       '2004-10-10 00:00:00+00',      '2004-10-11 00:00:00+00',        '2004-10-12 00:00:00+00',       '2004-10-13 00:00:00+00',      '2004-10-14 00:00:00+00',        '2004-10-15 00:00:00+00',       '2004-10-16 00:00:00+00',      '2004-10-17 00:00:00+00',        '2004-10-18 00:00:00+00',       '2004-10-19 00:00:00+00',      '2004-10-20 00:00:00+00',        '2004-10-21 00:00:00+00',       '2004-10-22 00:00:00+00',      '2004-10-23 00:00:00+00',        '2004-10-24 00:00:00+00',       '2004-10-25 00:00:00+00',      '2004-10-26 00:00:00+00',        '2004-10-27 00:00:00+00',       '2004-10-28 00:00:00+00',      '2004-10-29 00:00:00+00',        '2004-10-30 00:00:00+00',       '2004-10-31 00:00:00+00',      '2004-11-01 00:00:00+00',        '2004-11-02 00:00:00+00',       '2004-11-03 00:00:00+00',      '2004-11-04 00:00:00+00',        '2004-11-05 00:00:00+00',       '2004-11-06 00:00:00+00',      '2004-11-07 00:00:00+00',        '2004-11-08 00:00:00+00',       '2004-11-09 00:00:00+00',      '2004-11-10 00:00:00+00',        '2004-11-11 00:00:00+00',       '2004-11-12 00:00:00+00',      '2004-11-13 00:00:00+00',        '2004-11-14 00:00:00+00',       '2004-11-15 00:00:00+00',      '2004-11-16 00:00:00+00',        '2004-11-17 00:00:00+00',       '2004-11-18 00:00:00+00',      '2004-11-19 00:00:00+00',        '2004-11-20 00:00:00+00',       '2004-11-21 00:00:00+00',      '2004-11-22 00:00:00+00',        '2004-11-23 00:00:00+00',       '2004-11-24 00:00:00+00',      '2004-11-25 00:00:00+00',        '2004-11-26 00:00:00+00',       '2004-11-27 00:00:00+00',      '2004-11-28 00:00:00+00',        '2004-11-29 00:00:00+00',       '2004-11-30 00:00:00+00',      '2004-12-01 00:00:00+00',        '2004-12-02 00:00:00+00',       '2004-12-03 00:00:00+00',      '2004-12-04 00:00:00+00',        '2004-12-05 00:00:00+00',       '2004-12-06 00:00:00+00',      '2004-12-07 00:00:00+00',        '2004-12-08 00:00:00+00',       '2004-12-09 00:00:00+00',      '2004-12-10 00:00:00+00',        '2004-12-11 00:00:00+00',       '2004-12-12 00:00:00+00',      '2004-12-13 00:00:00+00',        '2004-12-14 00:00:00+00',       '2004-12-15 00:00:00+00',      '2004-12-16 00:00:00+00',        '2004-12-17 00:00:00+00',       '2004-12-18 00:00:00+00',      '2004-12-19 00:00:00+00',        '2004-12-20 00:00:00+00',       '2004-12-21 00:00:00+00',      '2004-12-22 00:00:00+00',        '2004-12-23 00:00:00+00',       '2004-12-24 00:00:00+00',      '2004-12-25 00:00:00+00',        '2004-12-26 00:00:00+00',       '2004-12-27 00:00:00+00',      '2004-12-28 00:00:00+00',        '2004-12-29 00:00:00+00',       '2004-12-30 00:00:00+00',      '2004-12-31 00:00:00+00',        '2005-01-01 00:00:00+00',       '2005-01-02 00:00:00+00',      '2005-01-03 00:00:00+00',        '2005-01-04 00:00:00+00',       '2005-01-05 00:00:00+00',      '2005-01-06 00:00:00+00',        '2005-01-07 00:00:00+00',       '2005-01-08 00:00:00+00',      '2005-01-09 00:00:00+00',        '2005-01-10 00:00:00+00',       '2005-01-11 00:00:00+00',      '2005-01-12 00:00:00+00',        '2005-01-13 00:00:00+00',       '2005-01-17 00:00:00+00',      '2005-01-18 00:00:00+00',        '2005-01-25 00:00:00+00',       '2005-01-26 00:00:00+00',      '2005-01-28 00:00:00+00',        '2005-01-29 00:00:00+00',       '2005-01-31 00:00:00+00',      '2005-02-08 00:00:00+00',        '2005-02-09 00:00:00+00',       '2005-02-10 00:00:00+00',      '2005-02-11 00:00:00+00',        '2005-02-12 00:00:00+00',       '2005-02-13 00:00:00+00',      '2005-02-14 00:00:00+00',        '2005-02-15 00:00:00+00',       '2005-02-16 00:00:00+00',      '2005-02-17 00:00:00+00',        '2005-02-18 00:00:00+00',       '2005-02-19 00:00:00+00',      '2005-02-20 00:00:00+00',        '2005-02-21 00:00:00+00',       '2005-02-22 00:00:00+00',      '2005-02-23 00:00:00+00',        '2005-02-24 00:00:00+00',       '2005-02-25 00:00:00+00',      '2005-02-26 00:00:00+00',        '2005-02-27 00:00:00+00',       '2005-02-28 00:00:00+00',      '2005-03-01 00:00:00+00',        '2005-03-02 00:00:00+00',       '2005-03-03 00:00:00+00',      '2005-03-04 00:00:00+00',        '2005-03-05 00:00:00+00',       '2005-03-06 00:00:00+00',      '2005-03-07 00:00:00+00',        '2005-03-08 00:00:00+00',       '2005-03-09 00:00:00+00',      '2005-03-10 00:00:00+00',        '2005-03-11 00:00:00+00',       '2005-03-12 00:00:00+00',      '2005-03-13 00:00:00+00',        '2005-03-14 00:00:00+00',       '2005-03-15 00:00:00+00',      '2005-03-16 00:00:00+00',        '2005-03-17 00:00:00+00',       '2005-03-18 00:00:00+00',      '2005-03-19 00:00:00+00',        '2005-03-20 00:00:00+00',       '2005-03-21 00:00:00+00',      '2005-03-22 00:00:00+00',        '2005-03-23 00:00:00+00',       '2005-03-24 00:00:00+00',      '2005-03-25 00:00:00+00',        '2005-03-26 00:00:00+00',       '2005-03-27 00:00:00+00',      '2005-03-28 00:00:00+00',        '2005-03-29 00:00:00+00',       '2005-03-30 00:00:00+00',      '2005-03-31 00:00:00+00',        '2005-04-01 00:00:00+00',       '2005-04-02 00:00:00+00',      '2005-04-03 00:00:00+00',        '2005-04-04 00:00:00+00',       '2005-04-05 00:00:00+00',      '2005-04-06 00:00:00+00',        '2005-04-07 00:00:00+00',       '2005-04-08 00:00:00+00',      '2005-04-09 00:00:00+00',        '2005-04-10 00:00:00+00',       '2005-04-11 00:00:00+00',      '2005-04-12 00:00:00+00',        '2005-04-13 00:00:00+00',       '2005-04-14 00:00:00+00',      '2005-04-15 00:00:00+00',        '2005-04-16 00:00:00+00',       '2005-04-17 00:00:00+00',      '2005-04-18 00:00:00+00',        '2005-04-19 00:00:00+00',       '2005-04-20 00:00:00+00',      '2005-04-21 00:00:00+00',        '2005-04-22 00:00:00+00',       '2005-04-23 00:00:00+00',      '2005-04-24 00:00:00+00',        '2005-04-25 00:00:00+00',       '2005-04-26 00:00:00+00',      '2005-04-27 00:00:00+00',        '2005-04-28 00:00:00+00',       '2005-04-29 00:00:00+00',      '2005-04-30 00:00:00+00',        '2005-05-01 00:00:00+00',       '2005-05-02 00:00:00+00',      '2005-05-03 00:00:00+00',        '2005-05-04 00:00:00+00',       '2005-05-05 00:00:00+00',      '2005-05-06 00:00:00+00',        '2005-05-07 00:00:00+00',       '2005-05-08 00:00:00+00',      '2005-05-09 00:00:00+00',        '2005-05-10 00:00:00+00',       '2005-05-11 00:00:00+00',      '2005-05-12 00:00:00+00',        '2005-05-13 00:00:00+00',       '2005-05-14 00:00:00+00',      '2005-05-15 00:00:00+00',        '2005-05-16 00:00:00+00',       '2005-05-17 00:00:00+00',      '2005-05-18 00:00:00+00',        '2005-05-19 00:00:00+00',       '2005-05-20 00:00:00+00',      '2005-05-21 00:00:00+00',        '2005-05-22 00:00:00+00',       '2005-05-23 00:00:00+00',      '2005-05-24 00:00:00+00',        '2005-05-25 00:00:00+00',       '2005-05-26 00:00:00+00',      '2005-05-27 00:00:00+00',        '2005-05-28 00:00:00+00',       '2005-05-29 00:00:00+00',      '2005-05-30 00:00:00+00',        '2005-05-31 00:00:00+00',       '2005-06-01 00:00:00+00',      '2005-06-02 00:00:00+00',        '2005-06-03 00:00:00+00',       '2005-06-04 00:00:00+00',      '2005-06-05 00:00:00+00',        '2005-06-06 00:00:00+00',
+  );
+my @obsepoch = (81.8670764502497,       42.4188998589563,       100,    99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       100,    99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.6528982992017,       100,    99.9652898299202,       99.9652898299202,       99.9652898299202,      99.9652898299202,        100,    100,    100,    100,    100,    100,    100,    100,    100,   100,     100,    100,    100,    100,    100,    100,    100,    100,    100,    100,    100,   100,     100,    100,    100,    100,    100,    100,    100,    99.6180555555556,       100,   100,     100,    100,    100,    100,    99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652777777778,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.7223186393613,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9306037473976,       99.9306037473976,       99.9652898299202,       99.7570288094412,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9306037473976,       99.9306037473976,       99.9306037473976,       99.9652898299202,       99.9652898299202,       99.9652898299202,       99.9306037473976,       99.9306037473976,       99.9306037473976,       99.9306037473976,       99.9306037473976,       99.9306037473976,       99.9306037473976,       99.9306037473976,       94.5176960444136,       100,    98.125, 100,    100,    100,    100,    100,   99.4444444444444,        100,    100,    100,    100,    100,    100,    100,    100,    100,   99.9652777777778,        100,    100,    100,    100,    100,    100,    100,    100,    100,   100,     100,    100,    100,    100,    100,    100,    100,    100,    100,    100,    100,   100,     100,    99.6180555555556,       100,    100,    100,    100,    100,    100,    100,   100,     99.6527777777778,       100,    100,    100,    100,    100,    100,    94.9494949494949,       100,    100,    100,    100,    100,    100,    100,    100,    100,    100,    100,   100,     100,    100,    100,    100,    100,    100,    100,    100,    100,    100,    100,   100,     100,    100,    100,    99.965241571081,        99.930483142162,        99.860966284324,99.8262078554049,       99.7914494264859,       99.7566063977747,       99.6870653685674,      99.6175243393602,        99.547983310153,        99.4784422809458,       99.3741307371349,      99.5138888888889,        100,    100,    100,    100,    100,    100,    100,    100,    100,   100,     100,    100,    100,    100,    100,    100,    100,    100,    100,    100,    100,   100,     100,    100,    100,    100,    100,    100,    100,    100,    100,    100,    100,   100,     100,    100,    100,    100,    100,    100,    100,    100,    100,    100,    100,   100,     100,    100,    100,    100,    100,    100,    100,    100,    100,    100,    100,   100,     100,    100,    100,    100,    100,    100,    100,    100,    100,    100,    100,   100,     100,    100,    100,    100,    100,    100,    100,    100,    100,    100,    100,);
+
+my $g = Chart::LinesPoints->new (700, 450);
+#my  $g = Chart::Lines->new(700,450);
+
+$g-> add_dataset ( @bezugszeitraum );
+$g-> add_dataset ( @obsepoch );
+	 
+$g-> set ('x_ticks' => 'vertical');
+$g-> set ('x_label' => ' Time');
+$g-> set ('y_label' => 'actual_nr_of_obsepoch / possible_nr');
+$g-> set ('legend' => 'none');
+$g-> set ('precision' => 0);
+$g-> set ('title' => 'DRES');
+$g-> set ('grey_background' => 'false');
+$g-> set ('max_val' => '100');
+$g-> set ('min_val' => '80');
+$g-> set ('pt_size' => '10');
+$g-> set ('brush_size' => '4');
+$g-> set ('skip_x_ticks' => '50');
+
+$g-> png ("samples/linespoints_6.png");
+print "ok 1\n\n";
+	  
+	  

Added: packages/libchart-perl/branches/upstream/current/t/linespoints_7.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/linespoints_7.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/linespoints_7.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,35 @@
+#!/usr/bin/perl -w
+
+use strict;
+use Chart::LinesPoints;
+use Chart::Lines;
+
+print "1..1\n";
+
+
+my @bezugszeitraum = ('2004-06-13 00:00:00+00',       '2004-06-14 00:00:00+00',       '2004-06-15 00:00:00+00',      '2004-06-16 00:00:00+00',        '2004-06-17 00:00:00+00');
+
+my @obsepoch =       (81.8670764502497,       42.4188998589563,       100,    0.9652898299202,       12.9652898299202);
+
+my $g = Chart::LinesPoints->new (700, 450);
+#my  $g = Chart::Lines->new(700,450);
+
+$g-> add_dataset ( @bezugszeitraum );
+$g-> add_dataset ( @obsepoch );
+	 
+$g-> set ('x_ticks' => 'staggered');
+$g-> set ('x_label' => ' Time');
+$g-> set ('y_label' => 'actual_nr_of_obsepoch / possible_nr');
+$g-> set ('legend' => 'none');
+$g-> set ('precision' => 0);
+$g-> set ('title' => 'Station Test');
+$g-> set ('grey_background' => 'false');
+$g-> set ('max_val' => '100');
+$g-> set ('min_val' => '0');
+$g-> set ('pt_size' => '10');
+$g-> set ('brush_size' => '3');
+$g-> set ('stepline' => 'true');
+
+$g-> png ("samples/linespoints_7.png");
+print "ok 1\n\n";
+	  

Added: packages/libchart-perl/branches/upstream/current/t/mapbars.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/mapbars.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/mapbars.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,55 @@
+use strict;
+use Chart::Bars;
+ 
+my $png_name     = 'samples/mapbars.png';
+my @legend_keys  = ( "Actual ","Goal" );
+ 
+my $Graph = new Chart::Bars(600,400);
+
+print "1..1\n";
+ 
+$Graph->add_dataset("Oct 01", "Nov 01", "Dec 01", "Jan 02", "Feb 02", "Mar
+02" );
+$Graph->add_dataset( 95.1, 84.4, 90.2, 94.4, 93.8, 95.5 );
+$Graph->add_dataset( 93.0, 83.0, 94.0, 94.0, 94.0, 94.0 );
+ 
+$Graph->set(
+            composite_info  => [ [ 'Bars',  [ 1 ] ],
+                                 [ 'Lines', [ 2 ] ] ],
+            colors           => { dataset0   => 'green',
+                                  dataset1   => 'red' },
+            title_font       => GD::Font->Giant,
+            label_font       => GD::Font->Small,
+            legend_font      => GD::Font->Large,
+            tick_label_font  => GD::Font->Large,
+            grid_lines       => 'true',
+            graph_border     => 0,
+            imagemap         => 'true',
+            legend           => 'bottom',
+            legend_labels    => \@legend_keys,
+            max_val          => 100,
+            min_val          => 80,
+            png_border       => 4,
+            same_y_axes      => 'true',
+            spaced_bars      => 'true',
+            title            => "Yield 2004",
+            text_space       => 5,
+            transparent      => 'true',
+            x_ticks          => 'vertical',
+            integer_ticks_only => 'true',
+            skip_int_ticks     => 5,
+            );
+ 
+$Graph->png( "$png_name" );
+ 
+my $imagemap_data = $Graph->imagemap_dump();
+ 
+foreach my $ds ( 1 .. 1 ) {
+    foreach my $pt ( 0 .. 5 ) {
+         my @i = @{$imagemap_data->[$ds]->[$pt]};     # **
+        print "Dataset:$ds - Point: $pt  ----  VALUES: @i \n";
+    }
+}
+print "ok 1\n";
+
+exit 0;

Added: packages/libchart-perl/branches/upstream/current/t/mapcomp.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/mapcomp.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/mapcomp.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,57 @@
+use strict;
+use Chart::Composite;
+
+my $png_name     = 'samples/mapcomp.png';
+my @legend_keys  = ( "Actual ","Goal" );
+# 
+my $Graph = new Chart::Composite(600,400);
+
+print "1..1\n";
+# 
+$Graph->add_dataset("Oct 01", "Nov 01", "Dec 01", "Jan 02", "Feb 02", "Mar 02" );
+$Graph->add_dataset( 95.1, 84.4, 90.2, 94.4, 93.8, 95.5 );
+$Graph->add_dataset( 93.0, 83.0, 94.0, 94.0, 94.0, 94.0 );
+# 
+$Graph->set(
+            composite_info  => [ [ 'Bars',  [ 1 ] ],
+                                 [ 'Lines', [ 2 ] ] ],
+            colors           => { dataset0   => 'green',
+                                  dataset1   => 'red' },
+            title_font       => GD::Font->Giant,
+            label_font       => GD::Font->Small,
+            legend_font      => GD::Font->Large,
+            tick_label_font  => GD::Font->Large,
+            grid_lines       => 'true',
+            graph_border     => 0,
+            imagemap         => 'true',
+            legend           => 'bottom',
+            legend_labels    => \@legend_keys,
+            max_val          => 100,
+            min_val          => 80,
+            png_border       => 4,
+            same_y_axes      => 'true',
+            spaced_bars      => 'true',
+            title            => "Yield 2004",
+            text_space       => 5,
+            transparent      => 'true',
+            x_ticks          => 'vertical',
+            integer_ticks_only => 'true',
+            skip_int_ticks     => 5,
+            );
+
+$Graph->png( "$png_name" );
+# 
+my $imagemap_data = $Graph->imagemap_dump();
+# 
+foreach my $ds ( 1 .. 1 ) {
+    foreach my $pt ( 0 .. 5 ) {
+        if ( defined($imagemap_data->[$ds]->[$pt]) ) {
+           my @i = @{$imagemap_data->[$ds]->[$pt]};     # **
+           print "Dataset:$ds - Point: $pt  ----  VALUES: @i \n";
+        }
+    }
+}
+ 
+print "ok\n";
+
+exit 0;

Added: packages/libchart-perl/branches/upstream/current/t/mountain.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/mountain.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/mountain.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,56 @@
+#!/usr/bin/perl -w
+
+use Chart::Mountain;         
+use File::Spec;
+
+print "1..2\n";
+
+my @data = ( 
+	["1st","2nd","3rd","4th","5th","6th","7th", "8th", "9th"],
+	[    3,    7,    8,    2,    4,  8.5,    2,     5,     9],
+	[    4,    2,    5,    6,    3,  2.5,    3,     3,     4],
+	[    7,    3,    2,    8,  8.5,    2,    9,     4,     5],
+);
+
+my @hex_colors = qw(0099FF 00CC00 FFCC33 FF0099 3333FF);
+my @colors = map { [ map { hex($_) } unpack("a2 a2 a2", $_) ] } @hex_colors; 
+
+my @patterns = ();
+foreach (1.. at data-1) { 
+	open(PNG, '<'.File::Spec->catfile(File::Spec->curdir, 'patterns', "PATTERN$_.PNG")) || die "Can't load pattern $_";
+	push(@patterns, GD::Image->newFromPng(\*PNG));
+	close(PNG);
+}
+
+my @opts = (
+	{},
+	{
+		'x_label' 		=> 'X Label',
+		'y_label' 		=> 'Y label',
+		'title' 		=> 'Mountain Chart',
+		'grid_lines'	=> 'true',
+		'colors'		=> { map { ( "dataset$_" => $colors[$_] ) } 0.. at colors-1 },
+	},
+	{
+		'x_label' 		=> 'X Label',
+		'y_label' 		=> 'Y label',
+		'title' 		=> 'Mountain Chart with Patterns',
+		'grid_lines'	=> 'true',
+		'colors'		=> { map { ( "dataset$_" => $colors[$_] ) } 0.. at colors-1 },
+		'patterns'		=> \@patterns,
+	},
+);
+
+foreach my $i (1.. at opts-1)
+{
+	my $newpath = File::Spec->catfile(File::Spec->curdir, 'samples', "mountain-$i.png");
+	my $opts = $opts[$i];
+	my $g = new Chart::Mountain( );
+	$g->set( %$opts );
+	my $Image = $g->png( $newpath, \@data );
+	print "ok $i\n";
+}
+
+
+exit (0);
+

Added: packages/libchart-perl/branches/upstream/current/t/mountain_2.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/mountain_2.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/mountain_2.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,61 @@
+#!/usr/bin/perl -w
+
+use Chart::Mountain;         
+use File::Spec;
+
+print "1..2\n";
+
+my $a=(10**(-6));
+
+my @data = ( 
+	["1st","2nd","3rd","4th","5th","6th","7th", "8th", "9th"],
+	[    (3*$a),    (7*$a),    (8*$a),    (2*$a),    (4*$a),  (8.5*$a),    (2*$a),     (5*$a),     (9*$a)],
+	[    (4*$a),    (2*$a),    (5*$a),    (6*$a),    (3*$a),  (2.5*$a),    (3*$a),     (3*$a),     (4*$a)],
+	[    (7*$a),    (3*$a),    (2*$a),    (8*$a),  (8.5*$a),    (2*$a),    (9*$a),     (4*$a),     (5*$a)],
+);
+
+my @hex_colors = qw(0099FF 00CC00 FFCC33 FF0099 3333FF);
+my @colors = map { [ map { hex($_) } unpack("a2 a2 a2", $_) ] } @hex_colors; 
+
+my @patterns = ();
+foreach (1.. at data-1) { 
+	open(PNG, '<'.File::Spec->catfile(File::Spec->curdir, 'patterns', "PATTERN$_.PNG")) || die "Can't load pattern $_";
+	push(@patterns, GD::Image->newFromPng(\*PNG));
+	close(PNG);
+}
+
+my @opts = (
+	{},
+	{
+		'x_label' 		=> 'X Label',
+		'y_label' 		=> 'Y label',
+		'title' 		=> 'Mountain Chart',
+		'grid_lines'	        => 'true',
+		'colors'		=> { map { ( "dataset$_" => $colors[$_] ) } 0.. at colors-1 },
+		'precision'             => 6,
+		#'integer_ticks_only'      => 'true',
+	},
+	{
+		'x_label' 		=> 'X Label',
+		'y_label' 		=> 'Y label',
+		'title' 		=> 'Mountain Chart with Patterns',
+		'grid_lines'	        => 'true',
+		'colors'		=> { map { ( "dataset$_" => $colors[$_] ) } 0.. at colors-1 },
+		'patterns'		=> \@patterns,
+		'precision'             => 5,
+	},
+);
+
+foreach my $i (1.. at opts-1)
+{
+	my $newpath = File::Spec->catfile(File::Spec->curdir, 'samples', "mountain_2-$i.png");
+	my $opts = $opts[$i];
+	my $g = new Chart::Mountain( );
+	$g->set( %$opts );
+	my $Image = $g->png( $newpath, \@data );
+	print "ok $i\n";
+}
+
+
+exit (0);
+

Added: packages/libchart-perl/branches/upstream/current/t/pareto_1.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/pareto_1.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/pareto_1.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,39 @@
+#!/usr/bin/perl -w
+
+
+use Chart::Pareto;
+
+print "1..1\n";
+
+$g = Chart::Pareto->new(450,400);
+$g->add_dataset ('Mo', 'Tue', 'We', 'Th', 'Fr', 'Sa', 'Su');
+$g->add_dataset (2500, 1000, 250 , 700, 100, 610, 20);
+
+%hash =(
+         'colors' => {
+                       'dataset0' => 'green',
+                       'dataset1' => 'red',
+                       'x_label' => 'red',
+                       'y_grid_lines' => 'white',
+                       'title' => 'blue',
+                     },
+         'title' => 'Sold Tickets for Beethovens 9th\n ',
+         'integer_ticks_only' => 'true',
+         'skip_int_ticks' => 250,
+         'sort' => 'true',
+         'max_val' => 5500,
+         'y_grid_lines' => 'true',
+         'y_label' => 'Sold Tickets',
+         'x_label' => '! sold out in the first week !',
+ 	 'spaced_bars' => 'false',
+
+         'legend' => 'none',
+        );
+	
+$g->set ( %hash); 
+$g->png ("samples/pareto_1.png");
+
+print "ok 1\n";
+
+exit (0);
+


Property changes on: packages/libchart-perl/branches/upstream/current/t/pareto_1.t
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/t/pareto_2.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/pareto_2.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/pareto_2.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,34 @@
+use Chart::Pareto;
+
+print "1..1\n";
+
+$g = Chart::Pareto->new(500,400);
+$g->add_dataset ('1st week', '2nd week', '3rd week', '4th week', '5th week',
+                 '6th week', '7th week', '8th week', '9th week', '10th week');
+$g->add_dataset (37, 15, 9 , 4, 3.5,
+                  2.1, 1.2, 1.5, 6.2, 16);
+
+%hash =(
+         'colors' => {
+                       'dataset0' => 'mauve',
+                       'dataset1' => 'light_blue',
+                       'title' => 'orange',
+                     },
+         'title' => 'Visitors at the Picasso Exhibition',
+         'integer_ticks_only' => 'true',
+         'skip_int_ticks' => 5,
+         'grey_background' => 'false',
+         'max_val' => 100,
+         'y_label' => 'Visitors in Thousands',
+         'x_ticks' => 'vertical',
+ 	 'spaced_bars' => 'true',
+         'legend' => 'none',
+        );
+	
+$g->set ( %hash); 
+$g->png ("samples/pareto_2.png");
+
+print "ok 1\n";
+
+exit (0);
+


Property changes on: packages/libchart-perl/branches/upstream/current/t/pareto_2.t
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/t/pareto_3.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/pareto_3.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/pareto_3.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,39 @@
+#!/usr/bin/perl -w
+
+
+use Chart::Pareto;
+
+print "1..1\n";
+
+$g = Chart::Pareto->new(450,400);
+$g->add_dataset ('Mo', 'Tue', 'We', 'Th', 'Fr', 'Sa', 'Su');
+$g->add_dataset (3000, 1600, 1500 , 400, 100, 20, 5);
+
+
+%hash =(
+         'colors' => {
+                       'dataset0' => 'green',
+                       'dataset1' => 'red',
+                       'x_label' => 'red',
+                       'y_grid_lines' => 'white',
+                       'title' => 'blue',
+                     },
+         'title' => 'Pareto Chart ',
+         'integer_ticks_only' => 'true',
+	 'precision' => 0,
+         'skip_int_ticks' => 400,
+         'sort' => 'true',
+        # 'max_val' => 6800,
+         'y_grid_lines' => 'true',
+	 'spaced_bars' => 'false',
+
+         'legend' => 'none',
+        );
+	
+$g->set ( %hash); 
+$g->png ("samples/pareto_3.png");
+
+print "ok 1\n";
+
+exit (0);
+

Added: packages/libchart-perl/branches/upstream/current/t/pie_1.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/pie_1.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/pie_1.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,32 @@
+#!/usr/bin/perl -w
+
+use Chart::Pie;
+use strict;
+
+print "1..1\n";
+
+my $g = Chart::Pie->new(550,500);
+$g->add_dataset ('The Red', 'The Black', 'The Yellow', 'The Brown', 'The Green');
+$g->add_dataset (430, 411 , 50, 10, 100);
+
+$g->set ('title' => 'The Parlament');
+$g->set ('label_values' => 'percent');
+$g->set ('legend_label_values' => 'value');
+$g->set ('legend' => 'top');
+$g->set ('grey_background' => 'false');
+$g->set ('x_label' => 'seats in the parlament');
+$g->set ('colors' => {'misc' => 'light_blue',
+                      'background' => 'lavender',
+	 	      'dataset0' => 'red',
+                      'dataset1' => 'black',
+                      'dataset2' => [210,210,0],
+                      'dataset3' => 'DarkOrange',
+                      'dataset4' => 'green'
+              	      });
+$g->set('legend_lines'=>'true');
+         
+$g->png ("samples/pie_1.png");
+print "ok 1\n";
+
+exit (0);
+


Property changes on: packages/libchart-perl/branches/upstream/current/t/pie_1.t
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/t/pie_10.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/pie_10.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/pie_10.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,43 @@
+#!/usr/bin/perl -w
+
+use Chart::Pie;
+use strict;
+
+print "1..1\n";
+
+my $g = Chart::Pie->new(1000,1000);
+my @labels = ( 'Pending - 0 - 0.5 hour'
+              ,'Pending - 0.5 - 1 hour'
+              ,'Pending - 1 - 2 hours'
+              ,'Pending - 2 - 5 hours'
+              ,'Pending - 5 - 12 hours'
+              ,'Pending - 12 - 24 hours'
+              ,'Pending - 1 - 2 days'
+              ,'Pending - more than 2 days'
+              ,'Queued  - 0 - 0.5 hour'
+              ,'Queued  - 0.5 - 1 hour'
+              ,'Queued  - 1 - 2 hours'
+              ,'Queued  - 2 - 5 hours'
+              ,'Queued  - 5 - 12 hours'
+              ,'Queued  - 12 - 24 hours'
+              ,'Queued  - 1 - 2 days'
+              ,'Queued  - more than 2 days'
+              ,'Queued  - Future Delivery'
+             );
+$g->add_dataset(@labels);
+$g->add_dataset(40, 5, 12, 2, 4, 15, 20, 31, 1, 25, 40, 40, 40, 1, 0, 2, 20);
+
+$g->set ('title' => 'Pie Demo Chart');
+$g->set ('label_values' => 'percent');
+$g->set ('legend_label_values' => 'value');
+$g->set ('legend' => 'right');
+$g->set ('grey_background' => 'false');
+$g->set ('legend_lines' => 'true');
+
+
+         
+$g->png ("samples/pie_10.png");
+print "ok 1\n";
+
+exit (0);
+

Added: packages/libchart-perl/branches/upstream/current/t/pie_2.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/pie_2.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/pie_2.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,25 @@
+#!/usr/bin/perl -w
+
+use Chart::Pie;
+use strict;
+my $g;
+
+print "1..1\n";
+
+$g = Chart::Pie->new(530,330);
+
+$g->add_dataset ('Harry', 'Sally', 'Eve', 'Mark', 'John', 'Susan', 'Alex', 'Tony' , 'Kimberly', 'Theresa');
+$g->add_dataset (12, 20 , 12, 15, 8, 9, 22, 14, 8, 13 );
+
+$g->set ('title' => 'Pie Demo');
+$g->set ('label_values' => 'none');
+$g->set ('legend_label_values' => 'percent');
+$g->set ('grey_background' => 'false');
+$g->set ('colors' => {'title' => 'red'});
+$g->set ('legend_lines' => 'true');
+         
+$g->png ("samples/pie_2.png");
+print "ok 1\n";
+
+exit (0);
+


Property changes on: packages/libchart-perl/branches/upstream/current/t/pie_2.t
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/t/pie_3.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/pie_3.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/pie_3.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,36 @@
+#!/usr/bin/perl -w
+
+use Chart::Pie;
+
+print "1..1\n";
+
+$g = Chart::Pie->new(500,500);
+
+$g->add_dataset ('Har', 'Sug', 'Ert', 'Her', 'Tar', 'Kure');
+$g->add_dataset (12000, 20000 , 13000, 15000, 9000, 11000  );
+
+%opt = ( 'title' => 'Another Pie Demo Chart',
+         'label_values' => 'both',
+         'legend' => 'none',
+         'text_space' => 10,
+         'png_border' => 1,
+         'graph_border' => 0,
+         'colors' => { 'x_label' => 'red',
+                       'misc' => 'plum',
+                       'background' => 'grey',
+                       'dataset0' => [120, 0, 255],
+                       'dataset1' => [120, 100, 255],
+                       'dataset2' => [120, 200, 255],
+                       'dataset3' => [255, 100, 0],
+                       'dataset4' => [255, 50, 0],
+                       'dataset5' => [255, 0, 0],
+                     },
+         'x_label' => 'The Winner is Team Blue!',
+        );
+
+$g->set (%opt);
+
+$g->png ("samples/pie_3.png");
+
+print "ok 1\n";
+exit (0);


Property changes on: packages/libchart-perl/branches/upstream/current/t/pie_3.t
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/t/pie_4.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/pie_4.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/pie_4.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,30 @@
+#!/usr/bin/perl -w
+
+use Chart::Pie;
+use GD;
+use strict;
+
+print "1..1\n";
+
+my $g = Chart::Pie->new(500,450);
+$g->add_dataset('eins', 'zwei', 'drei', 'vier', 'fuenf', 'sechs', 'sieben', 'acht', 'neun', 'zehn');
+$g->add_dataset(120, 50, 100, 80, 40, 45, 150, 60, 110, 50); 
+
+
+
+$g->set ('title' => 'Pie\nDemo Chart');
+$g->set ('sub_title' => 'True Type Fonts');
+$g->set ('label_values' => 'percent');
+$g->set ('legend_label_values' => 'value');
+$g->set ('legend' => 'bottom');
+$g->set ('grey_background' => 'false');
+$g->set ('x_label' => '');
+$g->set ('legend_font' => gdSmallFont);
+$g->set ('title_font' => gdGiantFont);
+$g->set ('legend_lines' => 'false');
+         
+$g->png ("samples/pie_4.png");
+print "ok 1\n";
+
+exit (0);
+

Added: packages/libchart-perl/branches/upstream/current/t/pie_5.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/pie_5.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/pie_5.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,29 @@
+#!/usr/bin/perl -w
+
+use Chart::Pie;
+use strict;
+
+print "1..1\n";
+
+my $g = Chart::Pie->new(550,500);
+$g->add_dataset ('eins', 'zwei', 'drei', 'vier');
+$g->add_dataset (25, 30, 250, 50);
+
+$g->set ('title' => 'Pie Demo Chart');
+$g->set ('label_values' => 'percent');
+$g->set ('legend_label_values' => 'value');
+$g->set ('legend' => 'bottom');
+$g->set ('grey_background' => 'false');
+$g->set ('x_label' => '');
+$g->set ('colors' => {'misc' => 'light_blue',
+                      'dataset1' => 'red',
+                      'dataset2' => 'blue',
+		      'dataset0' => 'yellow',
+                      'dataset3' => 'green'
+              	      });
+         
+$g->png ("samples/pie_5.png");
+print "ok 1\n";
+
+exit (0);
+

Added: packages/libchart-perl/branches/upstream/current/t/pie_6.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/pie_6.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/pie_6.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,27 @@
+#!/usr/bin/perl -w
+use Chart::Pie;
+
+print "1..1\n";
+
+$g = Chart::Pie->new(500,400);
+#$g = Chart::Pie->new;
+
+$g->add_dataset ('Free', 'Reserved', 'Deactivated', 'Leased', 'Unavailable');
+$g->add_dataset (36, 0 , 1, 216, 0);
+
+%opt = ( 'label_values' => 'none',
+	 'legend_label_values' => 'both',
+         'legend' => 'right',
+         'text_space' => 10,
+         'png_border' => 1,
+         'graph_border' => 0,
+	 'grey_background' => 'false',
+	 'x_label' => 'Total IPs In Scope 253',
+        );
+
+$g->set (%opt);
+
+$g->png ("samples/pie_6.png");
+
+print "ok 1\n";
+exit (0);

Added: packages/libchart-perl/branches/upstream/current/t/pie_7.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/pie_7.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/pie_7.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,27 @@
+#!/usr/bin/perl -w
+
+use Chart::Pie;
+use GD;
+use strict;
+
+print "1..1\n";
+
+my $g = Chart::Pie->new(500,450);
+$g->add_dataset('eins', 'zwei', 'drei', 'vier', 'fuenf', 'sechs', 'sieben', 'acht', 'neun', 'zehn');
+$g->add_dataset(40, 1, 12 , 37, 8, 50, 19, 23, 5, 90);
+
+
+$g->set ('title' => 'Pie\nDemo Chart');
+$g->set ('sub_title' => 'Ring_Pie');
+$g->set ('label_values' => 'value');
+$g->set ('legend_label_values' => 'value');
+$g->set ('legend' => 'bottom');
+$g->set ('x_label' => '');
+$g->set ('ring' => 0.1);
+$g->set ('colors' => {'background' => 'grey'});
+         
+$g->png ("samples/pie_7.png");
+print "ok 1\n";
+
+exit (0);
+

Added: packages/libchart-perl/branches/upstream/current/t/pie_8.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/pie_8.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/pie_8.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,32 @@
+#!/usr/bin/perl -w
+
+use Chart::Pie;
+use strict;
+
+print "1..1\n";
+
+my $g = Chart::Pie->new(550,500);
+$g->add_dataset ('eins', 'zwei', 'drei', 'vier');
+$g->add_dataset (25, 80, 120, 50);
+
+
+$g->set ('title' => 'Pie Demo Chart');
+$g->set ('label_values' => 'percent');
+$g->set ('legend_label_values' => 'value');
+$g->set ('legend' => 'bottom');
+$g->set ('grey_background' => 'false');
+$g->set ('ring' => 0.9);
+$g->set ('legend_lines' => 'true');
+$g->set ('x_label' => '');
+$g->set ('colors' => {'misc' => 'light_blue',
+                      'dataset1' => 'red',
+                      'dataset2' => 'blue',
+		      'dataset0' => 'yellow',
+                      'dataset3' => 'green'
+              	      });
+         
+$g->png ("samples/pie_8.png");
+print "ok 1\n";
+
+exit (0);
+

Added: packages/libchart-perl/branches/upstream/current/t/pie_9.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/pie_9.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/pie_9.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,26 @@
+#!/usr/bin/perl -w
+
+use Chart::Pie;
+use strict;
+
+print "1..1\n";
+
+my $g = Chart::Pie->new(550,500);
+$g->add_dataset ('eins', 'zwei', 'drei', 'vier');
+$g->add_dataset(0, 0, 0, 0);
+
+$g->set ('title' => 'Pie Demo Chart');
+$g->set ('sub_title' => 'Only a circle, as all values are zero');
+$g->set ('label_values' => 'percent');
+$g->set ('legend_label_values' => 'value');
+$g->set ('legend' => 'bottom');
+$g->set ('grey_background' => 'false');
+$g->set ('legend_lines' => 'false');
+
+
+         
+$g->png ("samples/pie_9.png");
+print "ok 1\n";
+
+exit (0);
+

Added: packages/libchart-perl/branches/upstream/current/t/points.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/points.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/points.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,28 @@
+#!/usr/bin/perl -w
+
+
+use Chart::Points;
+
+print "1..1\n";
+
+$g = Chart::Points->new;
+$g->add_dataset ('foo', 'bar', 'junk');
+$g->add_dataset (3, 4, 9);
+$g->add_dataset (8, 6, 0);
+$g->add_dataset (5, 7, 2);
+
+ at hash = ('title' => 'Points Chart',
+	 'type_style' => 'donut',
+	 'png_border' =>10,
+	 
+	 
+	 );
+
+$g->set (@hash);
+
+$g->png ("samples/points.png");
+
+print "ok 1\n";
+
+exit (0);
+

Added: packages/libchart-perl/branches/upstream/current/t/points_100.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/points_100.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/points_100.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,25 @@
+use Chart::Points;
+use strict;
+
+print "1..1\n";
+my $g;
+
+my @x;
+my @y;
+
+for ( my $i = 9; $i < 100; $i++) {
+   $x[$i] = $i;
+   $y[$i] = $i/10;
+}
+$g = Chart::Points->new;
+$g->add_dataset (@x);
+$g->add_dataset (@y);
+
+$g->set ('title' => 'Points Chart with 100 Points');
+$g->set ('skip_x_ticks'=> 10);
+$g->png ("samples/points_100.png");
+
+print "ok 1\n";
+
+exit (0);
+

Added: packages/libchart-perl/branches/upstream/current/t/points_2.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/points_2.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/points_2.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,34 @@
+#!/usr/bin/perl -w
+
+
+use Chart::Points;
+
+print "1..1\n";
+
+$g = Chart::Points->new;
+$g->add_dataset ('Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So');
+$g->add_dataset (-3,    0,    8,     4,    2,     1,   0 );
+$g->add_dataset ( 8,    0.12,   9,     2,    4,    -1,   3);
+$g->add_dataset ( 5,     -7,   12,    5,    7,     5,    8);
+$g->add_dataset (0, 0, 0, 0, 0, 0, 0);
+
+
+ at hash = ('title' => 'Points Chart',
+	# 'type_style' => 'donut',
+	 'png_border' =>10,
+	 'precision' => 0,
+	 'min_val' => 0, 
+	 #'max_val' => 0,
+	 'include_zero' => 'true',
+	 
+	 
+	 );
+
+$g->set (@hash);
+
+$g->png ("samples/points_2.png");
+
+print "ok 1\n";
+
+exit (0);
+

Added: packages/libchart-perl/branches/upstream/current/t/split_1.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/split_1.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/split_1.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,36 @@
+#!/usr/bin/perl -w
+
+use Chart::Split;
+use strict;
+print "1..1\n";
+
+my ($x, $y, @x, @y, %hash);
+my $g = Chart::Split->new();
+
+for (my $i = 0; $i < 60; $i += .05) {
+   $y = sin( $i);
+   $x = $i;
+   push @x, $x;
+   push @y, $y;
+}
+
+$g->add_dataset(@x);
+$g->add_dataset(@y);
+
+%hash = (
+          'start' => 0,
+          'interval' => 20,
+          'interval_ticks' => 21,
+          'brush_size' => 1,
+          'legend' => 'none',
+          'title' => 'f(x) = sin x',
+          'precision' => 0,
+          'y_grid_lines' => 'true',
+
+        );
+$g->set(%hash);
+
+$g->png("samples/split_1.png");
+print "ok 1\n";
+
+exit (0);


Property changes on: packages/libchart-perl/branches/upstream/current/t/split_1.t
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/t/split_2.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/split_2.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/split_2.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,38 @@
+#!/usr/bin/perl -w
+
+
+use Chart::Split;
+print "1..1\n";
+
+$g = Chart::Split->new(500,500);
+$last =0;
+
+# create arrays of data
+for (1..4000) {
+  srand(time()/$_*50);   #intialize the random number generator
+  $y1 = (rand(10))  ;    #generate the number
+  push (@x, $_);        #add the x-values
+  push (@y1, $y1);       #add the random number
+  push (@y2, abs($y1-$last));     #add the difference to the last number
+  $last = $y1;
+}
+
+$g->add_dataset(@x);
+$g->add_dataset(@y1);
+$g->add_dataset(@y2);
+
+%options = (
+            'start' => 0,
+            'interval' => 400,
+            'brush_size' => 1,
+            'interval_ticks' => 0,
+            'title' => "Random Numbers Test",
+            'legend_labels' => ['random numbers', 'difference'],
+            'x_label' => "4000 Random Numbers",
+            'legend' => 'bottom',
+            );
+$g->set(%options);
+$g->png("samples/split_2.png");
+print "ok 1\n";
+
+exit (0);


Property changes on: packages/libchart-perl/branches/upstream/current/t/split_2.t
___________________________________________________________________
Name: svn:executable
   + 

Added: packages/libchart-perl/branches/upstream/current/t/stackedbars.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/stackedbars.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/stackedbars.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,22 @@
+#!/usr/bin/perl -w
+
+use Chart::StackedBars;
+
+print "1..1\n";
+
+$g = Chart::StackedBars->new(600,400);
+$g->add_dataset ('foo', 'bar', 'junk', 'taco', 'kcufasidog');
+$g->add_dataset (3, 4, 9, 10, 11);
+$g->add_dataset (8, 6, 1, 12, 1);
+$g->add_dataset (5, 7, 2, 13, 4);
+
+$g->set ('title' => 'Stacked Bar Chart',
+         'legend'=> 'left',
+	 'grey_background' => 'false',
+);
+
+$g->png ("samples/stackedbars.png");
+
+print "ok 1\n";
+
+exit (0);

Added: packages/libchart-perl/branches/upstream/current/t/stackedbars_2.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/stackedbars_2.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/stackedbars_2.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,61 @@
+#!/usr/bin/perl -w
+
+use strict;
+use Chart::StackedBars;
+
+print "1..1\n";
+
+my ($g) = Chart::StackedBars->new(788,435);
+
+
+# 0 = X-Achse
+$g->add_dataset('0:00', '1:00', '2:00', '3:00', '4:00', '5:00', '6:00', '7:00',
+                '8:00', '9:00', '10:00', '11:00');
+# 2 = Basas - stacked bar
+$g->add_dataset( 0.8,     0.8,   0.9,    1.1,   1.8,     2.1,     1.8,    1.4, 
+                 1.0,     1.0,   1.0,    1.0);  
+# 3 = Bolus - stacked bar
+$g->add_dataset( 4.4,     1.8,   6.5,    5.6,   2.4,     4.7,     6.0,    5.4,
+                 8.9,     9.5,   8.7,    9.2);
+# 4 = KHE - stacked bar
+$g->add_dataset( 3.0,     2.8,   2.5,    0.6,   2.4,     4.7,     5.0,    5.4,
+                 1.9,     3.5,   4.7,    3.2);
+		 
+		 
+		 
+		
+
+
+$g->set ('legend'         => 'bottom',
+	 'title'          => 'Stacked Bars',
+	 'precision'      => 0,
+	 'spaced_bars'    => 'false',
+	 'include_zero'   => 'true',
+	 'legend_example_size' => 100,
+	 'skip_int_ticks' => 3,
+	 'min_val_2'      => 0,
+	 'y_label'       => 'IE/KHE',
+	 'y_label2'       => 'mg/dl (mmol/l)',
+	 'grey_background' => 'false',
+	 
+	  );
+	 
+$g->set( 'colors' => {'y_label'  => [51, 255, 0],
+                      'y_label2' => [255, 0, 0],
+		      'dataset2' => [0, 0, 244],      
+		      'dataset1' => [0, 204, 0],
+		      'dataset0' => [255, 255, 51],
+		      'dataset3' => [204, 0, 0],
+		     
+		        });
+		      
+
+
+
+
+
+$g->png("samples/stackedbars_2.png"); 
+
+print "ok 1\n";
+
+exit;

Added: packages/libchart-perl/branches/upstream/current/t/stackedbars_3.t
===================================================================
--- packages/libchart-perl/branches/upstream/current/t/stackedbars_3.t	2006-02-16 13:43:02 UTC (rev 2141)
+++ packages/libchart-perl/branches/upstream/current/t/stackedbars_3.t	2006-02-16 14:32:00 UTC (rev 2142)
@@ -0,0 +1,41 @@
+#!/usr/bin/perl -w
+
+use strict;
+use Chart::StackedBars;
+
+print "1..1\n";
+
+my ($g) = Chart::StackedBars->new(580,400);
+
+
+
+$g->add_dataset('1', '2', '3', '4', '5', '6', '7');
+$g->add_dataset( 5,  7,   9,   11,   9,   7,   5 );  
+$g->add_dataset( 15, 11,  8,    5,   8,  11,  15 );
+$g->add_dataset( 5,   4,  3,    2,   3,   4,   5 );		 
+		 
+
+$g->set ('legend'         => 'right',
+	 'title'          => 'Stacked Bars',
+	 'precision'      => 0,
+	 'spaced_bars'    => 'true',
+	 'include_zero'   => 'true',
+	 'skip_int_ticks' => 3,
+	 'max_val'      => 30,
+	 'y_label'       => '',
+	 'y_label2'       => '',
+	 'grey_background' => 'false',
+	 
+	 
+	  );
+	 
+$g->set( 'colors' => {'dataset0' => [0,125,250],
+		      'dataset1' => [147,112,219],
+		      'dataset2' => [250,0,125],
+		      'background' => [230,230,250]});
+		      
+$g->png("samples/stackedbars_3.png"); 
+
+print "ok 1\n";
+
+exit;




More information about the Pkg-perl-cvs-commits mailing list