--- loncom/cgi/plot.gif 2001/12/11 13:47:36 1.3 +++ loncom/cgi/plot.gif 2001/12/20 22:36:15 1.5 @@ -1,6 +1,6 @@ -#!/usr/bin/perl +#!/usr/bin/perl # -# $Id: plot.gif,v 1.3 2001/12/11 13:47:36 matthew Exp $ +# $Id: plot.gif,v 1.5 2001/12/20 22:36:15 matthew Exp $ # # Copyright Michigan State University Board of Trustees # @@ -24,212 +24,27 @@ # # http://www.lon-capa.org/ # -########################################################################### -# -# CGI-BIN interface to GD, used for making mathematical plots. -# -# User specifies the following variables (given are defaults): -# height = "100" -# width = "100" -# xmin = "-10.0" -# xmax = " 10.0" -# ymin = "-10.0" -# ymax = " 10.0" -# transparent (doesn't work with gif?) -# frame -# drawaxes -# drawtics -# vtic_every = "1.0" -# htic_every = "1.0" -# xseries1 = "x1,x2,x3,x4,x5,...,xn" -# yseries1 = "y1,y2,y3,y4,y5,...,yn" -# xseries2 = .. -# yseries2 = .. -# ... -# label1 = "x,y,size,text" -# label2 = "x,y,size,text" -# label3 = "x,y,size,text" -# ... -# -# size of a labelN is one of : -# giant, large, medium, small, tiny -# -########################################################################### -use GD; - -my @inputs = split(/&/,$ENV{'QUERY_STRING'}); -foreach $input (@inputs) { - ($var,$val) = split /\=/,$input,2; - if (! defined($val)) { - $val = 1; - } - $In{lc($var)}=$val; -} -$height = &grab('height',100,\%In); -$width = &grab('width',100,\%In); -$axis->{'xmin'} = &grab('xmin',-10,\%In); -$axis->{'xmax'} = &grab('xmax', 10,\%In); -$axis->{'ymin'} = &grab('ymin',-10,\%In); -$axis->{'ymax'} = &grab('ymax', 10,\%In); -$axis->{'xlen'} = $axis->{'xmax'} - $axis->{'xmin'}; -$axis->{'ylen'} = $axis->{'ymax'} - $axis->{'ymin'}; -$vtic_every = &grab('vtic_every',1.0,\%In); -$htic_every = &grab('htic_every',1.0,\%In); - -my $image = new GD::Image($width,$height); - -# allocate standard colors -my @BGvalues = split /,/,&grab('bgcolor','255,255,255',\%In); -my @FGvalues = split /,/,&grab('fgcolor','0,0,0',\%In); -my $bgcolor = $image->colorAllocate(@BGvalues); -my $fgcolor = $image->colorAllocate(@FGvalues); - -# Draw a fgcolor frame around the picture -&drawtics($htic_every,$vtic_every) if (exists($In{'drawtics'})); -&drawaxes($axis) if (exists($In{'drawaxis'})); -&drawframe(1) if (exists($In{'frame'})); -# make the background transparent if needed (this doesn't work, at least -# not for gif images, don't know if it works for png) -$image->transparent($bgcolor) if (exists($In{'transparent'})); - -## Take care of labels and data series -foreach (keys %In) { - if (/^label/) { - my ($x,$y,$size,$text) = split/,/,$In{$_}; - &drawstring($text,$x,$y,$fgcolor,$size); - delete ($In{$_}); - next; - } elsif (/^xseries/) { - $xname = $_; - $yname = $xname; - $yname =~ s/^x/y/; - (@X)=split/,/,$In{$xname}; - (@Y)=split/,/,$In{$yname}; - delete ($In{$xname}); - delete ($In{$yname}); - if ($#X != $#Y) { - &drawstring("size of $xname and $yname do not match", - 10,10,$fgcolor,"giant"); - next; - } - &drawcurve(\@X,\@Y); - } -} +use strict; +my $output; +my $tmpdir = '/home/httpd/perl/tmp/'; +my $filename = $tmpdir . $ENV{'QUERY_STRING'}; +$output =<<"END"; +Content-type: text/html -# Tell the browser our mime-type -print <png; -undef $image; -binmode(STDOUT); -open IMG,"|pngtopnm|ppmtogif 2>/dev/null"; # convert into a gif image -print IMG $BinaryData; # output image -$|=1; # be sure to flush before closing -close IMG; - - -#-------------------------------------------------------------------- - -sub grab{ - my ($name,$default,$h) = @_; - my $value = $h->{$name}; - if (defined($value)) { - delete ($h->{$name}) ; - } else { - $value = $default; - } - return $value; -} - -# transformPoint(x,y) where x,y are in the coordinates of axis will return -# the coordinates transformed to the image coordinate system. -sub transformPoint{ - my ($x,$y) = @_; - my ($width,$height) = $image->getBounds(); - $x = ( $x - $axis->{"xmin"}) * $width / ( $axis->{"xlen"}); - $y = ( ( $axis->{"ylen"} ) - ($y - $axis->{"ymin"})) - * $height / ( $axis->{"ylen"} ); - return($x,$y); -} - -sub drawaxes{ - ($x1,$y1) = &transformPoint($axis->{"xmin"},0,$image,$axis); - ($x2,$y2) = &transformPoint($axis->{"xmax"},0,$image,$axis); - $image->line($x1,$y1,$x2,$y2,$fgcolor); - ($x1,$y1) = &transformPoint(0,$axis->{"ymin"},$image,$axis); - ($x2,$y2) = &transformPoint(0,$axis->{"ymax"},$image,$axis); - $image->line($x1,$y1,$x2,$y2,$fgcolor); -} - -sub drawtics{ - my ($htic_every,$vtic_every) = @_; - my ($width,$height) = $image->getBounds(); - - $ticwidth = ($width > 99 ? 5 : int($width /20) + 1); - $ticheight = ($height > 99 ? 5 : int($height/20) + 1); - - # Do tics along y-axis - for ($ntic = 0; $ntic <=int($axis->{"ylen"}/$vtic_every); $ntic++){ - my ($x1,$y1) = &transformPoint(0,$axis->{"ymin"}+$ntic*$vtic_every); - my ($x2,$y2) = &transformPoint(0,$axis->{"ymin"}+$ntic*$vtic_every); - $x1 -= $ticwidth; - $x2 += $ticwidth; - $image->line($x1,$y1,$x2,$y2,$fgcolor); - } - # Do tics along x-axis - for ($ntic = 0; $ntic <=int($axis->{"xlen"}/$htic_every); $ntic++){ - my ($x1,$y1) = &transformPoint( $axis->{"xmin"}+$ntic*$htic_every,0); - my ($x2,$y2) = &transformPoint( $axis->{"xmin"}+$ntic*$htic_every,0); - $y1 -= $ticheight; - $y2 += $ticheight; - $image->line($x1,$y1,$x2,$y2,$fgcolor); - } -} - -sub drawcurve{ - my ($X,$Y) = @_; - for($i=0;$i< (@$X-1);$i++) { - ($x1,$y1) = &transformPoint($X->[$i ],$Y->[$i ]); - ($x2,$y2) = &transformPoint($X->[$i+1],$Y->[$i+1]); - $image->line($x1,$y1,$x2,$y2,$fgcolor); - } -} +if (0) { +$output =<<"END"; +Content-type: image/gif -sub drawframe{ - # Draw a frame around the picture. - my ($xoffset,$yoffset) = @_; - $xoffset = $xoffset || 1; - $yoffset = $yoffset || $xoffset; - my ($width,$height) = $image->getBounds(); - $image->rectangle($xoffset-1,$yoffset-1,$width-$xoffset,$height-$yoffset,$fgcolor); -} -sub drawstring{ - # Write some text on the image. - my ($text,$x,$y,$color,$fontName) = @_; - $font = gdGiantFont if (lc($fontName) eq "giant" || - lc($fontName) eq "huge" ); - $font = gdLargeFont if (lc($fontName) eq "large"); - $font = gdMediumBoldFont if (lc($fontName) eq "medium"); - $font = gdSmallFont if (lc($fontName) eq "small"); - $font = gdTinyFont if (lc($fontName) eq "tiny"); - if (! defined($font)) { - $font = gdGiantFont; - $text = "Font size error!"; - } - ($x,$y) = &transformPoint($x,$y); - $image->string($font,$x,$y,$text,$color); +END +$output .= `gnuplot $filename`; } - - - - - +print $output;