--- loncom/xml/lonplot.pm	2002/02/27 22:17:06	1.52
+++ loncom/xml/lonplot.pm	2002/03/22 16:04:09	1.61
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Dynamic plot
 #
-# $Id: lonplot.pm,v 1.52 2002/02/27 22:17:06 matthew Exp $
+# $Id: lonplot.pm,v 1.61 2002/03/22 16:04:09 matthew Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -91,10 +91,6 @@ my %linestyles =
      yerrorbars	    => [3,4],
      xyerrorbars    => [4,6],
      boxes          => 3,
-#     boxerrorbars   => [3,4,5],
-#     boxxyerrorbars => [4,6,7],
-#     financebars    => 5,
-#     candlesticks   => 5,
      vector	    => 4
     );		    
 
@@ -144,6 +140,8 @@ A <b>gnuplot</b> tag can contain the fol
     <dd> Allows specification of the x and y coordinate 'tics' on the axes.
 This is mostly used to adjust the grid lines when a grid is displayed.
 </dl>
+If you are having trouble with your plot, please read the help
+available on Plot Curve.
 ENDPLOTHELP
 
 my %gnuplot_defaults = 
@@ -360,8 +358,8 @@ first tag will be the X data and the sec
 </p>
     <dt> Curve Function
     <dd> The <b>function</b> tag allows you to specify the curve to be 
-plotted as a formula that gnuplot can understand.  Be careful using this
-tag - it is surprisingly easy to give gnuplot a function it cannot deal
+plotted as a formula that gnuplot can understand.  <b>Be careful using this
+tag.</b>  It is surprisingly easy to give gnuplot a function it cannot deal
 with properly.  Be explicit: 2*sin(2*3.141592*x/4) will work but
 2sin(2*3.141592x/4) will not.  If you do not receive any errors in the
 gnuplot data but still do not have an image produced, it is likely there
@@ -369,6 +367,8 @@ is an error in your <b>function</b> tag.
 </dl>
 ENDCURVEHELP
 
+my @curve_edit_order = ('color','name','linestyle','pointsize');
+
 my %curve_defaults = 
     (
      color     => {
@@ -391,7 +391,22 @@ my %curve_defaults =
 	 description => 'Line style',
 	 edit_type   => 'choice',
 	 choices     => [keys(%linestyles)]
-	 }
+	 },
+# gnuplots term=gif driver does not handle linewidth :(
+#     linewidth => {
+#         default     => 1,
+#         test        => $int_test,
+#         description => 'Line width (may not apply to all line styles)',
+#         edit_type   => 'choice',
+#         choices     => [1,2,3,4,5,6,7,8,9,10]
+#         },
+     pointsize => {
+         default     => 1,
+         test        => $int_test,
+         description => 'point size (may not apply to all line styles)',
+         edit_type   => 'choice',
+         choices     => [0,1,2,3,4,5,6,7,8,9,10]
+         }
      );
 
 ###################################################################
@@ -414,9 +429,6 @@ sub start_gnuplot {
 	      'xtics','ytics'));
     push (@Apache::lonxml::namespace,'lonplot');
     if ($target eq 'web' || $target eq 'tex') {
-	my $inside = &Apache::lonxml::get_all_text("/gnuplot",$$parser[-1]);
-	$inside=&Apache::run::evaluate($inside,$safeeval,$$parstack[-1]);
-	&Apache::lonxml::newparser($parser,\$inside);
 	&get_attributes(\%plot,\%gnuplot_defaults,$parstack,$safeeval,
 			$tagstack->[-1]);
     } elsif ($target eq 'edit') {
@@ -441,26 +453,36 @@ sub end_gnuplot {
     &Apache::lonxml::deregister('Apache::lonplot',
 	('title','xlabel','ylabel','key','axis','label','curve'));
     my $result = '';
+    my $randnumber;
+    # need to call rand everytime start_script would evaluate, as the
+    # safe space rand number generator and the global rand generator 
+    # are not seperate
+    if ($target eq 'web' || $target eq 'tex' || $target eq 'grade' ||
+	$target eq 'answer') {
+      $randnumber=int(rand(1000));
+    }
     if ($target eq 'web' || $target eq 'tex') {
 	&check_inputs(); # Make sure we have all the data we need
 	##
 	## Determine filename
 	my $tmpdir = '/home/httpd/perl/tmp/';
 	my $filename = $ENV{'user.name'}.'_'.$ENV{'user.domain'}.
-	    '_'.time.'_'.$$.int(rand(1000)).'_plot.data';
+	    '_'.time.'_'.$$.$randnumber.'_plot.data';
 	## Write the plot description to the file
 	&write_gnuplot_file($tmpdir,$filename,$target);
+	$filename = &Apache::lonnet::escape($filename);
 	## return image tag for the plot
 	if ($target eq 'web') {
 	    $result .= <<"ENDIMAGE";
-<img src    = "/cgi-bin/plot.gif?$filename" 
+<img src    = "/cgi-bin/plot.gif?file=$filename&output=gif" 
      width  = "$plot{'width'}" 
      height = "$plot{'height'}"
      align  = "$plot{'align'}"
      alt    = "image should be /cgi-bin/plot.gif?$filename" />
 ENDIMAGE
         } elsif ($target eq 'tex') {
-	    system "gnuplot $filename";
+	    &Apache::lonnet::ssi('cgi-bin/plot.gif?file=$filename'.
+				 '&output=eps');
 	    $result = "$filename.eps";
 	}
     } elsif ($target eq 'edit') {
@@ -569,6 +591,7 @@ sub start_title {
     my $result='';
     if ($target eq 'web' || $target eq 'tex') {
 	$title = &Apache::lonxml::get_all_text("/title",$$parser[-1]);
+	$title=&Apache::run::evaluate($title,$safeeval,$$parstack[-1]);
 	$title =~ s/\n/ /g;
 	if (length($title) > $max_str_len) {
 	    $title = substr($title,0,$max_str_len);
@@ -578,7 +601,7 @@ sub start_title {
 	my $text=&Apache::lonxml::get_all_text("/title",$$parser[-1]);
 	$result.=&Apache::edit::end_row().
 	    &Apache::edit::start_spanning_row().
-	    &Apache::edit::editfield('',$text,'',60,1);
+	    &Apache::edit::textfield('',$text,'',60);
     } elsif ($target eq 'modified') {
 	my $text=$$parser[-1]->get_text("/title");
 	$result.=&Apache::edit::rebuild_tag($token);
@@ -602,6 +625,7 @@ sub start_xlabel {
     my $result='';
     if ($target eq 'web' || $target eq 'tex') {
 	$xlabel = &Apache::lonxml::get_all_text("/xlabel",$$parser[-1]);
+	$xlabel=&Apache::run::evaluate($xlabel,$safeeval,$$parstack[-1]);
 	$xlabel =~ s/\n/ /g;
 	if (length($xlabel) > $max_str_len) {
 	    $xlabel = substr($xlabel,0,$max_str_len);
@@ -611,7 +635,7 @@ sub start_xlabel {
 	my $text=&Apache::lonxml::get_all_text("/xlabel",$$parser[-1]);
 	$result.=&Apache::edit::end_row().
 	    &Apache::edit::start_spanning_row().
-	    &Apache::edit::editfield('',$text,'',60,1);
+	    &Apache::edit::textfield('',$text,'',60);
     } elsif ($target eq 'modified') {
 	my $text=$$parser[-1]->get_text("/xlabel");
 	$result.=&Apache::edit::rebuild_tag($token);	
@@ -636,6 +660,7 @@ sub start_ylabel {
     my $result='';
     if ($target eq 'web' || $target eq 'tex') {
 	$ylabel = &Apache::lonxml::get_all_text("/ylabel",$$parser[-1]);
+	$ylabel = &Apache::run::evaluate($ylabel,$safeeval,$$parstack[-1]);
 	$ylabel =~ s/\n/ /g;
 	if (length($ylabel) > $max_str_len) {
 	    $ylabel = substr($ylabel,0,$max_str_len);
@@ -645,7 +670,7 @@ sub start_ylabel {
 	my $text = &Apache::lonxml::get_all_text("/ylabel",$$parser[-1]);
 	$result .= &Apache::edit::end_row().
 	    &Apache::edit::start_spanning_row().
-	    &Apache::edit::editfield('',$text,'',60,1);
+	    &Apache::edit::textfield('',$text,'',60);
     } elsif ($target eq 'modified') {
 	my $text=$$parser[-1]->get_text("/ylabel");
 	$result.=&Apache::edit::rebuild_tag($token);
@@ -673,6 +698,7 @@ sub start_label {
 	&get_attributes(\%label,\%label_defaults,$parstack,$safeeval,
 		    $tagstack->[-1]);
 	my $text = &Apache::lonxml::get_all_text("/label",$$parser[-1]);
+	$text = &Apache::run::evaluate($text,$safeeval,$$parstack[-1]);
 	$text =~ s/\n/ /g;
 	$text = substr($text,0,$max_str_len) if (length($text) > $max_str_len);
 	$label{'text'} = $text;
@@ -683,7 +709,7 @@ sub start_label {
 	my $text = &Apache::lonxml::get_all_text("/label",$$parser[-1]);
 	$result .= &Apache::edit::end_row().
 	    &Apache::edit::start_spanning_row().
-	    &Apache::edit::editfield('',$text,'',60,1);
+	    &Apache::edit::textfield('',$text,'',60);
     } elsif ($target eq 'modified') {
 	&Apache::edit::get_new_args
 	    ($token,$parstack,$safeeval,keys(%label_defaults));
@@ -718,7 +744,8 @@ sub start_curve {
     } elsif ($target eq 'edit') {
 	$result .= &Apache::edit::tag_start($target,$token,'Curve');
 	$result .= &help_win($curve_help_text);
-	$result .= &edit_attributes($target,$token,\%curve_defaults);
+	$result .= &edit_attributes($target,$token,\%curve_defaults,
+                                    \@curve_edit_order);
     } elsif ($target eq 'modified') {
 	my $constructtag=&Apache::edit::get_new_args
 	    ($token,$parstack,$safeeval,keys(%curve_defaults));
@@ -751,14 +778,15 @@ sub start_function {
 	    &Apache::lonxml::warning('Use of <function> precludes use of <data>.  The <data> will be omitted in favor of the <function> declaration.');
 	    delete $curves[-1]->{'data'} ;
 	}
-	$curves[-1]->{'function'} = 
-	    &Apache::lonxml::get_all_text("/function",$$parser[-1]);
+        my $function = &Apache::lonxml::get_all_text("/function",$$parser[-1]);
+	$function = &Apache::run::evaluate($function,$safeeval,$$parstack[-1]);
+	$curves[-1]->{'function'} = $function; 
     } elsif ($target eq 'edit') {
 	$result .= &Apache::edit::tag_start($target,$token,'Gnuplot compatible curve function');
 	my $text = &Apache::lonxml::get_all_text("/function",$$parser[-1]);
 	$result .= &Apache::edit::end_row().
 	    &Apache::edit::start_spanning_row().
-	    &Apache::edit::editfield('',$text,'',60,1);
+	    &Apache::edit::textfield('',$text,'',60);
     } elsif ($target eq 'modified') {
 	$result.=&Apache::edit::rebuild_tag($token);
 	my $text=$$parser[-1]->get_text("/function");
@@ -789,6 +817,7 @@ sub start_data {
 	    delete($curves[-1]->{'function'});
 	}
 	my $datatext = &Apache::lonxml::get_all_text("/data",$$parser[-1]);
+	$datatext=&Apache::run::evaluate($datatext,$safeeval,$$parstack[-1]);
 	# Deal with cases where we're given an array...
 	if ($datatext =~ /^\@/) {
 	    $datatext = &Apache::run::run('return "'.$datatext.'"',
@@ -833,7 +862,7 @@ sub start_data {
 	my $text = &Apache::lonxml::get_all_text("/data",$$parser[-1]);
 	$result .= &Apache::edit::end_row().
 	    &Apache::edit::start_spanning_row().
-	    &Apache::edit::editfield('',$text,'',60,1);
+	    &Apache::edit::textfield('',$text,'',60);
     } elsif ($target eq 'modified') {
 	$result.=&Apache::edit::rebuild_tag($token);
 	my $text=$$parser[-1]->get_text("/data");
@@ -1003,6 +1032,18 @@ sub write_gnuplot_file {
 		$curve->{'function'}.' title "'.
 		$curve->{'name'}.'" with '.
 		$curve->{'linestyle'};
+#
+# gnuplot's term=gif driver does not handle linewidths :(
+# . ' linewidth '. $curve->{'linewidth'};
+#
+            if (($curve->{'linestyle'} eq 'points')      ||
+                ($curve->{'linestyle'} eq 'linespoints') ||
+                ($curve->{'linestyle'} eq 'errorbars')   ||
+                ($curve->{'linestyle'} eq 'xerrorbars')  ||
+                ($curve->{'linestyle'} eq 'yerrorbars')  ||
+                ($curve->{'linestyle'} eq 'xyerrorbars')) {
+                $gnuplot_input.=' pointsize '.$curve->{'pointsize'};
+            }
 	} elsif (exists($curve->{'data'})) {
 	    # Store data values in $datatext
 	    my $datatext = '';
@@ -1099,11 +1140,11 @@ sub edit_attributes {
 sub insert_gnuplot {
     my $result = '';
     #  plot attributes
-    $result .= "<gnuplot \n";
+    $result .= "\n<gnuplot ";
     foreach my $attr (keys(%gnuplot_defaults)) {
-	$result .= "     $attr=\"$gnuplot_defaults{$attr}->{'default'}\"\n";
+	$result .= "\n     $attr=\"$gnuplot_defaults{$attr}->{'default'}\"";
     }
-    $result .= ">\n";
+    $result .= ">";
     # Add the components (most are commented out for simplicity)
     # $result .= &insert_key();
     # $result .= &insert_axis();
@@ -1112,7 +1153,7 @@ sub insert_gnuplot {
     # $result .= &insert_ylabel();    
     $result .= &insert_curve();
     # close up the <gnuplot>
-    $result .= "</gnuplot>\n";
+    $result .= "\n</gnuplot>";
     return $result;
 }
 
@@ -1126,9 +1167,9 @@ sub insert_xtics {
     my $result;
     $result .= "\n    <xtics ";
     foreach my $attr (keys(%tic_defaults)) {
-	$result .= "$attr=\"$tic_defaults{$attr}->{'default'}\" ";
+	$result .= "\n        $attr=\"$tic_defaults{$attr}->{'default'}\" ";
     }
-    $result .= "/>\n";
+    $result .= "/>";
     return $result;
 }
 
@@ -1136,19 +1177,19 @@ sub insert_ytics {
     my $result;
     $result .= "\n    <ytics ";
     foreach my $attr (keys(%tic_defaults)) {
-	$result .= "$attr=\"$tic_defaults{$attr}->{'default'}\" ";
+	$result .= "\n        $attr=\"$tic_defaults{$attr}->{'default'}\" ";
     }
-    $result .= "/>\n";
+    $result .= "/>";
     return $result;
 }
 
 sub insert_key {
     my $result;
-    $result .= "\n    <key \n";
+    $result .= "\n    <key ";
     foreach my $attr (keys(%key_defaults)) {
-	$result .= "         $attr=\"$key_defaults{$attr}->{'default'}\"\n";
+	$result .= "\n         $attr=\"$key_defaults{$attr}->{'default'}\"";
     }
-    $result .= "   />\n";
+    $result .= " />";
     return $result;
 }
 
@@ -1156,24 +1197,24 @@ sub insert_axis{
     my $result;
     $result .= "\n    <axis ";
    foreach my $attr (keys(%axis_defaults)) {
-	$result .= "         $attr=\"$axis_defaults{$attr}->{'default'}\"\n";
+	$result .= "\n         $attr=\"$axis_defaults{$attr}->{'default'}\"";
     }
-    $result .= "   />\n";
+    $result .= " />";
     return $result;
 }
 
-sub insert_title { return "\n    <title></title>\n"; }
-sub insert_xlabel { return "\n    <xlabel></xlabel>\n"; }
-sub insert_ylabel { return "\n    <ylabel></ylabel>\n"; }
+sub insert_title  { return "\n    <title></title>"; }
+sub insert_xlabel { return "\n    <xlabel></xlabel>"; }
+sub insert_ylabel { return "\n    <ylabel></ylabel>"; }
 
 sub insert_label {
     my $result;
     $result .= "\n    <label ";
     foreach my $attr (keys(%label_defaults)) {
-	$result .= '         '.$attr.'="'.
-	    $label_defaults{$attr}->{'default'}."\"\n";
+	$result .= "\n         $attr=\"".
+            $label_defaults{$attr}->{'default'}."\"";
     }
-    $result .= "   ></label>\n";
+    $result .= "></label>";
     return $result;
 }
 
@@ -1181,22 +1222,22 @@ sub insert_curve {
     my $result;
     $result .= "\n    <curve ";
     foreach my $attr (keys(%curve_defaults)) {
-	$result .= '         '.$attr.'="'.
-	    $curve_defaults{$attr}->{'default'}."\"\n";
+	$result .= "\n         $attr=\"".
+	    $curve_defaults{$attr}->{'default'}."\"";
     }
-    $result .= "    >\n";
-    $result .= &insert_data().&insert_data()."</curve>\n";
+    $result .= " >";
+    $result .= &insert_data().&insert_data()."\n    </curve>";
 }
 
 sub insert_function {
     my $result;
-    $result .= "<function></function>\n";
+    $result .= "\n        <function></function>";
     return $result;
 }
 
 sub insert_data {
     my $result;
-    $result .= "     <data></data>\n";
+    $result .= "\n        <data></data>";
     return $result;
 }