cvsuser     05/11/07 20:59:56

  Added:       App-Widget-ChartDirector Build.PL CHANGES MANIFEST
                        MANIFEST.SKIP META.yml README TODO
               App-Widget-ChartDirector/cgi-bin app-cdgraph
               App-Widget-ChartDirector/lib/App/Widget ChartDirector.pm
  Log:
  new
  
  Revision  Changes    Path
  1.1                  p5ee/App-Widget-ChartDirector/Build.PL
  
  Index: Build.PL
  ===================================================================
  
  use App::Build;
  
  my $build = App::Build->new (
      dist_name         => "App-Widget-ChartDirector",
      dist_version      => "0.50",
      dist_author       => "[EMAIL PROTECTED]",
      dist_abstract     => "A graphing widget which displays graphs and charts 
for web applications using the ChartDirector graphing library within the 
App-Context/App-Widget widget framework",
      license           => "perl",
      requires => {
          "App::Options"   => 0,  # needed for option parsing
      },
      build_requires => {
          "App::Build"     => 0,  # needed for installing the software
          "Module::Build"  => 0,  # needed for installing the software
          "File::Spec"     => 0,  # platform-neutral directory processing
      },
      extra_dirs => [ "cgi-bin", ],
      dynamic_config => 1,
  );
  
  $build->create_build_script;
  
  
  
  
  1.1                  p5ee/App-Widget-ChartDirector/CHANGES
  
  Index: CHANGES
  ===================================================================
  #########################################
  # CHANGE LOG
  #########################################
  
  VERSION 0.50
   x Initial release
  
  
  
  
  1.1                  p5ee/App-Widget-ChartDirector/MANIFEST
  
  Index: MANIFEST
  ===================================================================
  CHANGES
  Build.PL
  MANIFEST
  README
  TODO
  lib/App/Widget/ChartDirector.pm
  META.yml                                 Module meta-data 
  
  
  
  1.1                  p5ee/App-Widget-ChartDirector/MANIFEST.SKIP
  
  Index: MANIFEST.SKIP
  ===================================================================
  ~$
  ^MANIFEST\.
  ^Makefile$
  ^blib/
  ^pm_to_blib$
  \.old$
  \.bak$
  \.cvsignore$
  \.tar\.gz$
  htdocs/.exists
  CVS/
  
  
  
  1.1                  p5ee/App-Widget-ChartDirector/META.yml
  
  Index: META.yml
  ===================================================================
  # http://module-build.sourceforge.net/META-spec.html
  #XXXXXXX This is a prototype!!!  It will change in the future!!! XXXXX#
  name:         App-Widget-JSApp
  version:      0.10
  version_from: 
  installdirs:  site
  requires:
      App::Widget:                   0
  
  distribution_type: module
  generated_by: ExtUtils::MakeMaker version 6.25
  
  
  
  1.1                  p5ee/App-Widget-ChartDirector/README
  
  Index: README
  ===================================================================
  ######################################################################
  ## File: $Id: README,v 1.1 2005/11/08 04:59:56 spadkins Exp $
  ######################################################################
  
  WHAT IS THIS?
  
  This is the App-Widget-ChartDirector distribution.
  It implements the Graph Widget abstraction from the App-Widget/App-Context
  frameworks on top of the ChartDirector graphing library.
  
  Thus, it is a widget for displaying line graphs, bar charts, pie charts,
  meters/gauges, and more.
  
  ChartDirector is not free software.  However, it has a very liberal
  try-before-you-buy policy, starting with free, anonymous downloading.
  The unlicensed version simply puts a small "Unregistered" message at
  the bottom of every graph.  This is quite workable for prototyping and
  development.  When you are ready to buy, the price is quite reasonable.
  
  As of 25-Oct-2005 when I checked the prices for Linux licenses were
  
     * USD 99 each (for 1 - 4 licenses)
     * USD 79 each (for 5 - 19 licenses)
     * USD 59 each (for >= 20 licenses)
  
  The web site for ChartDirector is at
  
     http://www.advsofteng.com/index.html      # Product/company home page
     http://www.advsofteng.com/cdperl.html     # Perl library page
     http://www.advsofteng.com/download.html   # Download page
     http://www.advsofteng.com/gallery.html    # Chart gallery
  
  HOW DO I INSTALL IT?
  
  Install ChartDirector for Perl first.
  
  Then install this distribution.  cd to the directory that contains this README
  file and type the following:
  
     perl Build.PL
     ./Build
     ./Build test
     ./Build install
  
  
  
  
  1.1                  p5ee/App-Widget-ChartDirector/TODO
  
  Index: TODO
  ===================================================================
  ######################################################################
  ## File: $Id: TODO,v 1.1 2005/11/08 04:59:56 spadkins Exp $
  ######################################################################
  
  To get to Version 1.0
   o tbd
  
  
  
  
  1.1                  p5ee/App-Widget-ChartDirector/cgi-bin/app-cdgraph
  
  Index: app-cdgraph
  ===================================================================
  #!/usr/local/bin/perl -w
  
  use strict;
  
  use App::Options;
  use CGI;
  
  {
      my $cgi = CGI->new();
      my ($value);
      foreach my $param ($cgi->param()) {
          $App::options{$param} = $cgi->param($param);
      }
      foreach my $param (keys %App::options) {
          $value = $App::options{$param};
          if (!ref($value)) {
              if ($value =~ /^\{\s*(.*)\}$/) {
                  $value = $1;
                  $value =~ s/=>/,/g;
                  $value =~ s/[ \t\r,]+$//;
                  $value = { split(/\s*,\s*/, $value) };
              }
              elsif ($value =~ /^\[\s*(.*)\]$/) {
                  $value = $1;
                  $value =~ s/=>/,/g;
                  $value =~ s/[ \t\r,]+$//;
                  $value = [ split(/\s*,\s*/, $value) ];
              }
              $App::options{$param} = $value;
          }
      }
      my ($errmsg, %data, $data_file);
      my $tempdir = $App::options{document_root} ? 
"$App::options{document_root}/temp/" :
             ($ENV{DOCUMENT_ROOT} ? "$ENV{DOCUMENT_ROOT}/temp/" : "/tmp/");
      my $data = $App::options{graph_data} || "graph_data.txt";
      $data_file = "$tempdir/$data";
      if (! -f $data_file) {
          $data_file = "$tempdir/$data";
      }
      if (! -f $data_file) {
          $errmsg = "Data file $data_file not found";
      }
      my $template = $ENV{PATH_INFO} || $App::options{graph_template} || 
"graph_template.txt";
      my $template_dir = $App::options{template_dir} || ".";
      my $template_file = "$template_dir/$template";
      if (! -f $template_file && -f $template) {
          $template_file = $template;
      }
      if (! -f $template_file) {
          $errmsg = "Template file $template_file not found";
      }
      if (!$errmsg) {
          eval {
              do $data_file;     # puts data in %data
              if ($@) {
                  $errmsg = "Error: $@";
              }
              else {
                  foreach my $param (keys %App::options) {
                      if (ref($App::options{$param})) {
                          $data{$param} = $App::options{$param};  # overlay 
data in %data
                      }
                  }
                  do $template_file; # reads data from %data
                  if ($@) {
                      $errmsg = "Error: $@";
                  }
              }
          };
          if ($@) {
              $errmsg = "Error running $template_file: $@";
          }
      }
      if ($errmsg) {
          print <<EOF;
  Content-type: text/plain
  
  $errmsg
  EOF
      }
  }
  
  
  
  
  1.1                  
p5ee/App-Widget-ChartDirector/lib/App/Widget/ChartDirector.pm
  
  Index: ChartDirector.pm
  ===================================================================
  
  ######################################################################
  ## $Id: ChartDirector.pm,v 1.1 2005/11/08 04:59:56 spadkins Exp $
  ######################################################################
  
  package App::Widget::ChartDirector;
  $VERSION = do { my @r=(q$Revision: 1.1 $=~/\d+/g); sprintf 
"%d."."%02d"x$#r,@r};
  
  use App;
  use App::Widget::Graph;
  @ISA = ( "App::Widget::Graph" );
  
  use strict;
  
  =head1 NAME
  
  App::Widget::ChartDirector - A graphing widget which displays graphs and 
charts for web applications using the ChartDirector graphing library within the 
App-Context/App-Widget widget framework
  
  =head1 SYNOPSIS
  
     $name = "first_name";
  
     # official way
     use App;
     $context = App->context();
     $w = $context->widget($name);
     # OR ...
     $w = $context->widget($name,
        class => "App::Widget::ChartDirector",
     );
  
     # internal way
     use App::Widget::ChartDirector;
     $w = App::Widget::ChartDirector->new($name);
  
  =cut
  
  =head1 DESCRIPTION
  
  A graphing widget which displays graphs and charts for web
  applications using the ChartDirector graphing library within the
  App-Context/App-Widget widget framework.
  
  =cut
  
  sub html {
      &App::sub_entry if ($App::trace);
      my $self = shift;
      my $name = $self->{name};
  
      my $spec = $self->create_graph_spec();
  
      my ($html);
      if ($self->{defer_images}) {   # write out the graph spec. produce graph 
image later.
          my $spec_path = $spec->{spec_path};
          if (open(App::Widget::ChartDirector::FILE, "> $spec_path")) {
              $self->write_graph_spec(\*App::Widget::ChartDirector::FILE, 
$spec);
              close(App::Widget::ChartDirector::FILE);
              $html .= "<img src=\"$spec->{cgi_url}\"";
              $html .= " height=\"$spec->{height}\"" if ($spec->{height});
              $html .= " width=\"$spec->{width}\"" if ($spec->{width});
              $html .= ">\n";
          }
          else {
              $html .= "[Error creating graph spec $spec_path: $!]";
          }
      }
      else {    # generate graph image now
          eval {
              $html = $self->write_graph_image($spec);
          };
          if ($@) {
              $html .= "[Error creating graph image $spec->{image_path}: [EMAIL 
PROTECTED]";
          }
      }
      if ($self->{debug}) {
          $html .= "<pre>\n";
          foreach my $key (sort keys %$spec) {
              $html .= "$key = ";
              if (ref($spec->{$key}) eq "ARRAY") {
                  $html .= "[ " . join(", ", @{$spec->{$key}}) . " ]\n";
              }
              else {
                  $html .= "$spec->{$key}\n";
              }
          }
          $html .= "</pre>\n";
      }
  
      &App::sub_exit($html) if ($App::trace);
      $html;
  }
  
  my $serial = 1;
  
  sub create_graph_spec {
      &App::sub_entry if ($App::trace);
      my ($self) = @_;
      my $context = $self->{context};
      my $options = $context->{options};
      my $spec_tempdir   = $options->{tempdir} || "$options->{prefix}/tmp";
      my $image_tempdir  = "$options->{html_dir}/temp";
      my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = 
localtime(time);
      $mon++;
      $year += 1900;
      my $datetime = sprintf("%04d%02d%02d-%02d%02d%02d", $year, $mon, $mday, 
$hour, $min, $sec);
      my $unique_tag = $datetime . "-" . $$ . "-" . $serial;
      my $spec_file  = "$unique_tag.graph";
      my $spec_path  = "$spec_tempdir/$spec_file";
      my $image_file = "$unique_tag.png";
      my $image_path = "$image_tempdir/$image_file";
      while (-f $spec_path || -f $image_path) {
          $serial++;
          $unique_tag = $datetime . "-" . $$ . "-" . $serial;
          $spec_file  = "$unique_tag.graph";
          $spec_path  = "$spec_tempdir/$spec_file";
          $image_file = "$unique_tag.png";
          $image_path = "$image_tempdir/$image_file";
      }
      my %spec = %$self;
      delete $spec{context};
      $spec{graphtype}  ||= "bar";
      if ($spec{graphtype} eq "area") {
          $spec{graphtype} = "line";
          $spec{area} = 1;
      }
      elsif ($spec{graphtype} eq "stacked_bar") {
          $spec{graphtype} = "bar";
          $spec{stacked} = 1;
      }
      $spec{height}     ||= 280;
      $spec{width}      ||= 360;
      $spec{spec_file}  = $spec_file;
      $spec{spec_path}  = $spec_path;
      $spec{image_file} = $image_file;
      $spec{image_path} = $image_path;
      $spec{image_url}  = "$options->{html_url_dir}/temp/$image_file";
      $spec{cgi_url}    = "$options->{script_url_dir}/app-cdgraph/$spec_file";
      &App::sub_exit(\%spec) if ($App::trace);
      return(\%spec);
  }
  
  sub write_graph_spec {
      &App::sub_entry if ($App::trace);
      my ($self, $fh, $spec) = @_;
      foreach my $key (%$spec) {
          if (!ref($spec->{$key})) {
              print $fh "\$data{$key} = [ ";
              foreach my $value (@{$spec->{$key}}) {
                  print $fh "\"$spec->{$key}\", ";
              }
              print $fh "]\n";
          }
          else {
              print $fh "\$data{$key} = \"$spec->{$key}\";\n";
          }
      }
      &App::sub_exit() if ($App::trace);
  }
  
  sub read_graph_spec {
      &App::sub_entry if ($App::trace);
      my ($self, $fh, $spec) = @_;
      foreach my $key (%$spec) {
          if (!ref($spec->{$key})) {
              print $fh "\$data{$key} = [ ";
              foreach my $value (@{$spec->{$key}}) {
                  print $fh "\"$spec->{$key}\", ";
              }
              print $fh "]\n";
          }
          else {
              print $fh "\$data{$key} = \"$spec->{$key}\";\n";
          }
      }
      &App::sub_exit() if ($App::trace);
  }
  
  sub write_graph_image {
      &App::sub_entry if ($App::trace);
      my ($self, $spec) = @_;
      my $graphtype = $spec->{graphtype} || "bar";
      my %known_graphtype = (
          bar   => 1,
          area  => 1,
          line  => 1,
          pie   => 1,
          meter => 1,
      );
      my $html = "";
      if ($known_graphtype{$graphtype}) {
          my $method = "write_${graphtype}_graph_image";
          $self->$method($spec);
          $html .= "<img src=\"$spec->{image_url}\"";
          $html .= " height=\"$spec->{height}\"" if ($spec->{height});
          $html .= " width=\"$spec->{width}\"" if ($spec->{width});
          $html .= ">\n";
      }
      else {
          $html = "[$self->{name}: Unknown graph type ($graphtype)]\n";
      }
      &App::sub_exit() if ($App::trace);
      return($html);
  }
  
  sub get_num_dims {
      &App::sub_entry if ($App::trace);
      my ($self, $graphtype) = @_;
      my %dims = (
          bar         => 3,
          area        => 3,
          line        => 3,
          stacked_bar => 3,
          pie         => 1,
          meter       => 0,
      );
      my $num_dims = $dims{$graphtype};
      $num_dims = 2 if (!defined $num_dims);
      &App::sub_exit($num_dims) if ($App::trace);
      return($num_dims);
  }
  
  sub new_xy_chart {
      &App::sub_entry if ($App::trace);
      my ($self, $spec) = @_;
      require "perlchartdir.pm";
  
      my $x = $self->get_x($spec);
      my $width  = $spec->{width}  || 250;
      my $height = $spec->{height} || 250;
      my $left_margin   = $spec->{left_margin};
      my $bottom_margin = $spec->{bottom_margin};
      my $right_margin  = $spec->{right_margin} || 20;
      my $top_margin    = $spec->{top_margin};
      if (!$top_margin) {
          $top_margin = 5;
          $top_margin += 20 if ($spec->{title});
          #$top_margin += 20 if ($spec->{y_labels});
          $top_margin += 8 if ($spec->{"3D"});
      }
      if (!$bottom_margin) {
          $bottom_margin = 10;
          $bottom_margin += 9 if (!$spec->{registered});
          $bottom_margin += 15 if ($x);
          $bottom_margin += 18 if ($spec->{x_title});
      }
      if (!$left_margin) {
          # TODO: This should be sensitive to the width of the numbers in the 
scale
          my ($y_min, $y_max) = $self->get_y_limits($spec);
          $y_min = int($y_min);
          $y_max = int($y_max);
          my $y_label_len = length($y_max);
          $y_label_len = length($y_min) if (length($y_min) > $y_label_len);
          $left_margin = 20 + $y_label_len * 6;
          $left_margin += 20 if ($spec->{y_title});
      }
  
      my $c = new XYChart($width, $height);
  
      my $plot_area = $c->setPlotArea($left_margin, $top_margin,
          $width-$left_margin-$right_margin,
          $height-$top_margin-$bottom_margin);
  
      # $plot_area->setBackground(0xffffc0, 0xffffe0);  # yellow
      $plot_area->setBackground(0xd8d8ff, 0xe0e0ff);
  
      $c->addTitle($spec->{title}) if ($spec->{title});
  
      #Add a legend box at (55, 22) using horizontal layout, with transparent
      #background
      if ($spec->{y_labels}) {
          my $x_adj = 0;
          my $y_adj = -2;
          if ($spec->{"3D"}) {
              $x_adj += 5;
              $y_adj += -5;
          }
          my $legend = $c->addLegend($left_margin+$x_adj, $top_margin+$y_adj, 
0);
          $legend->setBackground($perlchartdir::Transparent);
          $legend->setMargin(5);
      }
  
      #if ($x && $#$x > -1) {
      #    if ($x->[0] =~ /^([0-9]{4})-([0-9]{2})-([0-9]{2})$/) {
      #        my $begin_yr  = $1;
      #        my $begin_mon = $2;
      #        my $begin_day = $3;
      #        my $begin_time = &perlchartdir::chartTime($1, $2, $3);
      #        my ($end_time, $end_yr, $end_mon, $end_day);
      #        if ($x->[$#$x] =~ /^([0-9]{4})-([0-9]{2})-([0-9]{2})$/) {
      #            $end_yr   = $1;
      #            $end_mon  = $2;
      #            $end_day  = $3;
      #            $end_time = &perlchartdir::chartTime($1, $2, $3);
      #        }
      #        $c->xAxis()->setDateScale($begin_time, $end_time);
      #        my (@x_date);
      #        for (my $i = 0; $i <= $#$x; $i++) {
      #            if ($x->[$i] =~ /^([0-9]{4})-([0-9]{2})-([0-9]{2})$/) {
      #                $x_date[$i] = &perlchartdir::chartTime($1, $2, $3);
      #            }
      #            else {
      #                $x_date[$i] = $perlchartdir::NoValue;
      #            }
      #        }
      #        $spec->{x} = [EMAIL PROTECTED];
      #        #$c->xAxis()->setDateFormat("{value|mm/dd}");
      #    }
      #    else {
      #        $c->xAxis()->setLabels($x);
      #    }
      #}
      $c->xAxis()->setLabels($x);
  
      $c->xAxis()->setTitle($spec->{x_title}) if ($spec->{x_title});
      $c->yAxis()->setTitle($spec->{y_title}) if ($spec->{y_title});
      $c->setBackground(0xbbbbff);
      #$c->setBackground(perlchartdir::metalColor(0xaaaaff));
  
      &App::sub_exit($c) if ($App::trace);
      return($c);
  }
  
  sub new_pie_chart {
      &App::sub_entry if ($App::trace);
      my ($self, $spec) = @_;
      require "perlchartdir.pm";
  
      my $x = $self->get_x($spec);
      my $width  = $spec->{width}  || 250;
      my $height = $spec->{height} || 250;
      my $left_margin   = $spec->{left_margin};
      my $bottom_margin = $spec->{bottom_margin};
      my $right_margin  = $spec->{right_margin} || 20;
      my $top_margin    = $spec->{top_margin};
      if (!$top_margin) {
          $top_margin = 5;
          $top_margin += 20 if ($spec->{title});
          $top_margin += 5 if ($spec->{"3D"});
      }
      if (!$bottom_margin) {
          $bottom_margin = 10;
          $bottom_margin += 9 if (!$spec->{registered});
          $bottom_margin += 15 if ($x);
      }
      if (!$left_margin) {
          $left_margin = 20;
      }
      my $c = new PieChart($width, $height);
      my $center_x = int($width/2);
      my $center_y = int(($height - 20)/2);
      my $radius   = (($center_x > $center_y) ? $center_y : $center_x) - 40;
      $c->setPieSize($center_x, $center_y, $radius);
  
      $c->addTitle($spec->{title}) if ($spec->{title});
  
      &App::sub_exit($c) if ($App::trace);
      return($c);
  }
  
  sub new_meter_chart {
      &App::sub_entry if ($App::trace);
      my ($self, $spec) = @_;
      require "perlchartdir.pm";
  
      my $x = $self->get_x($spec);
      my $width  = $spec->{width}  || 250;
      my $height = $spec->{height} || 180;
      my $left_margin   = $spec->{left_margin};
      my $bottom_margin = $spec->{bottom_margin};
      my $right_margin  = $spec->{right_margin} || int($width * 0.08);
      my $top_margin    = $spec->{top_margin};
      if (!$top_margin) {
          $top_margin = 5;
          $top_margin += 20 if ($spec->{title});
          $top_margin += 5 if ($spec->{"3D"});
      }
      if (!$left_margin) {
          $left_margin = $right_margin;
      }
      if (!$bottom_margin) {
          $bottom_margin = 10;
          $bottom_margin += 9 if (!$spec->{registered});
          $bottom_margin += 15 if ($x);
      }
      my $c = new AngularMeter($width, $height, 
perlchartdir::metalColor(0xaaaaff), 0x0, 2);
      my $max_width_radius = int(($width - $left_margin - $right_margin)/2);
      my $max_height_radius = $height - $top_margin - $bottom_margin;
      my $radius   = ($max_width_radius > $max_height_radius) ? 
$max_height_radius : $max_width_radius;
      my $center_x = $left_margin + $max_width_radius;
      my $center_y = int(($height - $bottom_margin - $top_margin + $radius)/2) 
+ $top_margin;
      $spec->{radius}   = $radius;
      $spec->{center_x} = $center_x;
      $spec->{center_y} = $center_y;
      $c->setMeter($center_x, $center_y, $radius, -90, 90);
  
      $c->addTitle($spec->{title}) if ($spec->{title});
  
      &App::sub_exit($c) if ($App::trace);
      return($c);
  }
  
  sub write_bar_graph_image {
      &App::sub_entry if ($App::trace);
      my ($self, $spec) = @_;
      my $c = $self->new_xy_chart($spec);
      my $x  = $self->get_x($spec);
      my $yn = $self->get_y($spec);
      if ($#$yn > 0) {
          if ($spec->{stacked}) {
              my $three_d_depth = $spec->{"3D"} ? 8 : 0;
              my $layer = $c->addBarLayer2($perlchartdir::Stack, 
$three_d_depth);
              #$layer->setXData($x);
              my $y_labels = $spec->{y_labels} || [];
              for (my $i = 0; $i <= $#$yn; $i++) {
                  $layer->addDataSet($yn->[$i], -1, $y_labels->[$i]);
              }
              #Enable bar label for the whole bar
              $layer->setAggregateLabelStyle();
              #Enable bar label for each segment of the stacked bar
              $layer->setDataLabelStyle();
          }
          else {
              my $layer = $c->addBarLayer2($perlchartdir::Side, $#$yn + 1);
              #$layer->setXData($x);
              my $y_labels = $spec->{y_labels} || [];
              for (my $i = 0; $i <= $#$yn; $i++) {
                  $layer->addDataSet($yn->[$i], -1, $y_labels->[$i]);
              }
              #Enable bar label for the whole bar
              $layer->setAggregateLabelStyle();
              if ($spec->{"3D"}) {
                  $layer->set3D(5,0);
                  $layer->setBarGap(0.2, 0.03);
              }
              else {
                  $layer->set3D(0,0);
                  if ($spec->{overlap}) {
                      $layer->setOverlapRatio(($spec->{overlap} >= 1) ? 0.3 : 
$spec->{overlap})
                  }
                  else {
                      $layer->setBarGap(0.2, 0.03);
                  }
              }
          }
      }
      elsif ($#$yn > -1) {
          my $layer = $c->addBarLayer($yn->[0]);
          #$layer->setXData($x);
          $layer->set3D() if ($spec->{"3D"});
      }
      $c->makeChart($spec->{image_path});
      &App::sub_exit() if ($App::trace);
  }
  
  sub write_line_graph_image {
      &App::sub_entry if ($App::trace);
      my ($self, $spec) = @_;
      my $c = $self->new_xy_chart($spec);
  
      #Display 1 out of 3 labels on the x-axis.
      # $c->xAxis()->setLabelStep(3);
  
      #Set the labels on the x axis by spreading the labels evenly between the 
first
      #point (index = 0) and the last point (index = noOfPoints - 1)
      # $c->xAxis()->setLinearScale(0, $noOfPoints - 1, $labels);
      # $c->xAxis()->setLinearScale(0, 2, $x);
  
      my $x = $self->get_x($spec);
      my $yn = $self->get_y($spec);
      my ($layer, $dataset);
      my @symbols = (
          { symbol => $perlchartdir::SquareSymbol,  size => 7, },
          { symbol => $perlchartdir::DiamondSymbol, size => 9, },
          { symbol => $perlchartdir::CircleShape,   size => 7, },
          { symbol => $perlchartdir::TriangleShape, size => 8, },
      );
      if ($spec->{area}) {
          $layer = $c->addAreaLayer2($perlchartdir::Stack);
          $spec->{stacked} = 0;  # stacking is done for us in the area layer
      }
      else {
          $layer = $c->addLineLayer2();
          $layer->setLineWidth(2);
      }
      $layer->set3D(5) if ($spec->{"3D"});
      if ($#$yn > 0) {
          my ($stacked_y, $y, $dataset);
          if ($spec->{stacked}) {
              $stacked_y = [ ];  # make a copy
          }
          my $y_labels = $spec->{y_labels} || [];
          for (my $i = 0; $i <= $#$yn; $i++) {
              $y = $yn->[$i];
              if ($spec->{stacked}) {
                  for (my $j = 0; $j <= $#$y; $j++) {
                      $stacked_y->[$j] += $y->[$j];
                  }
                  $y = $stacked_y;
              }
              $dataset = $layer->addDataSet($y, -1, $y_labels->[$i]);
              $dataset->setDataSymbol($self->sym($i, [EMAIL PROTECTED])) if 
($spec->{points});
          }
      }
      elsif ($#$yn > -1) {
          $layer = $c->addLineLayer($yn->[0]);
          $layer->setLineWidth(2);
      }
      if ($spec->{point_labels}) {
          my $label_format = $spec->{point_labels};
          $label_format = "{value|0}" if ($label_format eq "1");
          $layer->setDataLabelFormat($label_format);
      }
      $c->makeChart($spec->{image_path});
      &App::sub_exit() if ($App::trace);
  }
  
  sub sym {
      &App::sub_entry if ($App::trace);
      my ($self, $series, $symbols) = @_;
      my $idx = $series % ($#$symbols + 1);
      my $symboldef = $symbols->[$idx];
      &App::sub_exit($symboldef->{symbol}, $symboldef->{size}) if ($App::trace);
      return($symboldef->{symbol}, $symboldef->{size});
  }
  
  ##Add a legend box at (400, 100)
  #$c->addLegend(400, 100);
  ##Add a stacked bar layer and set the layer 3D depth to 8 pixels
  #my $layer = $c->addBarLayer2($perlchartdir::Stack, 8);
  ##Add the three data sets to the bar layer
  #$layer->addDataSet($data0, 0xff8080, "Server # 1");
  #$layer->addDataSet($data1, 0x80ff80, "Server # 2");
  #$layer->addDataSet($data2, 0x8080ff, "Server # 3");
  
  # TODO: this needs more work before it really works
  sub write_meter_graph_image {
      &App::sub_entry if ($App::trace);
      my ($self, $spec) = @_;
      my $c = $self->new_meter_chart($spec);
      my $x = $self->get_x($spec);
      my $yn = $self->get_y($spec) || [[]];
      my $value = $yn->[0][0];
      my $radius   = $spec->{radius};
      my $center_x = $spec->{center_x};
      my $center_y = $spec->{center_y};
  
      my $y_max = $spec->{y_max} || 100;
      my ($major_tick, $minor_tick, $micro_tick);
      {
          my $y_mantissa = $y_max;
          my $y_scale = 1;
          while ($y_mantissa > 1.0) {
              $y_mantissa /= 10;
              $y_scale    *= 10;
          }
          if ($y_mantissa > 0.5) {
              $y_max = $y_scale;
              $minor_tick = $y_max/10;
              $micro_tick = $y_max/20;
          }
          elsif ($y_mantissa > 0.2) {
              $y_max = 0.5 * $y_scale;
              $minor_tick = $y_max/25;
              $micro_tick = undef;
          }
          else {
              $y_max = 0.2 * $y_scale;
              $minor_tick = $y_max/10;
              $micro_tick = $y_max/20;
          }
          $major_tick = $y_max/5;
      }
  
      my $y_red = $spec->{y_red} || ($y_max * 0.80);
      my $y_yellow = $spec->{y_yellow} || ($y_max * 0.60);
  
      #Meter scale is 0 - 100, with major tick every 20 units, minor tick every 
10
      #units, and micro tick every 5 units
      $c->setScale(0, $y_max, $major_tick, $minor_tick, $micro_tick);
      #Set 0 - 60 as green (66FF66) zone
      $c->addZone(0, $y_yellow, 0, $radius, 0x66ff66);
      #Set 60 - 80 as yellow (FFFF33) zone
      $c->addZone($y_yellow, $y_red, 0, $radius, 0xffff33);
      #Set 80 - 100 as red (FF6666) zone
      $c->addZone($y_red, $y_max, 0, $radius, 0xff6666);
      #Add a text label centered at (100, 60) with 12 pts Arial Bold font
      if ($spec->{y_title}) {
          $c->addText($center_x, $center_y-int($radius * 0.35), 
$spec->{y_title},
              "arialbd.ttf", 11, $perlchartdir::TextColor, 
$perlchartdir::Center);
      }
  
      my $x_title = "";
      $x_title = $spec->{x_title} if ($spec->{x_title});
      if ($x) {
          $x_title .= ": " if ($x_title);
          $x_title .= $x->[0];
      }
      if ($spec->{y_labels}) {
          if ($x_title) {
              $x_title .= " ($spec->{y_labels}[0])";
          }
          else {
              $x_title = $spec->{y_labels}[0];
          }
      }
      if ($x_title) {
          $c->addText($center_x, $center_y+18, $x_title,
              "arialbd.ttf", 10, $perlchartdir::TextColor, 
$perlchartdir::Center);
      }
  
      #Add a text box at the top right corner of the meter showing the value 
formatted
      #to 2 decimal places, using white text on a black background, and with 1 
pixel
      #3D depressed border
      $c->addText($center_x + int($radius * 0.7), $center_y - int($radius * 
1.0),
          $c->formatValue($value, "2"),
          "arial.ttf", 8, 0xffffff)->setBackground(0x0, 0, -1);
  
      #Add a semi-transparent blue (40666699) pointer with black border at the
      #specified value
      $value = $y_max if ($value > $y_max);
      $value = 0 if ($value < 0);
      $c->addPointer($value, 0x40666699, 0x0);
      $c->makeChart($spec->{image_path});
      &App::sub_exit() if ($App::trace);
  }
  
  sub write_pie_graph_image {
      &App::sub_entry if ($App::trace);
      my ($self, $spec) = @_;
      my $c = $self->new_pie_chart($spec);
      my $x = $self->get_x($spec);
      my $yn = $self->get_y($spec);
      if ($#$yn > 0) {
      }
      else {
      }
      $c->setData($yn->[0], $x);
      $c->set3D() if ($spec->{"3D"});
      $c->makeChart($spec->{image_path});
      &App::sub_exit() if ($App::trace);
  }
  
  #my $data = [25, 18, 15, 12, 8, 30, 35];
  ##The labels for the pie chart
  #my $labels = ["Labor", "Licenses", "Taxes", "Legal", "Insurance", 
"Facilities",
  #    "Production"];
  ##Create a PieChart object of size 360 x 300 pixels
  #my $c = new PieChart(360, 300);
  ##Set the center of the pie at (180, 140) and the radius to 100 pixels
  #$c->setPieSize(180, 140, 100);
  ##Add a title to the pie chart
  #$c->addTitle("Project Cost Breakdown");
  ##Draw the pie in 3D
  #$c->set3D();
  ##Set the pie data and the pie labels
  #$c->setData($data, $labels);
  
  # TODO: This one doesn't work yet
  sub write_step_graph_image_step {
      &App::sub_entry if ($App::trace);
      my ($self, $spec) = @_;
      require "perlchartdir.pm";
  
      #Create a XYChart object of size 500 x 270 pixels, with a pale blue 
(0xe0e0ff)
      #background, a light blue (0xccccff) border, and 1 pixel 3D border effect.
      my $c = new XYChart(800, 350, 0xe0e0ff, 0xccccff, 1);
  
      #Set the plotarea at (50, 50) and of size 420 x 180 pixels, using white
      #(0xffffff) as the plot area background color. Turn on both horizontal and
      #vertical grid lines with light grey color (0xc0c0c0)
      $c->setPlotArea(50, 50, 720, 260, 0xffffff)->setGridColor(0xc0c0c0, 
0xc0c0c0);
  
      #Add a legend box at (55, 25) (top of the chart) with horizontal layout. 
Use 10
      #pts Arial Bold Italic font. Set the background and border color to 
Transparent.
      $c->addLegend(55, 20, 0, "arialbi.ttf", 
10)->setBackground($perlchartdir::Transparent);
  
      #Add a title to the chart using 14 points Times Bold Itatic font, using 
blue
      #(0x9999ff) as the background color
      $c->addTitle("Rate History", "arialbi.ttf", 12)->setBackground(0x9999ff);
  
      #Set the y axis label format to display a percentage sign
      #$c->yAxis()->setLabelFormat("{value}%");
  
      my $labels = $spec->{labels} || [ "Unknown" ];
      my $default_colors =
          [ 0x0000ff, 0x00ff00, 0xff0000, 0x00ffff, 0xff00ff, 0xffff00,
            0x111199, 0x119911, 0x991111, 0x119999, 0x991199, 0x999911,
            0x3333dd, 0x33dd33, 0xdd3333, 0x33dddd, 0xdd33dd, 0xdddd33,
            0x2222bb, 0x22bb22, 0xbb2222, 0x22bbbb, 0xbb22bb, 0xbbbb22 ];
      my $colors = $spec->{colors} || $default_colors;
  
      my ($label, $color, $step_xaxis, $xaxis, $yaxis, $layer);
      for (my $i = 0; $i <= $#$labels; $i++) {
          $label = $labels->[$i];
          $color = $colors->[$i] || 0;
          if ($color =~ /^0[xX][0-9A-Fa-f]+$/) {
              $color = eval $color;
          }
          $xaxis = $spec->{"x$i"} || [ $i, $i+1, $i+2, $i+3 ];
          $yaxis = $spec->{"y$i"} || [ $i, $i+1, $i+2, $i+3 ];
  
          # set the xAxis scale
          #$c->xAxis()->setLinearScale($xaxis->[0] - 1, $xaxis->[$#$xaxis], 1, 
0);
          $c->xAxis()->setAutoScale(0,0,1);
          $c->yAxis()->setAutoScale(0,0,1);
          $c->xAxis()->setIndent(1);
  
          # we decrement the $step_xaxis values by a day to account for the 
fact that
          # the step function runs from left to right but that the spec-> 
occurred
          # from right to left.
          $step_xaxis = [ @$xaxis ];   # make a copy
          for (my $x = 0; $x <= $#$step_xaxis; $x++) {
              $step_xaxis->[$x]--;
          }
  
          #Add a step line layer to the chart and set the line width to 2 pixels
          $layer = $c->addStepLineLayer($yaxis, $color, $label);
          #$layer->setXData($step_xaxis);
          $layer->setLineWidth(2);
  
          # Add a line layer to the chart
          # $layer = $c->addLineLayer();
          # Add the line. Plot the points with a 9 pixel diamond symbol
          # $layer->addDataSet($yaxis, $color)->setDataSymbol( 
$perlchartdir::DiamondSymbol, 9);
          # Enable data label on the data points. Set the label format to nn%.
          # $layer->setDataLabelFormat("{value}");
      }
  
      print $c->makeChart($spec->{image_path});
      &App::sub_exit() if ($App::trace);
  }
  
  1;
  
  
  
  

Reply via email to