version 1.36, 2002/01/09 16:58:18
|
version 1.43, 2002/01/21 17:23:31
|
Line 29
|
Line 29
|
# 12/17 12/18 12/19 12/20 12/21 12/27 12/28 12/30 12/31 Matthew |
# 12/17 12/18 12/19 12/20 12/21 12/27 12/28 12/30 12/31 Matthew |
# 01/01/02 Matthew |
# 01/01/02 Matthew |
# 01/02 01/03 01/04 01/07 01/08 01/09 Matthew |
# 01/02 01/03 01/04 01/07 01/08 01/09 Matthew |
|
# 01/21 Matthew |
|
|
# Current issues |
|
# 1. Gnuplot is unable to vary the color or linestyle of <data> plots. |
|
# The key does not know this so it is misleading for the user. |
|
# Multiple <function>s can be plotted with varying line styles and |
|
# colors. |
|
# |
|
package Apache::lonplot; |
package Apache::lonplot; |
|
|
use strict; |
use strict; |
Line 119 my $words_test = sub {$_[0]=~s/\s+/
|
Line 114 my $words_test = sub {$_[0]=~s/\s+/
|
## ## |
## ## |
################################################################### |
################################################################### |
my @plot_edit_order = |
my @plot_edit_order = |
qw/bgcolor fgcolor height width font transparent grid border/; |
qw/bgcolor fgcolor height width font transparent grid border align/; |
my %plot_defaults = |
my %plot_defaults = |
( |
( |
height => { |
height => { |
default => 200, |
default => 200, |
test => $int_test, |
test => $int_test, |
description => 'height of image (pixels)', |
description => 'height of image (pixels)', |
edit_type => 'entry' |
edit_type => 'entry', |
|
size => '10' |
}, |
}, |
width => { |
width => { |
default => 200, |
default => 200, |
test => $int_test, |
test => $int_test, |
description => 'width of image (pixels)', |
description => 'width of image (pixels)', |
edit_type => 'entry' |
edit_type => 'entry', |
|
size => '10' |
}, |
}, |
bgcolor => { |
bgcolor => { |
default => 'xffffff', |
default => 'xffffff', |
test => $color_test, |
test => $color_test, |
description => 'background color of image (xffffff)', |
description => 'background color of image (xffffff)', |
edit_type => 'entry' |
edit_type => 'entry', |
|
size => '10' |
}, |
}, |
fgcolor => { |
fgcolor => { |
default => 'x000000', |
default => 'x000000', |
test => $color_test, |
test => $color_test, |
description => 'foreground color of image (x000000)', |
description => 'foreground color of image (x000000)', |
edit_type => 'entry' |
edit_type => 'entry', |
|
size => '10' |
}, |
}, |
transparent => { |
transparent => { |
default => 'off', |
default => 'off', |
Line 186 my %key_defaults =
|
Line 185 my %key_defaults =
|
default => '', |
default => '', |
test => $words_test, |
test => $words_test, |
description => 'Title of key', |
description => 'Title of key', |
edit_type => 'entry' |
edit_type => 'entry', |
|
size => '40' |
}, |
}, |
box => { |
box => { |
default => 'off', |
default => 'off', |
Line 210 my %label_defaults =
|
Line 210 my %label_defaults =
|
default => 0, |
default => 0, |
test => $real_test, |
test => $real_test, |
description => 'x position of label (graph coordinates)', |
description => 'x position of label (graph coordinates)', |
edit_type => 'entry' |
edit_type => 'entry', |
|
size => '10' |
}, |
}, |
ypos => { |
ypos => { |
default => 0, |
default => 0, |
test => $real_test, |
test => $real_test, |
description => 'y position of label (graph coordinates)', |
description => 'y position of label (graph coordinates)', |
edit_type => 'entry' |
edit_type => 'entry', |
|
size => '10' |
}, |
}, |
justify => { |
justify => { |
default => 'left', |
default => 'left', |
Line 233 my %axis_defaults =
|
Line 235 my %axis_defaults =
|
default => 'x000000', |
default => 'x000000', |
test => $color_test, |
test => $color_test, |
description => 'color of axes (x000000)', |
description => 'color of axes (x000000)', |
edit_type => 'entry' |
edit_type => 'entry', |
|
size => '10' |
}, |
}, |
xmin => { |
xmin => { |
default => '-10.0', |
default => '-10.0', |
test => $real_test, |
test => $real_test, |
description => 'minimum x-value shown in plot', |
description => 'minimum x-value shown in plot', |
edit_type => 'entry' |
edit_type => 'entry', |
|
size => '10' |
}, |
}, |
xmax => { |
xmax => { |
default => ' 10.0', |
default => ' 10.0', |
test => $real_test, |
test => $real_test, |
description => 'maximum x-value shown in plot', |
description => 'maximum x-value shown in plot', |
edit_type => 'entry' |
edit_type => 'entry', |
|
size => '10' |
}, |
}, |
ymin => { |
ymin => { |
default => '-10.0', |
default => '-10.0', |
test => $real_test, |
test => $real_test, |
description => 'minimum y-value shown in plot', |
description => 'minimum y-value shown in plot', |
edit_type => 'entry' |
edit_type => 'entry', |
|
size => '10' |
}, |
}, |
ymax => { |
ymax => { |
default => ' 10.0', |
default => ' 10.0', |
test => $real_test, |
test => $real_test, |
description => 'maximum y-value shown in plot', |
description => 'maximum y-value shown in plot', |
edit_type => 'entry' |
edit_type => 'entry', |
|
size => '10' |
} |
} |
); |
); |
|
|
Line 267 my %curve_defaults =
|
Line 274 my %curve_defaults =
|
default => 'x000000', |
default => 'x000000', |
test => $color_test, |
test => $color_test, |
description => 'color of curve (x000000)', |
description => 'color of curve (x000000)', |
edit_type => 'entry' |
edit_type => 'entry', |
|
size => '10' |
}, |
}, |
name => { |
name => { |
default => '', |
default => '', |
test => $words_test, |
test => $words_test, |
description => 'name of curve to appear in key', |
description => 'name of curve to appear in key', |
edit_type => 'entry' |
edit_type => 'entry', |
|
size => '20' |
}, |
}, |
linestyle => { |
linestyle => { |
default => 'lines', |
default => 'lines', |
test => $linestyle_test, |
test => $linestyle_test, |
description => 'Line style', |
description => 'Line style', |
edit_type => 'choice', |
edit_type => 'choice', |
choices => ['lines','linespoints','dots','points','steps', |
choices => [keys(%linestyles)] |
'fsteps','histeps','errorbars','xerrorbars', |
|
'yerrorbars','xyerrorbars','boxes','boxerrorbars', |
|
'boxxyerrorbars','financebars','candlesticks', |
|
'vector'] |
|
} |
} |
); |
); |
|
|
Line 320 sub start_plot {
|
Line 325 sub start_plot {
|
($token,$parstack,$safeeval,keys(%plot_defaults)); |
($token,$parstack,$safeeval,keys(%plot_defaults)); |
if ($constructtag) { |
if ($constructtag) { |
$result = &Apache::edit::rebuild_tag($token); |
$result = &Apache::edit::rebuild_tag($token); |
# $result.= &Apache::edit::handle_insert(); |
|
} |
} |
} |
} |
return $result; |
return $result; |
Line 341 sub end_plot {
|
Line 345 sub end_plot {
|
my $filename = $ENV{'user.name'}.'_'.$ENV{'user.domain'}. |
my $filename = $ENV{'user.name'}.'_'.$ENV{'user.domain'}. |
'_'.time.'_'.$$.int(rand(1000)).'_plot.data'; |
'_'.time.'_'.$$.int(rand(1000)).'_plot.data'; |
## Write the plot description to the file |
## Write the plot description to the file |
my $fh=Apache::File->new(">$tmpdir$filename"); |
&write_gnuplot_file($tmpdir,$filename); |
print $fh &write_gnuplot_file(); |
|
close($fh); |
|
## return image tag for the plot |
## return image tag for the plot |
$result .= <<"ENDIMAGE"; |
$result .= <<"ENDIMAGE"; |
<img src = "/cgi-bin/plot.gif?$filename" |
<img src = "/cgi-bin/plot.gif?$filename" |
Line 373 sub start_key {
|
Line 375 sub start_key {
|
($token,$parstack,$safeeval,keys(%key_defaults)); |
($token,$parstack,$safeeval,keys(%key_defaults)); |
if ($constructtag) { |
if ($constructtag) { |
$result = &Apache::edit::rebuild_tag($token); |
$result = &Apache::edit::rebuild_tag($token); |
$result.= &Apache::edit::handle_insert(); |
|
} |
} |
} |
} |
return $result; |
return $result; |
Line 401 sub start_title {
|
Line 402 sub start_title {
|
} elsif ($target eq 'edit') { |
} elsif ($target eq 'edit') { |
$result.=&Apache::edit::tag_start($target,$token,'Plot Title'); |
$result.=&Apache::edit::tag_start($target,$token,'Plot Title'); |
my $text=&Apache::lonxml::get_all_text("/title",$$parser[-1]); |
my $text=&Apache::lonxml::get_all_text("/title",$$parser[-1]); |
$result.='</td></tr><tr><td colspan="3">'. |
$result.=&Apache::edit::end_row(). |
|
&Apache::edit::start_spanning_row(). |
&Apache::edit::editfield('',$text,'',60,1); |
&Apache::edit::editfield('',$text,'',60,1); |
} elsif ($target eq 'modified') { |
} elsif ($target eq 'modified') { |
my $text=$$parser[-1]->get_text("/title"); |
my $text=$$parser[-1]->get_text("/title"); |
|
$result.=&Apache::edit::rebuild_tag($token); |
$result.=&Apache::edit::modifiedfield($token); |
$result.=&Apache::edit::modifiedfield($token); |
} |
} |
return $result; |
return $result; |
Line 431 sub start_xlabel {
|
Line 434 sub start_xlabel {
|
} elsif ($target eq 'edit') { |
} elsif ($target eq 'edit') { |
$result.=&Apache::edit::tag_start($target,$token,'Plot Xlabel'); |
$result.=&Apache::edit::tag_start($target,$token,'Plot Xlabel'); |
my $text=&Apache::lonxml::get_all_text("/xlabel",$$parser[-1]); |
my $text=&Apache::lonxml::get_all_text("/xlabel",$$parser[-1]); |
$result.='</td></tr><tr><td colspan="3">'. |
$result.=&Apache::edit::end_row(). |
|
&Apache::edit::start_spanning_row(). |
&Apache::edit::editfield('',$text,'',60,1); |
&Apache::edit::editfield('',$text,'',60,1); |
} elsif ($target eq 'modified') { |
} elsif ($target eq 'modified') { |
my $text=$$parser[-1]->get_text("/xlabel"); |
my $text=$$parser[-1]->get_text("/xlabel"); |
|
$result.=&Apache::edit::rebuild_tag($token); |
$result.=&Apache::edit::modifiedfield($token); |
$result.=&Apache::edit::modifiedfield($token); |
} |
} |
return $result; |
return $result; |
Line 462 sub start_ylabel {
|
Line 467 sub start_ylabel {
|
} elsif ($target eq 'edit') { |
} elsif ($target eq 'edit') { |
$result .= &Apache::edit::tag_start($target,$token,'Plot Ylabel'); |
$result .= &Apache::edit::tag_start($target,$token,'Plot Ylabel'); |
my $text = &Apache::lonxml::get_all_text("/ylabel",$$parser[-1]); |
my $text = &Apache::lonxml::get_all_text("/ylabel",$$parser[-1]); |
$result .= '</td></tr><tr><td colspan="3">'. |
$result .= &Apache::edit::end_row(). |
|
&Apache::edit::start_spanning_row(). |
&Apache::edit::editfield('',$text,'',60,1); |
&Apache::edit::editfield('',$text,'',60,1); |
} elsif ($target eq 'modified') { |
} elsif ($target eq 'modified') { |
my $text=$$parser[-1]->get_text("/ylabel"); |
my $text=$$parser[-1]->get_text("/ylabel"); |
|
$result.=&Apache::edit::rebuild_tag($token); |
$result.=&Apache::edit::modifiedfield($token); |
$result.=&Apache::edit::modifiedfield($token); |
} |
} |
return $result; |
return $result; |
Line 497 sub start_label {
|
Line 504 sub start_label {
|
$result .= &Apache::edit::tag_start($target,$token,'Plot Label'); |
$result .= &Apache::edit::tag_start($target,$token,'Plot Label'); |
$result .= &edit_attributes($target,$token,\%label_defaults); |
$result .= &edit_attributes($target,$token,\%label_defaults); |
my $text = &Apache::lonxml::get_all_text("/label",$$parser[-1]); |
my $text = &Apache::lonxml::get_all_text("/label",$$parser[-1]); |
$result .= '</td></tr><tr><td colspan="3">'. |
$result .= &Apache::edit::end_row(). |
|
&Apache::edit::start_spanning_row(). |
&Apache::edit::editfield('',$text,'',60,1); |
&Apache::edit::editfield('',$text,'',60,1); |
} elsif ($target eq 'modified') { |
} elsif ($target eq 'modified') { |
my $constructtag=&Apache::edit::get_new_args |
&Apache::edit::get_new_args |
($token,$parstack,$safeeval,keys(%label_defaults)); |
($token,$parstack,$safeeval,keys(%label_defaults)); |
if ($constructtag) { |
$result.=&Apache::edit::rebuild_tag($token); |
$result = &Apache::edit::rebuild_tag($token); |
|
$result.= &Apache::edit::handle_insert(); |
|
} |
|
my $text=$$parser[-1]->get_text("/label"); |
my $text=$$parser[-1]->get_text("/label"); |
$result.=&Apache::edit::modifiedfield($token); |
$result.=&Apache::edit::modifiedfield($token); |
} |
} |
Line 571 sub start_function {
|
Line 576 sub start_function {
|
$curves[-1]->{'function'} = |
$curves[-1]->{'function'} = |
&Apache::lonxml::get_all_text("/function",$$parser[-1]); |
&Apache::lonxml::get_all_text("/function",$$parser[-1]); |
} elsif ($target eq 'edit') { |
} elsif ($target eq 'edit') { |
$result .= &Apache::edit::tag_start($target,$token,'Curve Function'); |
$result .= &Apache::edit::tag_start($target,$token,'Gnuplot compatible curve function'); |
my $text = &Apache::lonxml::get_all_text("/function",$$parser[-1]); |
my $text = &Apache::lonxml::get_all_text("/function",$$parser[-1]); |
$result .= '</td></tr><tr><td colspan="3">'. |
$result .= &Apache::edit::end_row(). |
|
&Apache::edit::start_spanning_row(). |
&Apache::edit::editfield('',$text,'',60,1); |
&Apache::edit::editfield('',$text,'',60,1); |
} elsif ($target eq 'modified') { |
} elsif ($target eq 'modified') { |
# Why do I do this? |
$result.=&Apache::edit::rebuild_tag($token); |
my $text=$$parser[-1]->get_text("/function"); |
my $text=$$parser[-1]->get_text("/function"); |
$result.=&Apache::edit::modifiedfield($token); |
$result.=&Apache::edit::modifiedfield($token); |
} |
} |
Line 605 sub start_data {
|
Line 611 sub start_data {
|
delete($curves[-1]->{'function'}); |
delete($curves[-1]->{'function'}); |
} |
} |
my $datatext = &Apache::lonxml::get_all_text("/data",$$parser[-1]); |
my $datatext = &Apache::lonxml::get_all_text("/data",$$parser[-1]); |
|
# Deal with cases where we're given an array... |
|
if ($datatext =~ /^\@/) { |
|
$datatext = &Apache::run::run('return "'.$datatext.'"', |
|
$safeeval,1); |
|
} |
$datatext =~ s/\s+/ /g; |
$datatext =~ s/\s+/ /g; |
# Need to do some error checking on the @data array - |
# Need to do some error checking on the @data array - |
# make sure it's all numbers and make sure each array |
# make sure it's all numbers and make sure each array |
Line 640 sub start_data {
|
Line 651 sub start_data {
|
} |
} |
push @{$curves[-1]->{'data'}},\@data; |
push @{$curves[-1]->{'data'}},\@data; |
} elsif ($target eq 'edit') { |
} elsif ($target eq 'edit') { |
$result .= &Apache::edit::tag_start($target,$token,'Curve Data'); |
$result .= &Apache::edit::tag_start($target,$token,'Comma or space deliminated curve data'); |
my $text = &Apache::lonxml::get_all_text("/data",$$parser[-1]); |
my $text = &Apache::lonxml::get_all_text("/data",$$parser[-1]); |
$result .= '</td></tr><tr><td colspan="3">'. |
$result .= &Apache::edit::end_row(). |
|
&Apache::edit::start_spanning_row(). |
&Apache::edit::editfield('',$text,'',60,1); |
&Apache::edit::editfield('',$text,'',60,1); |
} elsif ($target eq 'modified') { |
} elsif ($target eq 'modified') { |
|
$result.=&Apache::edit::rebuild_tag($token); |
my $text=$$parser[-1]->get_text("/data"); |
my $text=$$parser[-1]->get_text("/data"); |
$result.=&Apache::edit::modifiedfield($token); |
$result.=&Apache::edit::modifiedfield($token); |
} |
} |
Line 676 sub start_axis {
|
Line 689 sub start_axis {
|
($token,$parstack,$safeeval,keys(%axis_defaults)); |
($token,$parstack,$safeeval,keys(%axis_defaults)); |
if ($constructtag) { |
if ($constructtag) { |
$result = &Apache::edit::rebuild_tag($token); |
$result = &Apache::edit::rebuild_tag($token); |
$result.= &Apache::edit::handle_insert(); |
|
} |
} |
} |
} |
return $result; |
return $result; |
Line 728 sub get_attributes{
|
Line 740 sub get_attributes{
|
} |
} |
return ; |
return ; |
} |
} |
|
|
##------------------------------------------------------- write_gnuplot_file |
##------------------------------------------------------- write_gnuplot_file |
sub write_gnuplot_file { |
sub write_gnuplot_file { |
|
my ($tmpdir,$filename)= @_; |
my $gnuplot_input = ''; |
my $gnuplot_input = ''; |
my $curve; |
my $curve; |
# Collect all the colors |
# Collect all the colors |
Line 766 sub write_gnuplot_file {
|
Line 780 sub write_gnuplot_file {
|
if (%key) { |
if (%key) { |
$gnuplot_input .= 'set key '.$key{'pos'}.' '; |
$gnuplot_input .= 'set key '.$key{'pos'}.' '; |
if ($key{'title'} ne '') { |
if ($key{'title'} ne '') { |
$gnuplot_input .= 'title "'.$key{'title'}.'" '; |
$gnuplot_input .= 'title " '.$key{'title'}.'" '; |
} |
} |
$gnuplot_input .= ($key{'box'} eq 'on' ? 'box ' : 'nobox ').$/; |
$gnuplot_input .= ($key{'box'} eq 'on' ? 'box ' : 'nobox ').$/; |
} else { |
} else { |
Line 780 sub write_gnuplot_file {
|
Line 794 sub write_gnuplot_file {
|
} |
} |
# curves |
# curves |
$gnuplot_input .= 'plot '; |
$gnuplot_input .= 'plot '; |
my $datatext = ''; |
|
for (my $i = 0;$i<=$#curves;$i++) { |
for (my $i = 0;$i<=$#curves;$i++) { |
$curve = $curves[$i]; |
$curve = $curves[$i]; |
$gnuplot_input.= ', ' if ($i > 0); |
$gnuplot_input.= ', ' if ($i > 0); |
Line 790 sub write_gnuplot_file {
|
Line 803 sub write_gnuplot_file {
|
$curve->{'name'}.'" with '. |
$curve->{'name'}.'" with '. |
$curve->{'linestyle'}; |
$curve->{'linestyle'}; |
} elsif (exists($curve->{'data'})) { |
} elsif (exists($curve->{'data'})) { |
$gnuplot_input.= '\'-\' title "'. |
# Store data values in $datatext |
$curve->{'name'}.'" with '. |
my $datatext = ''; |
$curve->{'linestyle'}; |
# get new filename |
|
my $datafilename = "$tmpdir/$filename.$i"; |
|
my $fh=Apache::File->new(">$datafilename"); |
|
# Compile data |
my @Data = @{$curve->{'data'}}; |
my @Data = @{$curve->{'data'}}; |
my @Data0 = @{$Data[0]}; |
my @Data0 = @{$Data[0]}; |
for (my $i =0; $i<=$#Data0; $i++) { |
for (my $i =0; $i<=$#Data0; $i++) { |
Line 802 sub write_gnuplot_file {
|
Line 818 sub write_gnuplot_file {
|
} |
} |
$datatext .= $/; |
$datatext .= $/; |
} |
} |
$datatext .=$/; |
# write file |
|
print $fh $datatext; |
|
close ($fh); |
|
# generate gnuplot text |
|
$gnuplot_input.= '"'.$datafilename.'" title "'. |
|
$curve->{'name'}.'" with '. |
|
$curve->{'linestyle'}; |
} |
} |
} |
} |
$gnuplot_input .= $/.$datatext; |
# Write the output to a file. |
return $gnuplot_input; |
my $fh=Apache::File->new(">$tmpdir$filename"); |
|
print $fh $gnuplot_input; |
|
close($fh); |
|
# That's all folks. |
|
return ; |
} |
} |
|
|
#---------------------------------------------- check_inputs |
#---------------------------------------------- check_inputs |
Line 848 sub edit_attributes {
|
Line 874 sub edit_attributes {
|
$description .= ' ' if ($description !~ / $/); |
$description .= ' ' if ($description !~ / $/); |
if ($defaults->{$attr}->{'edit_type'} eq 'entry') { |
if ($defaults->{$attr}->{'edit_type'} eq 'entry') { |
$result .= &Apache::edit::text_arg |
$result .= &Apache::edit::text_arg |
($description,$attr,$token); |
($description,$attr,$token, |
|
$defaults->{$attr}->{'size'}); |
} elsif ($defaults->{$attr}->{'edit_type'} eq 'choice') { |
} elsif ($defaults->{$attr}->{'edit_type'} eq 'choice') { |
$result .= &Apache::edit::select_arg |
$result .= &Apache::edit::select_arg |
($description,$attr,$defaults->{$attr}->{'choices'},$token); |
($description,$attr,$defaults->{$attr}->{'choices'},$token); |
Line 926 sub insert_label {
|
Line 953 sub insert_label {
|
|
|
sub insert_curve { |
sub insert_curve { |
my $result; |
my $result; |
$result .= ' <curve '; |
$result .= "\n <curve "; |
foreach my $attr (keys(%curve_defaults)) { |
foreach my $attr (keys(%curve_defaults)) { |
$result .= ' '.$attr.'="'. |
$result .= ' '.$attr.'="'. |
$curve_defaults{$attr}->{'default'}."\"\n"; |
$curve_defaults{$attr}->{'default'}."\"\n"; |
} |
} |
$result .= " ></curve>\n"; |
$result .= " >\n"; |
|
$result .= &insert_data().&insert_data()."</curve>\n"; |
} |
} |
|
|
sub insert_function { |
sub insert_function { |