--- loncom/xml/lonplot.pm 2001/12/18 15:33:47 1.2
+++ loncom/xml/lonplot.pm 2001/12/20 20:24:36 1.11
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Dynamic plot
#
-# $Id: lonplot.pm,v 1.2 2001/12/18 15:33:47 matthew Exp $
+# $Id: lonplot.pm,v 1.11 2001/12/20 20:24:36 matthew Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -25,75 +25,100 @@
#
# http://www.lon-capa.org/
#
-# 2/21 Guy
+# 12/15/01 Matthew
+# 12/18 12/19 12/20 Matthew
package Apache::lonplot;
+
use strict;
+use Apache::File;
use Apache::response;
use Apache::lonxml;
+
use Digest::MD5 qw(md5 md5_hex md5_base64);
sub BEGIN {
&Apache::lonxml::register('Apache::lonplot',('plot'));
}
-
+##
+## Description of data structures:
+##
+## %plot %key %axis
+## --------------------------
+## height title color
+## width box xmin
+## bgcolor pos xmax
+## fgcolor ymin
+## transparent ymax
+## grid
+## border
+## font
+##
+## @labels: $labels[$i] = \%label
+## %label: text, xpos, ypos, justify
+##
+## @curves: $curves[$i] = \%curve
+## %curve: name, linestyle, ( function | data )
+##
+## $curves[$i]->{'data'} = [ [x1,x2,x3,x4],
+## [y1,y2,y3,y4] ]
+##
+##------------------------------------------------------------
##
## Tests used in checking the validitity of input
##
-my $int_test = sub {$_[0]=~/^\d+$/};
-my $real_test = sub {$_[0]=~/^[+-]?\d*\.?\d*$/};
-my $color_test = sub {$_[0]=~/^x[\da-f]{6}$/};
+my $int_test = sub {$_[0]=~s/\s+//g;$_[0]=~/^\d+$/};
+my $real_test = sub {$_[0]=~s/\s+//g;$_[0]=~/^[+-]?\d*\.?\d*$/};
+my $color_test = sub {$_[0]=~s/\s+//g;$_[0]=~/^x[\da-f]{6}$/};
my $onoff_test = sub {$_[0]=~/^(on|off)$/};
my $key_pos_test = sub {$_[0]=~/^(top|bottom|right|left|outside|below)+$/};
my $sml_test = sub {$_[0]=~/^(small|medium|large)$/};
my $linestyle_test = sub {$_[0]=~/^(lines|linespoints|dots|points|steps)$/};
-
+my $words_test = sub {$_[0]=~s/\s+/ /g;$_[0]=~/^(\w+ ?)+$/};
##
## Default values for attributes of elements
##
my %plot_defaults =
(
- height => {default => 200, test => $int_test },
- width => {default => 200, test => $int_test },
- bgcolor => {default => "xffffff", test => $color_test},
- fgcolor => {default => "x000000", test => $color_test},
- transparent => {default => "off", test => $onoff_test},
- grid => {default => "off", test => $onoff_test},
- border => {default => "on" , test => $onoff_test},
- font => {default => "medium", test => $sml_test }
+ height => {default => 200, test => $int_test },
+ width => {default => 200, test => $int_test },
+ bgcolor => {default => 'xffffff', test => $color_test },
+ fgcolor => {default => 'x000000', test => $color_test },
+ transparent => {default => 'off', test => $onoff_test },
+ grid => {default => 'off', test => $onoff_test },
+ border => {default => 'on', test => $onoff_test },
+ font => {default => 'medium', test => $sml_test }
);
my %key_defaults =
(
- title => { default => "on" , test => $onoff_test },
- box => { default => "off" , test => $onoff_test },
- pos => { default => "top right" , test => $key_pos_test}
+ title => { default => '', test => $words_test },
+ box => { default => 'off', test => $onoff_test },
+ pos => { default => 'top right', test => $key_pos_test }
);
my %label_defaults =
(
- xpos => {default => 0, test => $real_test },
- ypos => {default => 0, test => $real_test },
- color => {default => "x000000", test => $color_test },
- justify => {default => "left",
- test => sub {$_[0]=~/^(left|right|center)$/}}
+ xpos => {default => 0, test => $real_test },
+ ypos => {default => 0, test => $real_test },
+ justify => {default => 'left',
+ test => sub {$_[0]=~/^(left|right|center)$/} }
);
my %axis_defaults =
(
- color => {default => "x000000", test => $color_test},
- thickness => {default => 1, test => $int_test },
- xmin => {default => -10.0, test => $real_test },
- xmax => {default => 10.0, test => $real_test },
- ymin => {default => -10.0, test => $real_test },
- ymax => {default => 10.0, test => $real_test }
+ color => {default => 'x000000', test => $color_test},
+ xmin => {default => '-10.0', test => $real_test },
+ xmax => {default => ' 10.0', test => $real_test },
+ ymin => {default => '-10.0', test => $real_test },
+ ymax => {default => ' 10.0', test => $real_test }
);
my %curve_defaults =
(
- color => {default => "x000000", test => $color_test },
- name => {default => "x000000", test => sub {$_[0]=~/^[\w ]*$/} },
- linestyle => {default => "lines", test => $linestyle_test }
+ color => {default => 'x000000', test => $color_test },
+ name => {default => 'x000000', test => sub {1} },#sub {$_[0]=~/^[\w ]*$/} },
+ linestyle => {default => 'lines', test => $linestyle_test }
);
##
@@ -102,45 +127,49 @@ my %curve_defaults =
my (%plot,%key,%axis,$title,$xlabel,$ylabel,@labels,@curves);
sub start_plot {
- %plot = ''; %key=''; %axis='';
- $title=''; $xlabel=''; $ylabel='';
- @labels = ''; @curves='';
-
+ %plot = undef; %key = undef; %axis = undef;
+ $title = undef; $xlabel = undef; $ylabel = undef;
+ $#labels = -1; $#curves = -1;
+ #
my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
my $result='';
- &Apache::lonxml::register('Apache::plot',
+ &Apache::lonxml::register('Apache::lonplot',
('title','xlabel','ylabel','key','axis','label','curve'));
push (@Apache::lonxml::namespace,'plot');
- ##-------------------------------------------------------
- ## How do I do this? I need to "eval" and I need to keep the info
- ## available for the parser.
- ##
+ ## Always evaluate the insides of the
'; + $result .= &write_gnuplot_file($fh); + $result .= ''.$/; + ## return image tag for the plot + $result .= ''; + } return $result; } @@ -148,13 +177,20 @@ sub end_plot { sub start_key { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result=''; - &get_attributes(\%key,\%key_defaults,$parstack,$safeeval,'key'); + &get_attributes(\%key,\%key_defaults,$parstack,$safeeval, + $tagstack->[-1]); + if ($target eq 'web') { + # This routine should never return anything. + } return $result; } sub end_key { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result = ''; + if ($target eq 'web') { + # This routine should never return anything. + } return $result; } ##------------------------------------------------------------------- title @@ -162,12 +198,18 @@ sub start_title { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; $title = &Apache::lonxml::get_all_text("/title",$$parser[-1]); my $result=''; + if ($target eq 'web') { + # This routine should never return anything. + } return $result; } sub end_title { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result = ''; + if ($target eq 'web') { + # This routine should never return anything. + } return $result; } ##------------------------------------------------------------------- xlabel @@ -175,12 +217,18 @@ sub start_xlabel { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result=''; $xlabel = &Apache::lonxml::get_all_text("/xlabel",$$parser[-1]); + if ($target eq 'web') { + # This routine should never return anything. + } return $result; } sub end_xlabel { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result = ''; + if ($target eq 'web') { + # This routine should never return anything. + } return $result; } ##------------------------------------------------------------------- ylabel @@ -188,28 +236,45 @@ sub start_ylabel { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result=''; $ylabel = &Apache::lonxml::get_all_text("/ylabel",$$parser[-1]); + if ($target eq 'web') { + # This routine should never return anything. + } return $result; } sub end_ylabel { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result = ''; + if ($target eq 'web') { + # This routine should never return anything. + } return $result; } ##------------------------------------------------------------------- label sub start_label { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result=''; - my $label = &newhashref(); - &get_attributes($label,\%label_defaults,$parstack,$safeeval,'label'); - $label->{'text'} = &Apache::lonxml::get_all_text("/label",$$parser[-1]); - push(@labels,$label); + my %label; + &get_attributes(\%label,\%label_defaults,$parstack,$safeeval, + $tagstack->[-1]); + $label{'text'} = &Apache::lonxml::get_all_text("/label",$$parser[-1]); + if (! &$words_test($label{'text'})) { + # I should probably warn about it, too. + $label{'text'} = 'Illegal text'; + } + push(@labels,\%label); + if ($target eq 'web') { + # This routine should never return anything. + } return $result; } sub end_label { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result = ''; + if ($target eq 'web') { + # This routine should never return anything. + } return $result; } @@ -217,50 +282,92 @@ sub end_label { sub start_curve { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result=''; - my $curve = &newhashref(); - &get_attributes($curve,\%curve_defaults,$parstack,$safeeval,'curve'); - push (@curves,$curve); - - &Apache::lonxml::register('Apache::plot',('function','data')); + my %curve; + &get_attributes(\%curve,\%curve_defaults,$parstack,$safeeval, + $tagstack->[-1]); + push (@curves,\%curve); + &Apache::lonxml::register('Apache::lonplot',('function','data')); push (@Apache::lonxml::namespace,'curve'); - + if ($target eq 'web') { + # This routine should never return anything. + } return $result; } sub end_curve { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result = ''; + pop @Apache::lonxml::namespace; + &Apache::lonxml::deregister('Apache::lonplot',('function','data')); + if ($target eq 'web') { + # This routine should never return anything. + } return $result; } - ##------------------------------------------------------------ curve function sub start_function { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result=''; - + if (exists($curves[-1]->{'data'})) { + &Apache::lonxml::warning('Use of