--- loncom/interface/loncommon.pm	2003/10/15 21:12:24	1.129
+++ loncom/interface/loncommon.pm	2003/10/30 13:57:06	1.140
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # a pile of common routines
 #
-# $Id: loncommon.pm,v 1.129 2003/10/15 21:12:24 matthew Exp $
+# $Id: loncommon.pm,v 1.140 2003/10/30 13:57:06 matthew Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -69,6 +69,7 @@ use Apache::Constants qw(:common :http :
 use Apache::lonmsg();
 use Apache::lonmenu();
 use Apache::lonlocal;
+use HTML::Entities;
 
 my $readit;
 
@@ -274,7 +275,7 @@ of the element the selection from the se
 sub browser_and_searcher_javascript {
     return <<END;
     var editbrowser = null;
-    function openbrowser(formname,elementname,only,omit) {
+    function openbrowser(formname,elementname,only,omit,titleelement) {
         var url = '/res/?';
         if (editbrowser == null) {
             url += 'launch=1&';
@@ -288,6 +289,9 @@ sub browser_and_searcher_javascript {
         if (omit != null) {
             url += 'omit=' + omit + '&';
         }
+        if (titleelement != null) {
+            url += 'titleelement=' + titleelement + '&';
+        }
         url += 'element=' + elementname + '';
         var title = 'Browser';
         var options = 'scrollbars=1,resizable=1,menubar=0';
@@ -296,7 +300,7 @@ sub browser_and_searcher_javascript {
         editbrowser.focus();
     }
     var editsearcher;
-    function opensearcher(formname,elementname) {
+    function opensearcher(formname,elementname,titleelement) {
         var url = '/adm/searchcat?';
         if (editsearcher == null) {
             url += 'launch=1&';
@@ -304,6 +308,9 @@ sub browser_and_searcher_javascript {
         url += 'catalogmode=interactive&';
         url += 'mode=edit&';
         url += 'form=' + formname + '&';
+        if (titleelement != null) {
+            url += 'titleelement=' + titleelement + '&';
+        }
         url += 'element=' + elementname + '';
         var title = 'Search';
         var options = 'scrollbars=1,resizable=1,menubar=0';
@@ -2663,7 +2670,7 @@ $uname, optional the username of the use
 
 sub check_if_partid_hidden {
     my ($id,$symb,$udom,$uname) = @_;
-    my $hiddenparts=&Apache::lonnet::EXT('resource.0.parameter_hiddenparts',
+    my $hiddenparts=&Apache::lonnet::EXT('resource.0.hiddenparts',
 					 $symb,$udom,$uname);
     my @hiddenlist=split(/,/,$hiddenparts);
     foreach my $checkid (@hiddenlist) {
@@ -2672,23 +2679,86 @@ sub check_if_partid_hidden {
     return undef;
 }
 
+
+############################################################
+############################################################
+
+=pod
+
+=head1 cgi-bin script and graphing routines
+
+=item get_cgi_id
+
+Inputs: none
+
+Returns an id which can be used to pass environment variables
+to various cgi-bin scripts.  These environment variables will
+be removed from the users environment after a given time by
+the routine &Apache::lonnet::transfer_profile_to_env.
+
+=cut
+
+############################################################
+############################################################
+
+sub get_cgi_id {
+    return (time.'_'.int(rand(1000)));
+}
+
 ############################################################
 ############################################################
 
 =pod
 
-=item DrawGraph
+=item DrawBarGraph
+
+Facilitates the plotting of data in a (stacked) bar graph.
+Puts plot definition data into the users environment in order for 
+graph.png to plot it.  Returns an <img> tag for the plot.
+The bars on the plot are labeled '1','2',...,'n'.
 
-Returns a link to cgi-bin/graph
+Inputs:
+
+=over 4
+
+=item $Title: string, the title of the plot
+
+=item $xlabel: string, text describing the X-axis of the plot
+
+=item $ylabel: string, text describing the Y-axis of the plot
+
+=item $Max: scalar, the maximum Y value to use in the plot
+If $Max is < any data point, the graph will not be rendered.
+
+=item $colors: array ref holding the colors to be used for the data sets when
+they are plotted.  If undefined, default values will be used.
+
+=item @Values: An array of array references.  Each array reference holds data
+to be plotted in a stacked bar chart.
+
+=back
+
+Returns:
+
+An <img> tag which references graph.png and the appropriate identifying
+information for the plot.
 
 =cut
 
 ############################################################
 ############################################################
-sub DrawGraph {
+sub DrawBarGraph {
     my ($Title,$xlabel,$ylabel,$Max,$colors,@Values)=@_;
     #
-    my $identifier = time.'_'.int(rand(1000));
+    if (! defined($colors)) {
+        $colors = ['#33ff00', 
+                  '#0033cc', '#990000', '#aaaa66', '#663399', '#ff9933',
+                  '#66ccff', '#ff9999', '#cccc33', '#660000', '#33cc66',
+                  ]; 
+    }
+    #
+    my $identifier = &get_cgi_id();
+    my $id = 'cgi.'.$identifier;        
     if (! @Values || ref($Values[0]) ne 'ARRAY') {
         return '';
     }
@@ -2697,31 +2767,287 @@ sub DrawGraph {
     my $NumSets=1;
     foreach my $array (@Values) {
         next if (! ref($array));
-        $ValuesHash{$identifier.'.data.'.$NumSets++} = join(',',@$array);
+        $ValuesHash{$id.'.data.'.$NumSets++} = 
+            join(',',@$array);
     }
     #
-    $Title  = '' if (! defined($Title));
-    $xlabel = '' if (! defined($xlabel));
-    $ylabel = '' if (! defined($ylabel));
-    $Title  = &Apache::lonnet::escape($Title);
-    $xlabel = &Apache::lonnet::escape($xlabel);
-    $ylabel = &Apache::lonnet::escape($ylabel);
+    my ($height,$width,$xskip,$bar_width) = (200,120,1,15);
+    if ($NumBars < 10) {
+        $width = 120+$NumBars*15;
+        $xskip = 1;
+        $bar_width = 15;
+    } elsif ($NumBars <= 25) {
+        $width = 120+$NumBars*11;
+        $xskip = 5;
+        $bar_width = 8;
+    } elsif ($NumBars <= 50) {
+        $width = 120+$NumBars*8;
+        $xskip = 5;
+        $bar_width = 4;
+    } else {
+        $width = 120+$NumBars*8;
+        $xskip = 5;
+        $bar_width = 4;
+    }
+    #
+    my @Labels;
+    for (my $i=0;$i<@{$Values[0]};$i++) {
+        push (@Labels,$i+1);
+    }
     #
     $Max = 1 if ($Max < 1);
     if ( int($Max) < $Max ) {
         $Max++;
         $Max = int($Max);
     }
+    $Title  = '' if (! defined($Title));
+    $xlabel = '' if (! defined($xlabel));
+    $ylabel = '' if (! defined($ylabel));
+    $ValuesHash{$id.'.title'}    = &Apache::lonnet::escape($Title);
+    $ValuesHash{$id.'.xlabel'}   = &Apache::lonnet::escape($xlabel);
+    $ValuesHash{$id.'.ylabel'}   = &Apache::lonnet::escape($ylabel);
+    $ValuesHash{$id.'.y_max_value'} = $Max;
+    $ValuesHash{$id.'.NumBars'}  = $NumBars;
+    $ValuesHash{$id.'.NumSets'}  = $NumSets;
+    $ValuesHash{$id.'.PlotType'} = 'bar';
+    $ValuesHash{$id.'.Colors'}   = join(',',@{$colors});
+    $ValuesHash{$id.'.height'}   = $height;
+    $ValuesHash{$id.'.width'}    = $width;
+    $ValuesHash{$id.'.xskip'}    = $xskip;
+    $ValuesHash{$id.'.bar_width'} = $bar_width;
+    $ValuesHash{$id.'.labels'} = join(',',@Labels);
+    #
+    &Apache::lonnet::appenv(%ValuesHash);
+    return '<img src="/cgi-bin/graph.png?'.$identifier.'" border="1" />';
+}
+
+############################################################
+############################################################
+
+=pod
+
+=item DrawXYGraph
+
+Facilitates the plotting of data in an XY graph.
+Puts plot definition data into the users environment in order for 
+graph.png to plot it.  Returns an <img> tag for the plot.
+
+Inputs:
+
+=over 4
+
+=item $Title: string, the title of the plot
+
+=item $xlabel: string, text describing the X-axis of the plot
+
+=item $ylabel: string, text describing the Y-axis of the plot
+
+=item $Max: scalar, the maximum Y value to use in the plot
+If $Max is < any data point, the graph will not be rendered.
+
+=item $colors: Array ref containing the hex color codes for the data to be 
+plotted in.  If undefined, default values will be used.
+
+=item $Xlabels: Array ref containing the labels to be used for the X-axis.
+
+=item $Ydata: Array ref containing Array refs.  
+Each of the contained arrays will be plotted as a seperate curve.
+
+=item %Values: hash indicating or overriding any default values which are 
+passed to graph.png.  
+Possible values are: width, xskip, x_ticks, x_tick_offset, among others.
+
+=back
+
+Returns:
+
+An <img> tag which references graph.png and the appropriate identifying
+information for the plot.
+
+=cut
+
+############################################################
+############################################################
+sub DrawXYGraph {
+    my ($Title,$xlabel,$ylabel,$Max,$colors,$Xlabels,$Ydata,%Values)=@_;
+    #
+    # Create the identifier for the graph
+    my $identifier = &get_cgi_id();
+    my $id = 'cgi.'.$identifier;
+    #
+    $Title  = '' if (! defined($Title));
+    $xlabel = '' if (! defined($xlabel));
+    $ylabel = '' if (! defined($ylabel));
+    my %ValuesHash = 
+        (
+         $id.'.title'  => &Apache::lonnet::escape($Title),
+         $id.'.xlabel' => &Apache::lonnet::escape($xlabel),
+         $id.'.ylabel' => &Apache::lonnet::escape($ylabel),
+         $id.'.y_max_value'=> $Max,
+         $id.'.labels'     => join(',',@$Xlabels),
+         $id.'.PlotType'   => 'XY',
+         );
+    #
+    if (defined($colors) && ref($colors) eq 'ARRAY') {
+        $ValuesHash{$id.'.Colors'}   = join(',',@{$colors});
+    }
     #
-    &Apache::lonnet::appenv($identifier.'.title'   => $Title,
-                            $identifier.'.xlabel'  => $xlabel,
-                            $identifier.'.ylabel'  => $ylabel,
-                            $identifier.'.Max'     => $Max,
-                            $identifier.'.NumBars' => $NumBars,
-                            $identifier.'.NumSets' => $NumSets,
-                            $identifier.'.Colors'  => join(',',@{$colors}),
-                            %ValuesHash);
-    return '<IMG src="/cgi-bin/graph.png?'.$identifier.'" border="1" />';
+    if (! ref($Ydata) || ref($Ydata) ne 'ARRAY') {
+        return '';
+    }
+    my $NumSets=1;
+    foreach my $array (@{$Ydata}){
+        next if (! ref($array));
+        $ValuesHash{$id.'.data.'.$NumSets++} = join(',',@$array);
+    }
+    $ValuesHash{$id.'.NumSets'} = $NumSets-1;
+    #
+    # Deal with other parameters
+    while (my ($key,$value) = each(%Values)) {
+        $ValuesHash{$id.'.'.$key} = $value;
+    }
+    #
+    &Apache::lonnet::appenv(%ValuesHash);
+    return '<img src="/cgi-bin/graph.png?'.$identifier.'" border="1" />';
+}
+
+############################################################
+############################################################
+
+=pod
+
+=item DrawXYYGraph
+
+Facilitates the plotting of data in an XY graph with two Y axes.
+Puts plot definition data into the users environment in order for 
+graph.png to plot it.  Returns an <img> tag for the plot.
+
+Inputs:
+
+=over 4
+
+=item $Title: string, the title of the plot
+
+=item $xlabel: string, text describing the X-axis of the plot
+
+=item $ylabel: string, text describing the Y-axis of the plot
+
+=item $colors: Array ref containing the hex color codes for the data to be 
+plotted in.  If undefined, default values will be used.
+
+=item $Xlabels: Array ref containing the labels to be used for the X-axis.
+
+=item $Ydata1: The first data set
+
+=item $Min1: The minimum value of the left Y-axis
+
+=item $Max1: The maximum value of the left Y-axis
+
+=item $Ydata2: The second data set
+
+=item $Min2: The minimum value of the right Y-axis
+
+=item $Max2: The maximum value of the left Y-axis
+
+=item %Values: hash indicating or overriding any default values which are 
+passed to graph.png.  
+Possible values are: width, xskip, x_ticks, x_tick_offset, among others.
+
+=back
+
+Returns:
+
+An <img> tag which references graph.png and the appropriate identifying
+information for the plot.
+
+=cut
+
+############################################################
+############################################################
+sub DrawXYYGraph {
+    my ($Title,$xlabel,$ylabel,$colors,$Xlabels,$Ydata1,$Min1,$Max1,
+                                        $Ydata2,$Min2,$Max2,%Values)=@_;
+    #
+    # Create the identifier for the graph
+    my $identifier = &get_cgi_id();
+    my $id = 'cgi.'.$identifier;
+    #
+    $Title  = '' if (! defined($Title));
+    $xlabel = '' if (! defined($xlabel));
+    $ylabel = '' if (! defined($ylabel));
+    my %ValuesHash = 
+        (
+         $id.'.title'  => &Apache::lonnet::escape($Title),
+         $id.'.xlabel' => &Apache::lonnet::escape($xlabel),
+         $id.'.ylabel' => &Apache::lonnet::escape($ylabel),
+         $id.'.labels' => join(',',@$Xlabels),
+         $id.'.PlotType' => 'XY',
+         $id.'.NumSets' => 2,
+         $id.'.two_axes' => 1,
+         $id.'.y1_max_value' => $Max1,
+         $id.'.y1_min_value' => $Min1,
+         $id.'.y2_max_value' => $Max2,
+         $id.'.y2_min_value' => $Min2,
+         );
+    #
+    if (defined($colors) && ref($colors) eq 'ARRAY') {
+        $ValuesHash{$id.'.Colors'}   = join(',',@{$colors});
+    }
+    #
+    if (! ref($Ydata1) || ref($Ydata1) ne 'ARRAY' ||
+        ! ref($Ydata2) || ref($Ydata2) ne 'ARRAY'){
+        return '';
+    }
+    my $NumSets=1;
+    foreach my $array ($Ydata1,$Ydata2){
+        next if (! ref($array));
+        $ValuesHash{$id.'.data.'.$NumSets++} = join(',',@$array);
+    }
+    #
+    # Deal with other parameters
+    while (my ($key,$value) = each(%Values)) {
+        $ValuesHash{$id.'.'.$key} = $value;
+    }
+    #
+    &Apache::lonnet::appenv(%ValuesHash);
+    return '<img src="/cgi-bin/graph.png?'.$identifier.'" border="1" />';
+}
+
+############################################################
+############################################################
+
+=pod
+
+=head1 Statistics helper routines?  
+
+Bad place for them but what the hell.
+
+=item &chartlink
+
+Returns a link to the chart for a specific student.  
+
+Inputs:
+
+=over 4
+
+=item $linktext: The text of the link
+
+=item $sname: The students username
+
+=item $sdomain: The students domain
+
+=back
+
+=cut
+
+############################################################
+############################################################
+sub chartlink {
+    my ($linktext, $sname, $sdomain) = @_;
+    my $link = '<a href="/adm/statistics?reportSelected=student_assessment'.
+        '&SelectedStudent='.&Apache::lonnet::escape($sname.':'.$sdomain).
+        '&chartoutputmode='.HTML::Entities::encode('html, with all links').
+       '">'.$linktext.'</a>';
 }
 
 ############################################################