[LON-CAPA-cvs] cvs: loncom /cgi graph.png /interface loncommon.pm
matthew
lon-capa-cvs@mail.lon-capa.org
Mon, 27 Oct 2003 21:21:08 -0000
This is a MIME encoded message
--matthew1067289668
Content-Type: text/plain
matthew Mon Oct 27 16:21:08 2003 EDT
Modified files:
/loncom/interface loncommon.pm
/loncom/cgi graph.png
Log:
Complete rewrite of how graph.png works and of the interface routines for
it in loncommon.pm. Added &DrawXYGraph which occasionally works.
--matthew1067289668
Content-Type: text/plain
Content-Disposition: attachment; filename="matthew-20031027162108.txt"
Index: loncom/interface/loncommon.pm
diff -u loncom/interface/loncommon.pm:1.135 loncom/interface/loncommon.pm:1.136
--- loncom/interface/loncommon.pm:1.135 Fri Oct 24 17:09:24 2003
+++ loncom/interface/loncommon.pm Mon Oct 27 16:21:08 2003
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# a pile of common routines
#
-# $Id: loncommon.pm,v 1.135 2003/10/24 21:09:24 albertel Exp $
+# $Id: loncommon.pm,v 1.136 2003/10/27 21:21:08 matthew Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -2678,6 +2678,10 @@
return undef;
}
+sub get_cgi_id {
+ return (time.'_'.int(rand(1000)));
+}
+
############################################################
############################################################
@@ -2685,7 +2689,6 @@
=item DrawBarGraph
-
=cut
############################################################
@@ -2700,7 +2703,8 @@
];
}
#
- my $identifier = time.'_'.int(rand(1000));
+ my $identifier = &get_cgi_id();
+ my $id = 'cgi.'.$identifier;
if (! @Values || ref($Values[0]) ne 'ARRAY') {
return '';
}
@@ -2709,16 +2713,50 @@
my $NumSets=1;
foreach my $array (@Values) {
next if (! ref($array));
- $ValuesHash{'cgi.'.$identifier.'.data.'.$NumSets++} =
+ $ValuesHash{$id.'.data.'.$NumSets++} =
join(',',@$array);
}
#
+ my ($height,$width,$xskip,$bar_width) = (200,120,1,15);
+ if ($NumBars < 10) {
+ $width = 120+$NumBars*15;
+ $xskip = 1;
+ $bar_width = 15;
+ } elsif ($NumBars <= 25) {
+ $width = 120+$NumBars*11;
+ $xskip = 5;
+ $bar_width = 8;
+ } elsif ($NumBars <= 50) {
+ $width = 120+$NumBars*8;
+ $xskip = 5;
+ $bar_width = 4;
+ } else {
+ $width = 120+$NumBars*8;
+ $xskip = 5;
+ $bar_width = 4;
+ }
+ #
+ my @Labels;
+ for (my $i=0;$i<@{$Values[0]};$i++) {
+ push (@Labels,$i+1);
+ }
+ #
$Title = '' if (! defined($Title));
$xlabel = '' if (! defined($xlabel));
$ylabel = '' if (! defined($ylabel));
- $Title = &Apache::lonnet::escape($Title);
- $xlabel = &Apache::lonnet::escape($xlabel);
- $ylabel = &Apache::lonnet::escape($ylabel);
+ $ValuesHash{$id.'.title'} = &Apache::lonnet::escape($Title);
+ $ValuesHash{$id.'.xlabel'} = &Apache::lonnet::escape($xlabel);
+ $ValuesHash{$id.'.ylabel'} = &Apache::lonnet::escape($ylabel);
+ $ValuesHash{$id.'.Max'} = $Max;
+ $ValuesHash{$id.'.NumBars'} = $NumBars;
+ $ValuesHash{$id.'.NumSets'} = $NumSets;
+ $ValuesHash{$id.'.PlotType'} = 'bar';
+ $ValuesHash{$id.'.Colors'} = join(',',@{$colors});
+ $ValuesHash{$id.'.height'} = $height;
+ $ValuesHash{$id.'.width'} = $width;
+ $ValuesHash{$id.'.xskip'} = $xskip;
+ $ValuesHash{$id.'.bar_width'} = $bar_width;
+ $ValuesHash{$id.'.labels'} = join(',',@Labels);
#
$Max = 1 if ($Max < 1);
if ( int($Max) < $Max ) {
@@ -2726,14 +2764,52 @@
$Max = int($Max);
}
#
- &Apache::lonnet::appenv('cgi.'.$identifier.'.title' => $Title,
- 'cgi.'.$identifier.'.xlabel' => $xlabel,
- 'cgi.'.$identifier.'.ylabel' => $ylabel,
- 'cgi.'.$identifier.'.Max' => $Max,
- 'cgi.'.$identifier.'.NumBars' => $NumBars,
- 'cgi.'.$identifier.'.NumSets' => $NumSets,
- 'cgi.'.$identifier.'.Colors' => join(',',@{$colors}),
- %ValuesHash);
+ &Apache::lonnet::appenv(%ValuesHash);
+ return '<img src="/cgi-bin/graph.png?'.$identifier.'" border="1" />';
+}
+
+############################################################
+############################################################
+
+=pod
+
+=item DrawXYGraph
+
+=cut
+
+############################################################
+############################################################
+sub DrawXYGraph {
+ my ($Title,$xlabel,$ylabel,$Max,$Xlabels,$Ydata,%Values)=@_;
+ #
+ # Create the identifier for the graph
+ my $identifier = &get_cgi_id();
+ my $id = 'cgi.'.$identifier;
+ #
+ $Title = '' if (! defined($Title));
+ $xlabel = '' if (! defined($xlabel));
+ $ylabel = '' if (! defined($ylabel));
+ my %ValuesHash =
+ (
+ $id.'.title' => &Apache::lonnet::escape($Title),
+ $id.'.xlabel' => &Apache::lonnet::escape($xlabel),
+ $id.'.ylabel' => &Apache::lonnet::escape($ylabel),
+ $id.'.Max' => $Max,
+ $id.'.labels' => join(',',@$Xlabels),
+ $id.'.PlotType' => 'XY',
+ $id.'.NumSets' => 2,
+ );
+ #
+ if (! ref($Ydata) || ref($Ydata) ne 'ARRAY') {
+ return '';
+ }
+ my $NumSets=1;
+ foreach my $array ($Ydata){
+ next if (! ref($array));
+ $ValuesHash{$id.'.data.'.$NumSets++} = join(',',@$array);
+ }
+ #
+ &Apache::lonnet::appenv(%ValuesHash);
return '<img src="/cgi-bin/graph.png?'.$identifier.'" border="1" />';
}
Index: loncom/cgi/graph.png
diff -u loncom/cgi/graph.png:1.28 loncom/cgi/graph.png:1.29
--- loncom/cgi/graph.png:1.28 Tue Oct 21 11:19:25 2003
+++ loncom/cgi/graph.png Mon Oct 27 16:21:08 2003
@@ -1,6 +1,6 @@
#!/usr/bin/perl
#
-# $Id: graph.png,v 1.28 2003/10/21 15:19:25 matthew Exp $
+# $Id: graph.png,v 1.29 2003/10/27 21:21:08 matthew Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -57,6 +57,7 @@
use strict;
use lib '/home/httpd/lib/perl';
use GD::Graph::bars;
+use GD::Graph::lines;
use GD::Graph::colour;
use GD::Graph::Data;
use LONCAPA::loncgi();
@@ -67,6 +68,35 @@
return $str;
}
+sub error {
+ my ($error) = @_;
+ my $Str = <<"END";
+Content-type: text/html
+
+<html>
+<head><title>Bad Graph</title></head>
+<body>
+<p>
+There was an error producing the graph you requested.
+</p><p>
+$error
+</p>
+</body>
+</html>
+END
+ return $Str;
+}
+
+my $id = $ENV{'QUERY_STRING'};
+
+#
+# &get_env($name,$default)
+sub get_env {
+ my $key = 'cgi.'.$id.'.'.(shift());
+ return shift if (! exists($ENV{$key}));
+ return $ENV{$key};
+}
+
if (! &LONCAPA::loncgi::check_cookie_and_load_env()) {
print <<END;
Content-type: text/html
@@ -82,75 +112,24 @@
}
$|=1; # Autoflush after each print/write
-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
-my @xlabels;
-for (my $nIdx=0; $nIdx<$NumBars; $nIdx++ ) {
- $xlabels[$nIdx]=$nIdx+1;
-}
-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;
-my $bar_width=10;
-
-#
-# Customize graph based on the
-my $width;
-my $height = 200;
-
-if ($NumBars < 10) {
- $width = 120+$NumBars*15;
- $skip_x = 1;
- $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;
-if ($skip_x > 1) {
- $x_tick_offset = $skip_x - 1;
-}
-
-my $MyGraph = GD::Graph::bars->new($width,$height);
-my $error = '';
-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,
- long_ticks => 1,
- tick_length => 0,
- 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,
+ dclrs => [split(',',&get_env('Colors',
+ $colordefaults))],
fgclr => 'black',
boxclr => 'white',
accentclr => 'dblue',
@@ -159,60 +138,85 @@
b_margin => 10,
r_margin => 10,
t_margin => 10,
- #
transparent => 0,
- )) {
- $error = $MyGraph->error;
- print <<"END";
-Content-type: text/html
+ );
-<html>
-<head><title>Bad Graph</title></head>
-<body>
-<p>
-There was an error producing the graph you requested.
-</p><p>
-$error
-</p>
-</body>
-</html>
-END
+$GraphSettings{'x_label_skip'} = &get_env('xskip',1);
+$GraphSettings{'x_tick_offset'} = &get_env('x_tick_offset',0);
+$GraphSettings{'y_max_value'} = &get_env('Max',undef);
+
+my $MyGraph;
+if ($PlotType eq 'bar') {
+ # Pick up bar graph settings
+ $GraphSettings{'bar_width'} = &get_env('bar_width',undef);
+ $GraphSettings{'long_ticks'} = 1;
+ $GraphSettings{'tick_length'} = 0;
+ $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;
+}
+#
+# 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;
}
-my $plot = $MyGraph->plot(\@data);
-if (! defined($plot)) {
- print <<"END";
-Content-type: text/html
+##
+## Build the @Data array
+my $NumSets = &get_env('NumSets');
+my @Data; # stores the data for the graph
+my @xlabels = split(',',&get_env('labels'));
+push(@Data,\@xlabels);
+for (my $i=1;$i<=$NumSets;$i++) {
+ push(@Data,[split(',',&get_env('data.'.$i))]);
+}
-<html>
-<head><title>Bad Graph</title></head>
-<body>
-The system was unable to create the graph you requested.
-</body>
-</html>
-END
+my $error = '';
+if (! $MyGraph->set(%GraphSettings)) {
+ print &error($MyGraph->error);
return;
}
+my $plot = $MyGraph->plot(\@Data);
+if (! defined($plot)) {
+ my $error = 'Unable to plot the data provided.';
+ $error .= '<pre>'.join(',',@{$Data[0]}).'</pre>';
+ $error .= '<pre>'.join(',',@{$Data[1]}).'</pre>';
+ $error .= '<pre>'.join(',',@{$Data[2]}).'</pre>';
+ print &error($error);
+ exit;
+}
+
my $BinaryData=$plot->png;
undef($MyGraph);
undef($plot);
if (! defined($BinaryData)) {
- print <<"END";
-Content-type: text/html
-
-<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;
+ print &error('Unable to render graph as image');
+ exit;
}
-
# Tell the server we are sending a png graphic
print <<END;
--matthew1067289668--