Annotation of loncom/cgi/graph.png, revision 1.29

1.1       minaeibi    1: #!/usr/bin/perl
                      2: #
1.29    ! matthew     3: # $Id: graph.png,v 1.28 2003/10/21 15:19:25 matthew Exp $
1.5       minaeibi    4: #
                      5: # Copyright Michigan State University Board of Trustees
                      6: #
                      7: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
                      8: #
                      9: # LON-CAPA is free software; you can redistribute it and/or modify
                     10: # it under the terms of the GNU General Public License as published by
                     11: # the Free Software Foundation; either version 2 of the License, or
                     12: # (at your option) any later version.
                     13: #
                     14: # LON-CAPA is distributed in the hope that it will be useful,
                     15: # but WITHOUT ANY WARRANTY; without even the implied warranty of
                     16: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     17: # GNU General Public License for more details.
                     18: #
                     19: # You should have received a copy of the GNU General Public License
                     20: # along with LON-CAPA; if not, write to the Free Software
                     21: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     22: #
                     23: # /home/httpd/cgi-bin/graph.gif
                     24: #
                     25: # http://www.lon-capa.org/
                     26: #
1.1       minaeibi   27: # The LearningOnline Network with CAPA
1.22      matthew    28: #
1.1       minaeibi   29: # A CGI script that dynamically outputs a graphical chart for lonstatistics.
1.5       minaeibi   30: # 
                     31: #### 
1.22      matthew    32: 
                     33: =pod
                     34: 
                     35: =head1 NAME
                     36: 
                     37: graph.png
                     38: 
                     39: =head1 SYNOPSIS
                     40: 
                     41: produces plots based on input
                     42: 
                     43: =head1 DESCRIPTION
                     44: 
                     45: graph.png is a cgi-bin script which produces plots based on input data.
                     46: 
                     47: The query string is expected to be as follows (without whitespace):
                     48: 
                     49: escape(Plot title) & escape(X label)& escape(Y label) & Maximum Y value &
                     50: Number of bars & $data1 & $data2
                     51: 
                     52: $data1 and $data2 are expected to be comma seperated lists of numbers.
                     53: escape( value ) means the values must be run through lonnet::escape.
                     54: 
                     55: =cut
1.1       minaeibi   56: 
                     57: use strict;
1.24      matthew    58: use lib '/home/httpd/lib/perl';
1.9       minaeibi   59: use GD::Graph::bars;
1.29    ! matthew    60: use GD::Graph::lines;
1.1       minaeibi   61: use GD::Graph::colour;
                     62: use GD::Graph::Data;
1.24      matthew    63: use LONCAPA::loncgi();
1.1       minaeibi   64: 
1.21      matthew    65: sub unescape {
                     66:     my $str=shift;
                     67:     $str =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
                     68:     return $str;
                     69: }
                     70: 
1.29    ! matthew    71: sub error {
        !            72:     my ($error) = @_;
        !            73:     my $Str = <<"END";
        !            74: Content-type: text/html
        !            75: 
        !            76: <html>
        !            77: <head><title>Bad Graph</title></head>
        !            78: <body>
        !            79: <p>
        !            80: There was an error producing the graph you requested.
        !            81: </p><p>
        !            82: $error
        !            83: </p>
        !            84: </body>
        !            85: </html>
        !            86: END
        !            87:     return $Str;
        !            88: }
        !            89: 
        !            90: my $id = $ENV{'QUERY_STRING'};
        !            91: 
        !            92: #
        !            93: # &get_env($name,$default)
        !            94: sub get_env {
        !            95:     my $key = 'cgi.'.$id.'.'.(shift());
        !            96:     return shift if (! exists($ENV{$key}));
        !            97:     return $ENV{$key};
        !            98: }
        !            99: 
1.24      matthew   100: if (! &LONCAPA::loncgi::check_cookie_and_load_env()) {
                    101:     print <<END;
                    102: Content-type: text/html
                    103: 
                    104: <html>
                    105: <head><title>Bad Cookie</title></head>
                    106: <body>
1.28      matthew   107: Your cookie information is incorrect.
1.24      matthew   108: </body>
                    109: </html>
                    110: END
1.26      albertel  111:     exit;
1.24      matthew   112: }
                    113: 
1.4       matthew   114: $|=1;   # Autoflush after each print/write
1.1       minaeibi  115: 
1.29    ! matthew   116: my $colordefaults = join(',',
        !           117:                          ('#33ff00', 
        !           118:                           '#0033cc','#990000','#aaaa66','#663399','#ff9933',
        !           119:                           '#66ccff','#ff9999','#cccc33','#660000','#33cc66',
        !           120:                           ));
        !           121: 
        !           122: my $height   = &get_env('height',300);
        !           123: my $width    = &get_env('width', 400);
        !           124: my $PlotType = &get_env('PlotType','bar');
        !           125: 
        !           126: my %GraphSettings = (
        !           127:                      title           => &unescape(&get_env('title','')),
        !           128:                      x_label         => &unescape(&get_env('xlabel','')),
        !           129:                      y_label         => &unescape(&get_env('ylabel','')),
1.24      matthew   130:                      x_label_position => 0.5,
1.29    ! matthew   131:                      dclrs           => [split(',',&get_env('Colors',
        !           132:                                                             $colordefaults))],
1.24      matthew   133:                      fgclr           => 'black',
                    134:                      boxclr          => 'white',
                    135:                      accentclr       => 'dblue',
                    136:                      valuesclr       => '#ffff77',
                    137:                      l_margin        => 10,
                    138:                      b_margin        => 10,
                    139:                      r_margin        => 10,
                    140:                      t_margin        => 10,
                    141:                      transparent     => 0,
1.29    ! matthew   142:                      );
1.24      matthew   143: 
1.29    ! matthew   144: $GraphSettings{'x_label_skip'}  = &get_env('xskip',1);
        !           145: $GraphSettings{'x_tick_offset'} = &get_env('x_tick_offset',0);
        !           146: $GraphSettings{'y_max_value'}   = &get_env('Max',undef);
        !           147: 
        !           148: my $MyGraph;
        !           149: if ($PlotType eq 'bar') {
        !           150:     # Pick up bar graph settings
        !           151:     $GraphSettings{'bar_width'}     = &get_env('bar_width',undef);
        !           152:     $GraphSettings{'long_ticks'}    = 1;
        !           153:     $GraphSettings{'tick_length'}   = 0;
        !           154:     $GraphSettings{'x_ticks'}       = 0;
        !           155:     $GraphSettings{'cumulate'}      = 2;
        !           156:     $GraphSettings{'zero_axis'}     = 1;
        !           157: } else {
        !           158:     #
        !           159:     # X label skip setup
        !           160:     my $skip_x = &get_env('xskip',1);
        !           161:     my $x_tick_offset = &get_env('x_tick_offset',$skip_x-1);
        !           162:     my $zero_axis = &get_env('zero_axis',1);
        !           163:     #
        !           164:     # Fill up %GraphSettings
        !           165:     $GraphSettings{'long_ticks'}    = 1;
        !           166:     $GraphSettings{'tick_length'}   = 0;
        !           167:     $GraphSettings{'x_ticks'}       = &get_env('x_ticks',0),;
        !           168:     $GraphSettings{'x_label_skip'}  = $skip_x;
        !           169:     $GraphSettings{'x_tick_offset'} = $x_tick_offset;
        !           170:     $GraphSettings{'zero_axis'}     = 1;
        !           171: }
        !           172: #
        !           173: # Pick up miscellanious values passed in by the user
        !           174: #
        !           175: # Create the plot and check it out
        !           176: if ($PlotType eq 'bar') {
        !           177:     $MyGraph = GD::Graph::bars->new($width,$height);
        !           178: } else {
        !           179:     $MyGraph = GD::Graph::lines->new($width,$height);
        !           180: }
        !           181: if (! defined($MyGraph)) {
        !           182:     print &error('Unable to create initial graph');
1.24      matthew   183:     return;
                    184: }
1.1       minaeibi  185: 
1.29    ! matthew   186: ##
        !           187: ## Build the @Data array
        !           188: my $NumSets = &get_env('NumSets');
        !           189: my @Data;  # stores the data for the graph
        !           190: my @xlabels  = split(',',&get_env('labels'));
        !           191: push(@Data,\@xlabels);
        !           192: for (my $i=1;$i<=$NumSets;$i++) {
        !           193:     push(@Data,[split(',',&get_env('data.'.$i))]);
        !           194: }
1.24      matthew   195: 
1.29    ! matthew   196: my $error = '';
        !           197: if (! $MyGraph->set(%GraphSettings)) {
        !           198:     print &error($MyGraph->error);
1.24      matthew   199:     return;
                    200: }
1.1       minaeibi  201: 
1.29    ! matthew   202: my $plot = $MyGraph->plot(\@Data);
        !           203: if (! defined($plot)) {
        !           204:     my $error = 'Unable to plot the data provided.';
        !           205:     $error .= '<pre>'.join(',',@{$Data[0]}).'</pre>';
        !           206:     $error .= '<pre>'.join(',',@{$Data[1]}).'</pre>';
        !           207:     $error .= '<pre>'.join(',',@{$Data[2]}).'</pre>';
        !           208:     print &error($error);
        !           209:     exit;
        !           210: }
        !           211: 
1.24      matthew   212: my $BinaryData=$plot->png;
                    213: undef($MyGraph);
                    214: undef($plot);
                    215: 
                    216: if (! defined($BinaryData)) {
1.29    ! matthew   217:     print &error('Unable to render graph as image');
        !           218:     exit;
1.24      matthew   219: }
1.12      minaeibi  220: 
1.16      albertel  221: # Tell the server we are sending a png graphic
1.1       minaeibi  222: print <<END;
1.16      albertel  223: Content-type: image/png
1.1       minaeibi  224: 
                    225: END
                    226: 
                    227: binmode(STDOUT);
1.16      albertel  228: #open IMG,"|pngtopnm|ppmtogif 2>/dev/null"; # convert into a gif image
                    229: #print IMG $BinaryData; # output image
                    230: #$|=1; # be sure to flush before closing
                    231: #close IMG;
                    232: print $BinaryData;

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