--- loncom/cgi/plot.gif 2001/12/07 22:52:38 1.1 +++ loncom/cgi/plot.gif 2002/03/01 14:03:50 1.9 @@ -1,6 +1,6 @@ -#!/usr/bin/perl +#!/usr/bin/perl # -# $Id: plot.gif,v 1.1 2001/12/07 22:52:38 matthew Exp $ +# $Id: plot.gif,v 1.9 2002/03/01 14:03:50 matthew Exp $ # # Copyright Michigan State University Board of Trustees # @@ -24,208 +24,39 @@ # # 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" -# 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($height,$width); - -# allocate standard colors -my $white = $image->colorAllocate(255,255,255); -my $black = $image->colorAllocate( 0, 0, 0); - -# Draw a black frame around the picture -&drawtics($htic_every,$vtic_every) if (exists($In{"drawtics"})); -&drawaxes($axis) if (exists($In{"drawaxis"})); -&frame(1) if (exists($In{'frame'})); - -## Take care of labels and data series -foreach (keys %In) { - if (/^label/) { - my ($x,$y,$size,$text) = split/,/,$In{$_}; - &drawstring($text,$x,$y,$black,$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,$black,"giant"); - next; - } - &drawcurve(\@X,\@Y); - } -} +use strict; -# make the background transparent and interlaced -$image->transparent($white); +$|=1; -# make sure we are writing to a binary stream -binmode STDOUT; - -# Convert the image to PNG and print it on standard output -print <plot(\@data)->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; + while ($_=) { + print; } - return $value; +} elsif ($output eq 'eps') { + system ("gnuplot $filename"); +} else { + die "output $output is not a recognized value or has no value\n"; } -# 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,$black); - ($x1,$y1) = &transformPoint(0,$axis->{"ymin"},$image,$axis); - ($x2,$y2) = &transformPoint(0,$axis->{"ymax"},$image,$axis); - $image->line($x1,$y1,$x2,$y2,$black); -} - -sub drawtics{ - my ($htic_every,$vtic_every) = @_; - my ($width,$height) = $image->getBounds(); - - $ticwidth = ($width > 99 ? 10 : int($width /10) + 1); - $ticheight = ($height > 99 ? 10 : int($height/10)); - - # 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,$black); - } - # 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,$black); - } -} - -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,$black); - } -} - -sub frame{ - # 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,$black); -} - -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); -} - - - - - -