Diff for /loncom/cgi/graph.png between versions 1.28 and 1.34

version 1.28, 2003/10/21 15:19:25 version 1.34, 2005/04/07 06:56:21
Line 38  graph.png Line 38  graph.png
   
 =head1 SYNOPSIS  =head1 SYNOPSIS
   
 produces plots based on input  produces plots from data stored in users environment.
   
 =head1 DESCRIPTION  =head1 DESCRIPTION
   
 graph.png is a cgi-bin script which produces plots based on input data.  graph.png is a cgi-bin script which produces plots based on data stored
   in the users environment.  The users cookie is checked prior to producing
 The query string is expected to be as follows (without whitespace):  a plot.  The query string is expected to be an identifier, $id.  
   The parameters defining the plot must be stored in the environment as 
 escape(Plot title) & escape(X label)& escape(Y label) & Maximum Y value &  $ENV{'cgi.'.$id.'.'.$dataname}.  Two types of plots can be produced, 'bar'
 Number of bars & $data1 & $data2  and 'xy'.  The 'xy' graph can will 1 or 2 y-axes if the parameter
   'two_axes' is set to false or true respectively.  See perldoc GD::Graph and
 $data1 and $data2 are expected to be comma seperated lists of numbers.  loncommon::DrawBarGraph, loncommon::DrawXYGraph, and loncommon::DrawXYYGraph.
 escape( value ) means the values must be run through lonnet::escape.  
   
 =cut  =cut
   
 use strict;  use strict;
 use lib '/home/httpd/lib/perl';  use lib '/home/httpd/lib/perl';
 use GD::Graph::bars;  use GD::Graph::bars;
   use GD::Graph::lines;
 use GD::Graph::colour;  use GD::Graph::colour;
 use GD::Graph::Data;  use GD::Graph::Data;
 use LONCAPA::loncgi();  use LONCAPA::loncgi;
   
 sub unescape {  sub unescape {
     my $str=shift;      my $str=shift;
Line 67  sub unescape { Line 67  sub unescape {
     return $str;      return $str;
 }  }
   
 if (! &LONCAPA::loncgi::check_cookie_and_load_env()) {  sub error {
     print <<END;      my ($error) = @_;
       my $Str = <<"END";
 Content-type: text/html  Content-type: text/html
   
 <html>  <html>
 <head><title>Bad Cookie</title></head>  <head><title>Bad Graph</title></head>
 <body>  <body>
 Your cookie information is incorrect.  <p>
   There was an error producing the graph you requested.
   </p><p>
   $error
   </p>
 </body>  </body>
 </html>  </html>
 END  END
     exit;      return $Str;
 }  }
   
 $|=1;   # Autoflush after each print/write  my $id = $ENV{'QUERY_STRING'};
 my $identifier = $ENV{'QUERY_STRING'};  
 my $Title   = &unescape($ENV{'cgi.'.$identifier.'.title'});  
 my $xlabel  = &unescape($ENV{'cgi.'.$identifier.'.xlabel'});  
 my $ylabel  = &unescape($ENV{'cgi.'.$identifier.'.ylabel'});  
 my $Max     = $ENV{'cgi.'.$identifier.'.Max'};  
 my $NumBars = $ENV{'cgi.'.$identifier.'.NumBars'};  
 my $NumSets = $ENV{'cgi.'.$identifier.'.NumSets'};  
 my @Colors  = split(',',$ENV{'cgi.'.$identifier.'.Colors'});  
   
 #  #
 # Labels are always digits  # usage: &get_env($name,$default)
 my @xlabels;  sub get_env {
 for (my $nIdx=0; $nIdx<$NumBars; $nIdx++ ) {      my $key = 'cgi.'.$id.'.'.(shift());
     $xlabels[$nIdx]=$nIdx+1;      return shift if (! exists($env{$key}));
 }      return $env{$key};
 my @data;  # stores the data for the graph  
 push(@data,\@xlabels);  
 for (my $i=1;$i<=$NumSets;$i++) {  
     push(@data,[split(',',$ENV{'cgi.'.$identifier.'.data.'.$i})]);  
 }  }
   
 my $skip_x = 1;  if (! &LONCAPA::loncgi::check_cookie_and_load_env()) {
 my $bar_width=10;      print <<END;
   Content-type: text/html
   
 #  <html>
 # Customize graph based on the   <head><title>Bad Cookie</title></head>
 my $width;  <body>
 my $height = 200;  Your cookie information is incorrect.
   </body>
 if ($NumBars < 10) {  </html>
     $width = 120+$NumBars*15;  END
     $skip_x = 1;      exit;
     $bar_width = 15;  
 } elsif ($NumBars <= 25) {  
     $width = 120+$NumBars*11;  
     $skip_x = 5;  
     $bar_width = 8;  
 } elsif ($NumBars <= 50) {  
     $width = 120+$NumBars*8;  
     $skip_x = 5;  
     $bar_width = 4;  
 } else {  
     $width = 120+$NumBars*8;  
     $skip_x = 5;  
     $bar_width = 4;  
 }  }
   
 my $x_tick_offset = 0;  $|=1;   # Autoflush after each print/write
 if ($skip_x > 1) {  
     $x_tick_offset = $skip_x - 1;  
 }  
   
 my $MyGraph = GD::Graph::bars->new($width,$height);  ##
 my $error = '';  ## Set up the plot
 if (! $MyGraph->set( x_label         => $xlabel,  ##
                      y_label         => $ylabel,  my $colordefaults = join(',',
                            ('#33ff00', 
                             '#0033cc','#990000','#aaaa66','#663399','#ff9933',
                             '#66ccff','#ff9999','#cccc33','#660000','#33cc66',
                             ));
   
   my $height   = &get_env('height',300);
   my $width    = &get_env('width', 400);
   my $PlotType = &get_env('PlotType','bar');
   
   my %GraphSettings = (
                        title           => &unescape(&get_env('title','')),
                        x_label         => &unescape(&get_env('xlabel','')),
                        y_label         => &unescape(&get_env('ylabel','')),
                      x_label_position => 0.5,                       x_label_position => 0.5,
                      long_ticks      => 1,                       dclrs           => [split(',',&get_env('Colors',
                      tick_length     => 0,                                                              $colordefaults))],
                      x_ticks         => 0,  
                      title           => $Title,  
                      y_max_value     => $Max,  
                      x_label_skip    => $skip_x,     
                      x_tick_offset   => $x_tick_offset,  
                      #  
                      dclrs           => \@Colors,  
                      bar_width       => $bar_width,  
                      cumulate        => 2,  
                      zero_axis       => 1,  
                      fgclr           => 'black',                       fgclr           => 'black',
                      boxclr          => 'white',                       boxclr          => 'white',
                      accentclr       => 'dblue',                       accentclr       => 'dblue',
Line 159  if (! $MyGraph->set( x_label         => Line 140  if (! $MyGraph->set( x_label         =>
                      b_margin        => 10,                       b_margin        => 10,
                      r_margin        => 10,                       r_margin        => 10,
                      t_margin        => 10,                       t_margin        => 10,
                      #  
                      transparent     => 0,                       transparent     => 0,
                      )) {                       );
     $error = $MyGraph->error;  
     print <<"END";  
 Content-type: text/html  
   
 <html>  $GraphSettings{'x_label_skip'}  = &get_env('xskip',1);
 <head><title>Bad Graph</title></head>  $GraphSettings{'x_tick_offset'} = &get_env('x_tick_offset',0);
 <body>  $GraphSettings{'y_max_value'}   = &get_env('y_max_value',1);
 <p>  
 There was an error producing the graph you requested.  my $MyGraph;
 </p><p>  if ($PlotType eq 'bar') {
 $error      # Pick up bar graph settings
 </p>      $GraphSettings{'bar_width'}     = &get_env('bar_width',undef);
 </body>      $GraphSettings{'long_ticks'}    = 1;
 </html>      $GraphSettings{'tick_length'}   = 0;
 END      $GraphSettings{'x_ticks'}       = 0;
       $GraphSettings{'cumulate'}      = 2;
       $GraphSettings{'zero_axis'}     = 1;
   } else {
       #
       # X label skip setup
       my $skip_x = &get_env('xskip',1);
       my $x_tick_offset = &get_env('x_tick_offset',$skip_x-1);
       my $zero_axis = &get_env('zero_axis',1);
       #
       # Fill up %GraphSettings
       $GraphSettings{'long_ticks'}    = 1;
       $GraphSettings{'tick_length'}   = 0;
       $GraphSettings{'x_ticks'}       = &get_env('x_ticks',0),;
       $GraphSettings{'x_label_skip'}  = $skip_x;
       $GraphSettings{'x_tick_offset'} = $x_tick_offset;
       $GraphSettings{'zero_axis'}     = 1;
       if (&get_env('two_axes',0)) {
           $GraphSettings{'two_axes'}     = 1;
           $GraphSettings{'y1_label'}     = &get_env('y1_label',
                                                     $GraphSettings{'y_label'});
           $GraphSettings{'y2_label'}     = &get_env('y2_label','');
           $GraphSettings{'y1_max_value'} = &get_env('y1_max_value',0);
           $GraphSettings{'y1_min_value'} = &get_env('y1_min_value',1);
           $GraphSettings{'y2_max_value'} = &get_env('y2_max_value',1);
           $GraphSettings{'y2_min_value'} = &get_env('y2_min_value',1);
       }
   }
   #
   # Pick up miscellanious values passed in by the user
   #
   # Create the plot and check it out
   if ($PlotType eq 'bar') {
       $MyGraph = GD::Graph::bars->new($width,$height);
   } else {
       $MyGraph = GD::Graph::lines->new($width,$height);
   }
   if (! defined($MyGraph)) {
       print &error('Unable to create initial graph');
     return;      return;
 }  }
   
 my $plot = $MyGraph->plot(\@data);  ##
 if (! defined($plot)) {  ## Build the @Data array
     print <<"END";  my $NumSets = &get_env('NumSets');
 Content-type: text/html  my @Data;        # stores the data for the graph
   my @Legend;      # one entry per data set
   my @xlabels  = split(',',&get_env('labels'));
   push(@Data,\@xlabels);
   for (my $i=1;$i<=$NumSets;$i++) {
       push(@Data,[split(',',&get_env('data.'.$i))]);
       push(@Legend,&get_env('data.'.$i.'.label',undef));
   }
   
 <html>  my $error = '';
 <head><title>Bad Graph</title></head>  if (! $MyGraph->set(%GraphSettings)) {
 <body>      print &error($MyGraph->error);
 The system was unable to create the graph you requested.  
 </body>  
 </html>  
 END  
     return;      return;
 }  }
   
   if (join('',@Legend) ne '') {
       $MyGraph->set_legend(@Legend);
   }
   
   
   my $plot = $MyGraph->plot(\@Data);
   if (! defined($plot)) {
       my $error = 'Unable to plot the data provided.';
   # Debugging code:    
   #    $error .= '<pre>'.join(',',@{$Data[0]}).'</pre>';
   #    $error .= '<pre>'.join(',',@{$Data[1]}).'</pre>';
   #    $error .= '<pre>'.join(',',@{$Data[2]}).'</pre>' if (ref($Data[2]));
   #    $error .= '<pre>'.join(',',@{$Data[3]}).'</pre>' if (ref($Data[3]));
       print &error($error);
       exit;
   }
   
 my $BinaryData=$plot->png;  my $BinaryData=$plot->png;
 undef($MyGraph);  undef($MyGraph);
 undef($plot);  undef($plot);
   
 if (! defined($BinaryData)) {  if (! defined($BinaryData)) {
     print <<"END";      print &error('Unable to render graph as image');
 Content-type: text/html      exit;
   
 <html>  
 <head><title>Bad Graph</title></head>  
 <body>  
 The system was unable to produce a png image of the graph you requested.  
 </body>  
 </html>  
 END  
     return;  
 }  }
   
   
 # Tell the server we are sending a png graphic  # Tell the server we are sending a png graphic
 print <<END;  print <<END;
 Content-type: image/png  Content-type: image/png

Removed from v.1.28  
changed lines
  Added in v.1.34


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>