Diff for /loncom/interface/lonstatistics.pm between versions 1.65 and 1.135

version 1.65, 2003/03/25 22:20:25 version 1.135, 2006/05/18 01:08:50
Line 38  lonstatistics Line 38  lonstatistics
   
 Main handler for statistics and chart.  Main handler for statistics and chart.
   
 =head1 PACKAGES USED  
   
     use strict;  
     use Apache::Constants qw(:common :http);  
     use Apache::lonnet();  
     use Apache::lonhomework;  
     use Apache::loncommon;  
     use Apache::loncoursedata;  
     use Apache::lonhtmlcommon;  
     use Apache::lonproblemanalysis;  
     use Apache::lonproblemstatistics;  
     use Apache::lonstudentassessment;  
     use Apache::lonpercentage;  
   
 =over 4  =over 4
   
 =cut  =cut
Line 63  use Apache::Constants qw(:common :http); Line 49  use Apache::Constants qw(:common :http);
 use vars qw(  use vars qw(
     @FullClasslist       @FullClasslist 
     @Students      @Students
     @Sections       @Sections
     @SelectedSections      @Groups 
     %StudentData      %StudentData
     @StudentDataOrder      @StudentDataOrder
     @SelectedStudentData      @SelectedStudentData
     $top_map       $enrollment_status);
     @Sequences   
     @SelectedMaps  
     @Assessments);  
   
 use Apache::lonnet();  use Apache::lonnet;
 use Apache::lonhomework;  use Apache::lonhomework;
 use Apache::loncommon;  use Apache::loncommon;
 use Apache::loncoursedata;  use Apache::loncoursedata;
 use Apache::lonhtmlcommon;  use Apache::lonhtmlcommon;
   use Apache::lonmysql;
   use Apache::lonlocal;
   use Apache::longroup;
   use Time::HiRes;
   #
   # Statistics Packages
 use Apache::lonproblemanalysis();  use Apache::lonproblemanalysis();
   use Apache::lonsubmissiontimeanalysis();
   use Apache::loncorrectproblemplot();
 use Apache::lonproblemstatistics();  use Apache::lonproblemstatistics();
 use Apache::lonstudentassessment();  use Apache::lonstudentassessment();
 use Apache::lonpercentage;  use Apache::lonpercentage;
 use Time::HiRes;  use Apache::lonstudentsubmissions();
   use Apache::lonsurveyreports();
   use Apache::longradinganalysis();
   
 #######################################################  #######################################################
 #######################################################  #######################################################
Line 97  use Time::HiRes; Line 90  use Time::HiRes;
   
 =item @Sections The sections available in this class  =item @Sections The sections available in this class
   
   =item @Groups The groups available in the class
   
 =item $curr_student The student currently being examined  =item $curr_student The student currently being examined
   
 =item $prev_student The student previous in the classlist  =item $prev_student The student previous in the classlist
Line 133  undef the following package variables: Line 128  undef the following package variables:
   
 =item @Sections  =item @Sections
   
 =item @SelectedSections  =item @Groups
   
 =item %StudentData  =item %StudentData
   
Line 157  sub clear_classlist_variables { Line 152  sub clear_classlist_variables {
     undef(@FullClasslist);      undef(@FullClasslist);
     undef(@Students);      undef(@Students);
     undef(@Sections);      undef(@Sections);
     undef(@SelectedSections);      undef(@Groups);
     undef(%StudentData);      undef(%StudentData);
     undef(@SelectedStudentData);      undef(@SelectedStudentData);
     undef($curr_student);      undef($curr_student);
Line 183  the following package variables: Line 178  the following package variables:
   
 =item @Sections  =item @Sections
   
 =item @SelectedSections  =item @Groups 
   
 =item %StudentData  =item %StudentData
   
Line 205  upon the calling context. Line 200  upon the calling context.
 #######################################################  #######################################################
 #######################################################  #######################################################
 sub PrepareClasslist {  sub PrepareClasslist {
     my $r = shift;  
     my %Sections;      my %Sections;
     &clear_classlist_variables();      &clear_classlist_variables();
     #      #
     # Retrieve the classlist      # Retrieve the classlist
     my $cid  = $ENV{'request.course.id'};      my $cid  = $env{'request.course.id'};
     my $cdom = $ENV{'course.'.$cid.'.domain'};      my $cdom = $env{'course.'.$cid.'.domain'};
     my $cnum = $ENV{'course.'.$cid.'.num'};      my $cnum = $env{'course.'.$cid.'.num'};
     my ($classlist,$field_names) = &Apache::loncoursedata::get_classlist($cid,      my ($classlist,$field_names) = &Apache::loncoursedata::get_classlist($cdom,
                                                                   $cdom,$cnum);   $cnum);
     if (exists($ENV{'form.Section'})) {      my @selected_sections = &get_selected_sections();
         if (ref($ENV{'form.Section'})) {      my @selected_groups = &get_selected_groups();
             @SelectedSections = @{$ENV{'form.Section'}};      #
         } elsif ($ENV{'form.Section'} !~ /^\s*$/) {      # Deal with instructors with restricted section access
             @SelectedSections = ($ENV{'form.Section'});      if ($env{'request.course.sec'} !~ /^\s*$/) {
         }          @selected_sections = ($env{'request.course.sec'});
     }  
     @SelectedSections = ('all') if (! @SelectedSections);  
     foreach (@SelectedSections) {  
         if ($_ eq 'all') {  
             @SelectedSections = ('all');  
         }  
     }      }
     #      #
     # Set up %StudentData      # Set up %StudentData
     @StudentDataOrder = qw/fullname username domain id section status/;      @StudentDataOrder = qw/fullname username domain id section status groups comments/;
     foreach my $field (@StudentDataOrder) {      foreach my $field (@StudentDataOrder) {
         $StudentData{$field}->{'title'} = $field;          $StudentData{$field}->{'title'} = &mt($field);
         $StudentData{$field}->{'base_width'} = length($field);          $StudentData{$field}->{'base_width'} = length(&mt($field));
         $StudentData{$field}->{'width'} =           $StudentData{$field}->{'width'} = 
                                $StudentData{$field}->{'base_width'};                                 $StudentData{$field}->{'base_width'};
     }      }
   
     #      #
       # get the status requested
       $enrollment_status = 'Active';
       $enrollment_status = $env{'form.Status'} if (exists($env{'form.Status'}));
       #
       # Get groupmembership
       my ($classgroups,$studentgroups);
       my %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum);
       if (%curr_groups) {
           ($classgroups,$studentgroups) = 
       &Apache::loncoursedata::get_group_memberships($classlist,
                                                             $field_names,
     $cdom,$cnum);
       }
       my $now = time;
   
     # Process the classlist      # Process the classlist
     while (my ($student,$student_data) = each (%$classlist)) {      while (my ($student,$student_data) = each (%$classlist)) {
         my $studenthash = ();          my $studenthash = ();
Line 253  sub PrepareClasslist { Line 255  sub PrepareClasslist {
                 $StudentData{$field}->{'width'} = $length;                   $StudentData{$field}->{'width'} = $length; 
             }              }
         }          }
           my @studentsgroups = &Apache::loncoursedata::get_students_groups
                                                      ($student,$enrollment_status,
                                                       $classgroups);
           if (@studentsgroups) {
               $studenthash->{'groups'} = join(', ',@studentsgroups);
               $studenthash->{'groupref'} = \@studentsgroups;
           } else {
               $studenthash->{'groups'} = 'none';
               $studenthash->{'groupref'} = []; 
           }
         push (@FullClasslist,$studenthash);          push (@FullClasslist,$studenthash);
         #          #
         # Build up a list of sections          # Build up a list of sections
Line 264  sub PrepareClasslist { Line 276  sub PrepareClasslist {
         $Sections{$section}++;          $Sections{$section}++;
         #          #
         # Only put in the list those students we are interested in          # Only put in the list those students we are interested in
         foreach my $sect (@SelectedSections) {          foreach my $sect (@selected_sections) {
             if (($sect eq 'all') || ($section eq $sect)) {              if ( (($sect eq 'all') || 
                 push (@Students,$studenthash);                    ($section eq $sect)) &&
                 last;                   (($studenthash->{'status'} eq $enrollment_status) || 
                     ($enrollment_status eq 'Any')) 
                    ){
                   my $groupcheck = 0;
                   if (grep(/^all$/,@selected_groups)) {
                       push(@Students,$studenthash);
                       last;
                   } elsif (grep(/^none$/,@selected_groups)) {
                       if ($studenthash->{'groups'} eq 'none') {
                           push(@Students,$studenthash);
                           last;
                       }     
                   } else {
                       foreach my $group (@selected_groups) {
                           if (grep(/^$group$/,@studentsgroups)) {
                               push(@Students,$studenthash);
                               $groupcheck = 1;
                               last;
                           }
                       }
                       if ($groupcheck) {
                           last;
                       }
                   }
             }              }
         }          }
     }      }
     #      #
     # Put the consolidated section data in the right place      # Put the consolidated section data in the right place
     @Sections = sort {$a cmp $b} keys(%Sections);      if ($env{'request.course.sec'} !~ /^\s*$/) {
     unshift(@Sections,'all'); # Put 'all' at the front of the list          @Sections = ($env{'request.course.sec'});
       } else {
           @Sections = sort {$a cmp $b} keys(%Sections);
           unshift(@Sections,'all'); # Put 'all' at the front of the list
       }
       # Sort the groups
       @Groups = sort {$a cmp $b} keys(%{$studentgroups});
       unshift(@Groups,'all'); # Put 'all' at the front of the list
   
     #      #
     # Sort the Students      # Sort the Students
     my $sortby = 'fullname';      my $sortby = 'fullname';
     $sortby = $ENV{'form.sort'} if (exists($ENV{'form.sort'}));      $sortby = $env{'form.sort'} if (exists($env{'form.sort'}));
     my @TmpStudents = sort { $a->{$sortby} cmp $b->{$sortby} ||      my @TmpStudents = sort { lc($a->{$sortby}) cmp lc($b->{$sortby}) ||
                              $a->{'fullname'} cmp $b->{'fullname'} } @Students;                               lc($a->{'fullname'}) cmp lc($b->{'fullname'}) ||
        lc($a->{'username'}) cmp lc($b->{'username'}) } @Students;
     @Students = @TmpStudents;      @Students = @TmpStudents;
     #       # 
     # Now deal with that current student thing....      # Now deal with that current student thing....
     if (exists($ENV{'form.StudentAssessmentStudent'})) {      $curr_student = undef;
       if (exists($env{'form.SelectedStudent'})) {
         my ($current_uname,$current_dom) =           my ($current_uname,$current_dom) = 
             split(':',$ENV{'form.StudentAssessmentStudent'});              split(':',$env{'form.SelectedStudent'});
         my $i;          my $i;
         for ($i = 0; $i<=$#Students; $i++) {          for ($i = 0; $i<=$#Students; $i++) {
             next if (($Students[$i]->{'username'} ne $current_uname) ||               next if (($Students[$i]->{'username'} ne $current_uname) || 
Line 294  sub PrepareClasslist { Line 339  sub PrepareClasslist {
             $curr_student = $Students[$i];              $curr_student = $Students[$i];
             last; # If we get here, we have our student.              last; # If we get here, we have our student.
         }          }
         if ($i == 0) {          if (defined($curr_student)) {
             $prev_student = 'none';              if ($i == 0) {
         } else {                  $prev_student = undef;
             $prev_student = $Students[$i-1];              } else {
         }                  $prev_student = $Students[$i-1];
         if ($i == $#Students) {              }
             $next_student = 'none';              if ($i == $#Students) {
         } else {                  $next_student = undef;
             $next_student = $Students[$i+1];              } else {
                   $next_student = $Students[$i+1];
               }
         }          }
     }      }
     #      #
     if (exists($ENV{'form.StudentData'})) {      if (exists($env{'form.StudentData'})) {
         if (ref($ENV{'form.StudentData'}) eq 'ARRAY') {   @SelectedStudentData = 
             @SelectedStudentData = @{$ENV{'form.StudentData'}};      &Apache::loncommon::get_env_multiple('form.StudentData');
         } else {  
             @SelectedStudentData = ($ENV{'form.StudentData'});  
         }  
     } else {      } else {
         @SelectedStudentData = ('fullname');          @SelectedStudentData = ('username');
     }      }
     foreach (@SelectedStudentData) {      foreach (@SelectedStudentData) {
         if ($_ eq 'all') {          if ($_ eq 'all') {
Line 330  sub PrepareClasslist { Line 374  sub PrepareClasslist {
   
 =pod  =pod
   
 =item &current_student()  =item get_selected_sections
   
 Returns a pointer to a hash containing data about the currently  Returns an array of the selected sections
 selected student.  
   
 =cut  =cut
   
 #######################################################  #######################################################
 #######################################################  #######################################################
 sub current_student {   sub get_selected_sections {
     if (defined($curr_student)) {      my @selected_sections = 
         return $curr_student;   &Apache::loncommon::get_env_multiple('form.Section');
     } else {      @selected_sections = ('all') if (! @selected_sections);
         return 'All Students';      foreach (@selected_sections) {
           if ($_ eq 'all') {
               @selected_sections = ('all');
           }
       }
       #
       # Deal with instructors with restricted section access
       if ($env{'request.course.sec'} !~ /^\s*$/) {
           @selected_sections = ($env{'request.course.sec'});
     }      }
       return @selected_sections;
 }  }
   
 #######################################################  #######################################################
 #######################################################  #######################################################
                                                                                       
 =pod  =pod
                                                                                       
 =item &previous_student()  =item get_selected_groups
                                                                                       
 Returns a pointer to a hash containing data about the student prior  Returns an array of the selected groups
 in the list of students.  Or something.                                                                                        
   
 =cut  =cut
                                                                                       
 #######################################################  #######################################################
 #######################################################  #######################################################
 sub previous_student {   sub get_selected_groups {
     if (defined($prev_student)) {      my @selected_groups =
         return $prev_student;          &Apache::loncommon::get_env_multiple('form.Group');
     } else {      @selected_groups = ('all') if (! @selected_groups);
         return 'No Student Selected';      foreach my $grp (@selected_groups) {
           if ($grp eq 'all') {
               @selected_groups = ('all');
               last;
           }
     }      }
       return @selected_groups;
 }  }
                                                                                       
 #######################################################  
 #######################################################  
   
 =pod  =pod
   
 =item &next_student()  =item &section_and_enrollment_description
   
 Returns a pointer to a hash containing data about the next student  Returns a string describing the currently selected section(s), group(s) and 
 to be viewed.  enrollment status.  
   
   Inputs: mode = 'plaintext' or 'localized'  (defaults to 'localized')
       'plaintext' is used for example in Excel spreadsheets.
   Returns: scalar description string.
   
 =cut  =cut
   
 #######################################################  #######################################################
 #######################################################  #######################################################
 sub next_student {   sub section_and_enrollment_description {
     if (defined($next_student)) {      my ($mode) = @_;
         return $next_student;      if (! defined($mode)) { $mode = 'localized'; }
       my @sections = &Apache::lonstatistics::get_selected_sections();
       my @groups = &Apache::lonstatistics::get_selected_groups();
       my $description;
       if ($mode eq 'localized') {
           $description = &mt('Unable to determine section, groups and enrollment');
       } elsif ($mode eq 'plaintext') {
           $description = 'Unable to determine section, groups and enrollment';
     } else {      } else {
         return 'No Student Selected';          $description = 'Bad parameter passed to lonstatistics::section_and_enrollment_description';
           &Apache::lonnet::logthis($description);
       }
       $description = &section_or_group_text($mode,'section',@sections).
    ' '.&section_or_group_text($mode,'group',@groups);
       if ($mode eq 'localized') {
           $description .= &mt(' [_1] enrollment status.',$env{'form.Status'});
       } elsif ($mode eq 'plaintext') {
           $description .= ' '.$env{'form.Status'}.' enrollment status.';
     }      }
       return $description;
 }  }
   
 #######################################################  #######################################################
 #######################################################  #######################################################
   
 =pod  sub section_or_group_text {
       my ($mode,$type,@items) = @_;
 =item &clear_sequence_variables()      my $text;
       my %phrases = ();
 =cut      %{$phrases{'section'}} = (
                                 single => 'Section',
 #######################################################                                all => 'All sections',
 #######################################################                                plural => 'Sections',
 sub clear_sequence_variables {                               );
     undef($top_map);      %{$phrases{'group'}} = (
     undef(@Sequences);                                single => 'Group',
     undef(@Assessments);                                all => 'All groups',
                                 plural => 'Groups',
                                );
       if (scalar(@items) == 1 && $items[0] ne 'all') {
           if ($mode eq 'localized') {
               $text = &mt('[_1] [_2].',$phrases{$type}{single},$items[0]);
           } elsif ($mode eq 'plaintext') {
               $text = $phrases{$type}{single}.' '.$items[0].'.';
   
           }
       } elsif (scalar(@items) && $items[0] eq 'all') {
           if ($mode eq 'localized') {
               $text = &mt('[_1].',$phrases{$type}{all});
           } elsif ($mode eq 'plaintext') {
               $text = $phrases{$type}{all}.'.';
           }
       } elsif (scalar(@items)) {
           my $lastitem = pop(@items);
           if ($mode eq 'localized') {
               $text = &mt('[_1] [_2] and [_3].',$phrases{$type}{plural},
                           join(', ',@items),$lastitem);
           } elsif ($mode eq 'plaintext') {
               $text = $phrases{$type}{plural}.' '.join(', ',@items).' and '.
                       $lastitem.'.';
           }
       }
       return $text;
 }  }
   
 #######################################################  
 #######################################################  
   
 =pod  =pod
   
 =item &SetSelectedMaps($elementname)  =item get_students
   
 Sets the @SelectedMaps array from $ENV{'form.'.$elementname};  Returns a list of the selected students
   
 =cut  =cut
   
 #######################################################  #######################################################
 #######################################################  #######################################################
 sub SetSelectedMaps {  sub get_students {
     my $elementname = shift;      if (! @Students) {
     if (exists($ENV{'form.'.$elementname})) {          &PrepareClasslist()
         if (ref($ENV{'form.'.$elementname})) {  
             @SelectedMaps = @{$ENV{'form.'.$elementname}};  
         } else {  
             @SelectedMaps = ($ENV{'form.'.$elementname});  
         }  
     } else {  
         @SelectedMaps = ('all');  
     }      }
       return @Students;
 }  }
   
   
 #######################################################  #######################################################
 #######################################################  #######################################################
   
 =pod  =pod
   
 =item &Sequences_with_Assess()  =item &current_student()
   
 Returns an array containing the subset of @Sequences which contain  Returns a pointer to a hash containing data about the currently
 assessments.  selected student.
   
 =cut  =cut
   
 #######################################################  #######################################################
 #######################################################  #######################################################
 sub Sequences_with_Assess {  sub current_student { 
     my @Sequences_to_Show;      return $curr_student;
     foreach my $map_symb (@SelectedMaps) {  
         foreach my $sequence (@Sequences) {  
             next if ($sequence->{'symb'} ne $map_symb && $map_symb ne 'all');  
             next if ($sequence->{'num_assess'} < 1);  
             push (@Sequences_to_Show,$sequence);  
         }  
     }  
     return @Sequences_to_Show;  
 }  }
   
 #######################################################  #######################################################
Line 466  sub Sequences_with_Assess { Line 548  sub Sequences_with_Assess {
   
 =pod  =pod
   
 =item &PrepareCourseData($r)  =item &previous_student()
   
   Returns a pointer to a hash containing data about the student prior
   in the list of students.  Or something.  
   
 =cut  =cut
   
 #######################################################  #######################################################
 #######################################################  #######################################################
 sub PrepareCourseData {  sub previous_student { 
     my ($r) = @_;      return $prev_student;
     &clear_sequence_variables();  
     my ($top,$sequences,$assessments) =   
         &Apache::loncoursedata::get_sequence_assessment_data();  
     if (! defined($top) || ! ref($top)) {  
         # There has been an error, better report it  
         &Apache::lonnet::logthis('top is undefined');  
         return;  
     }  
     $top_map = $top if (ref($top));  
     @Sequences = @{$sequences} if (ref($sequences) eq 'ARRAY');  
     @Assessments = @{$assessments} if (ref($assessments) eq 'ARRAY');  
     #  
     # Compute column widths  
     foreach my $seq (@Sequences) {  
         my $name_length = length($seq->{'title'});  
         my $num_parts = $seq->{'num_assess_parts'};  
         #  
         # The number of columns needed for the summation text:   
         #    " 1/5" = 1+3 columns, " 10/99" = 1+5 columns  
         my $sum_length = 1+1+2*(length($num_parts));  
         my $num_col = $num_parts+$sum_length;  
         if ($num_col < $name_length) {  
             $num_col = $name_length;  
         }  
         $seq->{'base_width'} = $name_length;  
         $seq->{'width'} = $num_col;  
     }  
     return;  
 }  }
   
 #######################################################  #######################################################
Line 509  sub PrepareCourseData { Line 566  sub PrepareCourseData {
   
 =pod  =pod
   
 =item &log_sequence($sequence,$recursive,$padding)  =item &next_student()
   
 Write data about the sequence to a logfile.  If $recursive is not  Returns a pointer to a hash containing data about the next student
 undef the data is written recursively.  $padding is used for recursive  to be viewed.
 calls.  
   
 =cut  =cut
   
 #######################################################  #######################################################
 #######################################################  #######################################################
 sub log_sequence {  sub next_student { 
     my ($seq,$recursive,$padding) = @_;      return $next_student;
     $padding = '' if (! defined($padding));  
     if (ref($seq) ne 'HASH') {  
         &Apache::lonnet::logthis('log_sequence passed bad sequnce');  
         return;  
     }  
     &Apache::lonnet::logthis($padding.'sequence '.$seq->{'title'});  
     while (my($key,$value) = each(%$seq)) {  
         next if ($key eq 'contents');  
         if (ref($value) eq 'ARRAY') {  
             for (my $i=0;$i< scalar(@$value);$i++) {  
                 &Apache::lonnet::logthis($padding.$key.'['.$i.']='.  
                                          $value->[$i]);  
             }  
         } else {  
             &Apache::lonnet::logthis($padding.$key.'='.$value);  
         }  
     }  
     if (defined($recursive)) {  
         &Apache::lonnet::logthis($padding.'-'x20);  
         &Apache::lonnet::logthis($padding.'contains:');  
         foreach my $item (@{$seq->{'contents'}}) {  
             if ($item->{'type'} eq 'container') {  
                 &log_sequence($item,$recursive,$padding.'    ');  
             } else {  
                 &Apache::lonnet::logthis($padding.'title = '.$item->{'title'});  
                 while (my($key,$value) = each(%$item)) {  
                     next if ($key eq 'title');  
                     if (ref($value) eq 'ARRAY') {  
                         for (my $i=0;$i< scalar(@$value);$i++) {  
                             &Apache::lonnet::logthis($padding.$key.'['.$i.']='.  
                                                      $value->[$i]);  
                         }  
                     } else {  
                         &Apache::lonnet::logthis($padding.$key.'='.$value);  
                     }  
                 }  
             }  
         }  
         &Apache::lonnet::logthis($padding.'end contents of '.$seq->{'title'});  
         &Apache::lonnet::logthis($padding.'-'x20);  
     }  
     return;  
 }  }
   
 ##############################################  ##############################################
Line 628  sub StudentDataSelect { Line 642  sub StudentDataSelect {
     return $Str;      return $Str;
 }  }
   
   #######################################################
   #######################################################
   
   =pod
   
   =item &get_selected_maps($elementname)
   
   Input: Name of the <select> form element used to specify the maps.
   
   Returns: Array of symbs of selected maps or the description 'all'.
      If form.$elementname does not exist, 'all' is returned.
   
   =cut
   
   #######################################################
   #######################################################
   sub get_selected_maps {
       my ($elementname) = @_;
       my @selected_maps = 
    &Apache::loncommon::get_env_multiple('form.'.$elementname);
       @selected_maps = ('all') if (! @selected_maps);
       foreach my $map (@selected_maps) {
           if ($map eq 'all') {
               @selected_maps = ('all');
               last;
           }
       }
       return @selected_maps;
   }
   
   
   #######################################################
   #######################################################
   
   =pod
   
   =item &selected_sequences_with_assessments
   
   Retrieve the sequences which were selected by the user to show.  
   
   Input: $mode: scalar.  Either 'selected' or 'all'.  If not specified,
       'selected' is used.
   
   Returns: an array containing a navmap object and navmap resources, 
       or an array containing a scalar with an error message.
   
   =cut
   
   #######################################################
   #######################################################
   sub selected_sequences_with_assessments {
       my ($mode) = @_;
       $mode = 'selected' if (! defined($mode));
       my $navmap = Apache::lonnavmaps::navmap->new();
       if (!defined($navmap)) {
           return ('Can not open Coursemap');
       }
       #
       my @sequences = $navmap->retrieveResources(undef,
                                                  sub { shift->is_map(); },1,0,1);
       my @sequences_with_assessments;
       for my $sequence ($navmap->getById('0.0'), @sequences) {
    if ($navmap->hasResource($sequence,sub { shift->is_problem(); },0,1)){
               push(@sequences_with_assessments,$sequence);
           }
       }
       #
       my @sequences_to_show;
       foreach my $sequence (@sequences_with_assessments) {
           if ($mode eq 'all') {
               push (@sequences_to_show,$sequence);
           } elsif ($mode eq 'selected') {
               foreach my $map_symb (&get_selected_maps('Maps')) {
                   if ($sequence->symb eq $map_symb || $map_symb eq 'all'){
                       push (@sequences_to_show,$sequence);
                       last; # Only put it in once
                   }
               }
           }
   
       }
       return $navmap,@sequences_to_show;
   }
   
 ##############################################  ##############################################
 ##############################################  ##############################################
   
 =pod   =pod 
   
 =item &MapSelect($elementname,$status,$numvisible,$restriction)   =item &map_select($elementname,$status,$numvisible,$restriction) 
   
 Returns html for a selection box allowing the user to choose one (or more)   Returns html for a selection box allowing the user to choose one (or more) 
 of the sequences in the course.  The values of the sequences are the symbs.  of the sequences in the course.  The values of the sequences are the symbs.
Line 647  If the top sequence is selected, the val Line 745  If the top sequence is selected, the val
   
 =item $numvisible The number of options to be visible  =item $numvisible The number of options to be visible
   
 =item $restriction Code reference to subroutine which returns true or   
 false.  The code must expect a reference to a sequence data structure.  
   
 =back  =back
   
 =cut  =cut
   
 ##############################################  ##############################################
 ##############################################  ##############################################
 sub MapSelect {  sub map_select {
     my ($elementname,$status,$numvisible,$restriction)=@_;      my ($elementname,$status,$numvisible)=@_;
     if ($numvisible < 1) {      if ($numvisible < 1) {
         return;          return;
     }      }
     #      #
     # Set up array of selected items      # Set up array of selected items
     &SetSelectedMaps($elementname);      my @selected_maps = &get_selected_maps($elementname);
     #  
     # Set up the restriction call  
     if (! defined($restriction)) {  
         $restriction = sub { 1; };  
     }  
     #      #
     # Build the form element      # Build the form element
     my $Str = "\n";      my $form = "\n";
     $Str .= '<select name="'.$elementname.'" ';      $form .= '<select name="'.$elementname.'" ';
     if ($status ne 'single') {      if ($status ne 'single') {
         $Str .= 'multiple="true" ';          $form .= 'multiple="true" ';
     }  
     $Str .= 'size="'.$numvisible.'" >'."\n";  
     #  
     # Deal with 'all'  
     foreach (@SelectedMaps) {  
         if ($_ eq 'all') {  
             @SelectedMaps = ('all');  
             last;  
         }  
     }      }
       $form .= 'size="'.$numvisible.'" >'."\n";
     #      #
     # Put in option for 'all'      # Put in option for 'all'
     $Str .= '    <option value="all" ';      $form .= '    <option value="all" ';
     foreach (@SelectedMaps) {      if ($selected_maps[0] eq 'all') {
         if ($_ eq 'all') {          $form .= 'selected ';
             $Str .= 'selected ';  
             last;  
         }  
     }      }
     $Str .= ">all</option>\n";      $form .= ">all</option>\n";
     #      #
     # Loop through the sequences      # Loop through the sequences
     foreach my $seq (@Sequences) {      my @sequences = &selected_sequences_with_assessments('all');
         next if (! $restriction->($seq));      my $navmap;
         $Str .= '    <option value="'.$seq->{'symb'}.'" ';      if (!ref($sequences[0])) {
         foreach (@SelectedMaps) {          return $sequences[0];
             if ($seq->{'symb'} eq $_) {      } else {
                 $Str .= 'selected ';          $navmap = shift(@sequences);
       }
       foreach my $seq (@sequences){
           $form .= '    <option value="'.$seq->symb.'" ';
           foreach (@selected_maps) {
               if ($seq->symb eq $_) {
                   $form .= 'selected ';
                 last;                  last;
             }              }
         }          }
         $Str .= '>'.$seq->{'title'}."</option>\n";          $form .= '>'.$seq->compTitle."</option>\n";
     }      }
     $Str .= "</select>\n";      $form .= "</select>\n";
     return $Str;      return $form;
 }  }
   
 ##############################################  ##############################################
Line 722  sub MapSelect { Line 807  sub MapSelect {
 Returns html for a selection box allowing the user to choose one (or more)   Returns html for a selection box allowing the user to choose one (or more) 
 of the sections in the course.    of the sections in the course.  
   
   Uses the package variables @Sections
 =over 4  =over 4
   
 =item $elementname The name of the HTML form element  =item $elementname The name of the HTML form element
Line 730  of the sections in the course. Line 816  of the sections in the course.
   
 =item $numvisible The number of options to be visible  =item $numvisible The number of options to be visible
   
 =item $selected Array ref to the names of the already selected sections.  
 If undef, $ENV{'form.'.$elementname} is used.    
 If $ENV{'form.'.$elementname} is also empty, none will be selected.  
   
 =item $restriction Code reference to subroutine which returns true or   
 false.  The code must expect a reference to a sequence data structure.  
   
 =back  =back
   
 =cut  =cut
Line 749  sub SectionSelect { Line 828  sub SectionSelect {
         return;          return;
     }      }
     #      #
       # Make sure we have the data we need to continue
       if (! @Sections) {
           &PrepareClasslist()
       }
       #
     # Build the form element      # Build the form element
     my $Str = "\n";      my $Str = "\n";
     $Str .= '<select name="'.$elementname.'" ';      $Str .= '<select name="'.$elementname.'" ';
Line 760  sub SectionSelect { Line 844  sub SectionSelect {
     # Loop through the sequences      # Loop through the sequences
     foreach my $s (@Sections) {      foreach my $s (@Sections) {
         $Str .= '    <option value="'.$s.'" ';          $Str .= '    <option value="'.$s.'" ';
         foreach (@SelectedSections) {          foreach (&get_selected_sections()) {
             if ($s eq $_) {              if ($s eq $_) {
                 $Str .= 'selected ';                  $Str .= 'selected ';
                 last;                  last;
Line 772  sub SectionSelect { Line 856  sub SectionSelect {
     return $Str;      return $Str;
 }  }
   
   ##############################################
   ##############################################
                                                                                       
   =pod
                                                                                       
   =item &GroupSelect($elementname,$status,$numvisible)
                                                                                       
   Returns html for a selection box allowing the user to choose one (or more)
   of the groups in the course.
                                                                                       
   Uses the package variables @Groups
   =over 4
                                                                                       
   =item $elementname The name of the HTML form element
                                                                                       
   =item $status 'multiple' or 'single' selection box
                                                                                       
   =item $numvisible The number of options to be visible
                                                                                       
   =back
                                                                                       
   =cut
                                                                                       
   ##############################################
   ##############################################
   sub GroupSelect {
       my ($elementname,$status,$numvisible)=@_;
       if ($numvisible < 1) {
           return;
       }
       #
       # Make sure we have the data we need to continue
       if (! @Groups) {
           &PrepareClasslist();
       }
       #
       # Build the form element
       my $Str = "\n";
       $Str .= '<select name="'.$elementname.'" ';
       if ($status ne 'single') {
           $Str .= 'multiple="true" ';
       }
       $Str .= 'size="'.$numvisible.'" >'."\n";
       #
       # Loop through the groups
       foreach my $s (@Groups) {
           $Str .= '    <option value="'.$s.'" ';
           foreach my $group (&get_selected_groups()) {
               if ($s eq $group) {
                   $Str .= 'selected ';
                   last;
               }
           }
           $Str .= '>'.$s."</option>\n";
       }
       $Str .= "</select>\n";
   }
   
   
 ##################################################  ##################################################
 ##################################################  ##################################################
 sub DisplayClasslist {  sub DisplayClasslist {
     my ($r)=@_;      my ($r)=@_;
       &Apache::lonhtmlcommon::add_breadcrumb
           ({text=>'Select One Student'});
     #      #
     my @Fields = ('fullname','username','domain','id','section');      # Output some of the standard interface components
       my $Str;
       $Str .= &Apache::lonhtmlcommon::breadcrumbs('Select One Student');
       $Str .= '<p><table cellspacing="5">'."\n";
       $Str .= '<tr>';
       $Str .= '<th align="center"><b>'.&mt('Sections').'</b></th>';
       $Str .= '<th align="center"><b>'.&mt('Groups').'</b></th>';
       $Str .= '<th align="center"><b>'.&mt('Enrollment Status').'</b></th>';
       $Str .= '</tr>'.$/;
       $Str .= '<tr>';
       $Str .= '<td>'.
           &Apache::lonstatistics::SectionSelect('Section','multiple',5).
           '</td>';
       $Str .=  '<td>'.
           &Apache::lonstatistics::GroupSelect('Group','multiple',5).
           '</td>';
       $Str .= '<td>'.
           &Apache::lonhtmlcommon::StatusOptions(undef,undef,5).
           '</td>';
       
       $Str .= '</tr>'.$/;
       $Str .= '</table></p>';
       $Str .= '<input type="submit" name="selectstudent" value="'.
           &mt('Update Display').'" />';
       $r->print($Str);
       $r->rflush();
       #
       my @Fields = ('fullname','username','domain','id','section','status','groups');
     #      #
     my $Str='';      $Str = '';
       my @selected_sections = &get_selected_sections();
       if (! @Students) {
           if ($selected_sections[0] eq 'all') { 
               if (lc($env{'form.Status'}) eq 'any') {
                   $Str .= '<h2>'.
                       &mt('There are no students in the course.').
                       '</h2>';
               } elsif (lc($env{'form.Status'}) eq 'active') {
                   $Str .= '<h2>'.
                   &mt('There are no currently enrolled students in the course.').
                       '</h2>';
               } elsif (lc($env{'form.Status'}) eq 'expired') {
                   $Str .= '<h2>'.
                       &mt('There are no previously enrolled students in the course.').
                           '</h2>';
               }
           } else { 
               my $sections;
               if (lc($env{'form.Status'}) eq 'any') {
                   $Str .= '<h2>'.
                       &mt('There are no students in the selected sections.').
                       '</h2>';
               } elsif (lc($env{'form.Status'}) eq 'active') {
                   $Str .= '<h2>'.
                       &mt('There are no currently enrolled students in the selected sections.').
                       '</h2>';
               } elsif (lc($env{'form.Status'}) eq 'expired') {
                   $Str .= '<h2>'.
                       &mt('There are no previously enrolled students in the selected sections.').
                       '</h2>';
               }
           }
           $Str.= '<a href="/adm/statistics?reportSelected=student_assessment">'.
               &mt('Click here to return to the chart').'</a>';
           $r->print($Str);
           $r->rflush();
           return;
       }
   
       # "Click" is asinine but it is probably not my place to change the world.
       $Str .= '<h2>Click on a students name or username to view their chart</h2>';
     $Str .= '<table border="0"><tr><td bgcolor="#777777">'."\n";      $Str .= '<table border="0"><tr><td bgcolor="#777777">'."\n";
     $Str .= '<table border="0" cellpadding="3"><tr bgcolor="#e6ffff">'."\n";      $Str .= '<table border="0" cellpadding="3"><tr bgcolor="#e6ffff">'."\n";
     foreach my $field (@Fields) {      foreach my $field (@Fields) {
         $Str .= '<th><a href="/adm/statistics?reportSelected=classlist&sort='.$field.'">'.$field.          $Str .= '<th><a href="/adm/statistics?'.
               'reportSelected=student_assessment&'.
               'selectstudent=1&'.
               'sort='.$field.'">'.&mt($field).
             '</a></th>';              '</a></th>';
     }      }
     $Str .= '</tr>'."\n";      $Str .= '</tr>'."\n";
Line 800  sub DisplayClasslist { Line 1016  sub DisplayClasslist {
         #          #
         foreach my $field (@Fields) {          foreach my $field (@Fields) {
             $Str .= '<td>';              $Str .= '<td>';
             if ($field eq 'fullname') {              if ($field eq 'fullname' || $field eq 'username') {
                 $Str .= '<a href="/adm/statistics?reportSelected=';                  $Str .= '<a href="/adm/statistics?reportSelected=';
                 $Str .= &Apache::lonnet::escape('student_assessment');                  $Str .= &Apache::lonnet::escape('student_assessment');
                 $Str .= '&StudentAssessmentStudent=';                  $Str .= '&sort='.&Apache::lonnet::escape($env{'form.sort'});
                   $Str .= '&SelectedStudent=';
                 $Str .= &Apache::lonnet::escape($sname).'">';                  $Str .= &Apache::lonnet::escape($sname).'">';
                 $Str .= $student->{$field}.'&nbsp';                  $Str .= $student->{$field}.'&nbsp';
                 $Str .= '</a>';                  $Str .= '</a>';
               } elsif ($field eq 'status') {
                   $Str .= &mt($student->{$field});
             } else {              } else {
                 $Str .= $student->{$field};                  $Str .= $student->{$field};
             }              }
Line 825  sub DisplayClasslist { Line 1044  sub DisplayClasslist {
 ##############################################  ##############################################
 ##############################################  ##############################################
 sub CreateMainMenu {  sub CreateMainMenu {
     my ($status,$reports,$current)=@_;  
     #      #
     my $Str = '';      # Define menu data
     #      my @reports = ({ internal_name => 'problem_statistics',
     $Str .= '<table border="0"><tbody><tr>'."\n";                       name => &mt('Overall Problem Statistics'),
     $Str .= '<td></td>'."\n";                       short_description => 
     $Str .= '<td align="center"><b>Select a Report</b></td>'."\n";      &mt('Student performance statistics on all problems.'),
     $Str .= '<td align="center"><b>Student Status</b></td></tr>'."\n";                   },
     $Str .= '<tr>'."\n";                     { internal_name => 'problem_analysis',
     #                       name => &mt('Detailed Problem Analysis'),
     $Str .= '<td align="center"><input type="submit" name="Refresh" ';                       short_description => 
     $Str .= 'value="Update Display" /></td>'."\n";      &mt('Detailed statistics and graphs of student performance on problems.'),
                    },
                      { internal_name => 'submissiontime_analysis',
                        name => &mt('Submission Time Plots'),
                        short_description => 
       &mt('Display and analysis of submission times on assessments.'),
                    },
                      { internal_name => 'student_submission_reports',
                        name => &mt('Student Submission Reports'),
                        short_description => 
       &mt('Prepare reports of student submissions.'),
                    },
                      { internal_name => 'survey_reports',
                        name => &mt('Survey Reports'),
                        short_description => 
       &mt('Prepare reports on survey results.'),
                    },
                      { internal_name => 'correct_problems_plot',
                        name => &mt('Correct Problems Plot'),
                        short_description => 
       &mt('Display a histogram of student performance in the course.'),
                    },
   #                   { internal_name => 'grading_analysis',
   #                     name => &mt('Detailed Grading Analysis'),
   #                     short_description => 
   #    &mt('Display statistics about who graded who.'),
   #                 },
   #                   { internal_name => 'student_assessment',
   #                     name => &mt('Problem Status Chart'),
   #                     short_description => 
   #    &mt('Brief view of each students performance in course.'),
   #                 },
                      # 'percentage'  => 'Correct-problems Plot',
                      # 'activitylog' => 'Activity Log',
                      );
     #      #
     $Str .= '<td align="center">';      # Create the menu
     $Str .= '<select name="reportSelected" >'."\n";      my $Str;
     foreach (sort(keys(%$reports))) {      $Str .= '<h2>'.&mt('Please select a report to generate').'</h2>';
         $Str .= '<option value="'.$_.'"';      foreach my $reportdata (@reports) {
         if($current eq $_) {          $Str .='    <h3><a href="/adm/statistics?reportSelected='.
             $Str .= ' selected';              $reportdata->{'internal_name'}.'" >'.
         }              $reportdata->{'name'}."</a></h3>\n";
         $Str .= '>'.$reports->{$_}.'</option>'."\n";          $Str .= '    '.('&nbsp;'x8).$reportdata->{'short_description'}.
               "\n";
     }      }
     $Str .= '</select></td>'."\n";      $Str .="</dl>\n";
     #  
     $Str .= '<td align="center">';  
     $Str .= &Apache::lonhtmlcommon::StatusOptions($status, 'Statistics');  
     $Str .= '</td>'."\n";  
     #  
     $Str .= '</tr></tbody></table>'."\n";  
     $Str .= '<hr>'."\n";  
     #      #
     return $Str;      return $Str;
 }  }
Line 870  sub handler { Line 1116  sub handler {
     if ($loaderror) { return $loaderror; }      if ($loaderror) { return $loaderror; }
     $loaderror=      $loaderror=
        &Apache::lonnet::overloaderror($r,         &Apache::lonnet::overloaderror($r,
          $ENV{'course.'.$ENV{'request.course.id'}.'.home'});           $env{'course.'.$env{'request.course.id'}.'.home'});
     if ($loaderror) { return $loaderror; }      if ($loaderror) { return $loaderror; }
     #      #
     # Check for access      # Check for access
     unless(&Apache::lonnet::allowed('vgr',$ENV{'request.course.id'})) {      if (! &Apache::lonnet::allowed('vgr',$env{'request.course.id'})) {
         $ENV{'user.error.msg'}=          $env{'user.error.msg'}=
         $r->uri.":vgr:0:0:Cannot view grades for complete course";              $r->uri.":vgr:0:0:Cannot view grades for complete course";
         return HTTP_NOT_ACCEPTABLE;          if (! &Apache::lonnet::allowed('vgr',
     }                        $env{'request.course.id'}.'/'.$env{'request.course.sec'})) {
     #              $env{'user.error.msg'}=
     # Set document type for header only                  $r->uri.":vgr:0:0:Cannot view grades with given role";
     if($r->header_only) {              return HTTP_NOT_ACCEPTABLE;
         if ($ENV{'browser.mathml'}) {  
             $r->content_type('text/xml');  
         } else {  
             $r->content_type('text/html');  
         }          }
         &Apache::loncommon::no_cache($r);  
         $r->send_http_header;  
         return OK;  
     }      }
     #      #
     # Send the header      # Send the header
     $r->content_type('text/html');      &Apache::loncommon::no_cache($r);
       &Apache::loncommon::content_type($r,'text/html');
     $r->send_http_header;      $r->send_http_header;
       if ($r->header_only) { return OK; }
     #      #
     # Extract form elements from query string      # Extract form elements from query string
     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},      &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                                             ['sort','reportSelected',                                              ['sort','reportSelected',
                                              'StudentAssessmentStudent']);                                               'SelectedStudent']);
     if (! exists($ENV{'form.reportSelected'})) {  
         $ENV{'form.reportSelected'} = 'student_assessment';  
     }  
     #      #
     # Give the LON-CAPA page header      # Give the LON-CAPA page header
     $r->print(&Apache::lonhtmlcommon::Title('Course Statistics and Charts'));      my $style = <<ENDSTYLE;
     $r->rflush();  <style type="text/css">
     #      ul.sub_studentans { list-style-type: none }
     # Set up the statistics and chart environment      ul.sub_correctans { list-style-type: none }
     &PrepareClasslist($r);      tr.even           { background-color: \#CCCCCC }
     &PrepareCourseData($r);      td.essay          { border: 1px solid gray; }
     #  </style>
     # Begin form output  ENDSTYLE
     $r->print('<form name="Statistics" ');        
     $r->print('method="post" action="/adm/statistics">');      $r->print(&Apache::loncommon::start_page('Course Statistics and Charts',
     #       $style));
     # Print main menu  
     my %reports = ('classlist'          => 'Class list',  
                    'problem_statistics' => 'Problem Statistics',  
                    'student_assessment' => 'Student Assessment',  
                    'percentage'         => 'Correct-problems Plot',  
                    'option_response'    => 'Option Response Analysis',  
 #                   'activitylog'        => 'Activity Log',  
                    );  
     $r->print(&CreateMainMenu($ENV{'form.status'},  
                               \%reports,$ENV{'form.reportSelected'}));  
     $r->rflush();      $r->rflush();
       # 
       # Either print out a menu for them or send them to a report
       &Apache::lonhtmlcommon::clear_breadcrumbs();
       &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/statistics',
                                               title=>'Statistics',
                                               text =>'Statistics',
                                               faq=>139,
                                               bug=>'Statistics and Charts'});
       if (! exists($env{'form.reportSelected'}) || 
           $env{'form.reportSelected'} eq '') {
           $r->print(&Apache::lonhtmlcommon::breadcrumbs('Statistics Main Page').
                     &CreateMainMenu());
       } else {
     #      #
     my $GoToPage = $ENV{'form.reportSelected'};          if (! &Apache::lonmysql::verify_sql_connection()) {
     if($GoToPage eq 'activitylog') {              my $serveradmin = $r->dir_config('lonAdmEMail');
               $r->print('<h2><font color="Red">'.
                         &mt('Unable to connect to database!').
                         '</font></h2>');
               $r->print('<p>'.
                         &mt('Please notify the server administrator ').
                         '<b>'.$serveradmin.'</b></p>');
               $r->print('<p>'.
                         &mt('Course Statistics and Charts cannot be '.
                             'retrieved until the database is restarted.  '.
                             'Your data is intact but cannot be displayed '.
                             'at this time.').'</p>');
               $r->print(&Apache::loncommon::end_page());
               return;
           }
           #
           # Clean out the caches
           if (exists($env{'form.ClearCache'})) {
               &Apache::loncoursedata::delete_caches($env{'requres.course.id'});
           }
           #
           # Begin form output
           $r->print('<form name="Statistics" ');
           $r->print('method="post" action="/adm/statistics">');
           $r->rflush();
           #
           my $GoToPage = $env{'form.reportSelected'};
           #
           $r->print('<input type="hidden" name="reportSelected" value="'.
                     $GoToPage.'">');
           if($GoToPage eq 'activitylog') {
 #        &Apache::lonproblemstatistics::Activity();  #        &Apache::lonproblemstatistics::Activity();
     } elsif($GoToPage eq 'problem_statistics') {          } elsif($GoToPage eq 'problem_statistics') {
         &Apache::lonproblemstatistics::BuildProblemStatisticsPage($r,$c);              &Apache::lonhtmlcommon::add_breadcrumb
     } elsif($GoToPage eq 'option_response') {                  ({href=>'/adm/statistics?reportselected=problem_statistics',
 #        &Apache::lonproblemanalysis::BuildProblemAnalysisPage($r,$c);                    text=>'Overall Problem Statistics'});
     } elsif($GoToPage eq 'student_assessment') {              &Apache::lonproblemstatistics::BuildProblemStatisticsPage($r,$c);
         &Apache::lonstudentassessment::BuildStudentAssessmentPage($r,$c);          } elsif($GoToPage eq 'problem_analysis') {
     } elsif($GoToPage eq 'DoDiffGraph' || $GoToPage eq 'PercentWrongGraph') {              &Apache::lonhtmlcommon::add_breadcrumb
 #        &Apache::lonproblemstatistics::BuildGraphicChart($r,$c);                  ({href=>'/adm/statistics?reportselected=problem_analysis',
     } elsif($GoToPage eq 'classlist') {                    text=>'Detailed Problem Analysis'});
         &DisplayClasslist($r);              &Apache::lonproblemanalysis::BuildProblemAnalysisPage($r,$c);
     } elsif($GoToPage eq 'Correct-problems Plot') {          } elsif($GoToPage eq 'submissiontime_analysis') {
 # &Apache::lonpercentage::BuildPercentageGraph($r,$c);              &Apache::lonhtmlcommon::add_breadcrumb
                   ({href=>
                         '/adm/statistics?reportselected=submissiontime_analysis',
                         text=>'Submission Time Plots'});
               &Apache::lonsubmissiontimeanalysis::BuildSubmissionTimePage($r,$c);
           } elsif($GoToPage eq 'student_submission_reports') {
               &Apache::lonhtmlcommon::add_breadcrumb
                   ({href=>
                     '/adm/statistics?reportselected=student_submission_reports',
                     text=>'Student Submission Reports'});
               &Apache::lonstudentsubmissions::BuildStudentSubmissionsPage($r,$c);
           } elsif($GoToPage eq 'survey_reports') {
               &Apache::lonhtmlcommon::add_breadcrumb
                   ({href=>
                     '/adm/statistics?reportselected=survey_reports',
                     text=>'Survey Reports'});
               &Apache::lonsurveyreports::BuildSurveyReportsPage($r,$c);
           } elsif($GoToPage eq 'correct_problems_plot') {
               &Apache::lonhtmlcommon::add_breadcrumb
                   ({href=>'/adm/statistics?reportselected=correct_problems_plot',
                     text=>'Correct Problems Plot'});
               &Apache::loncorrectproblemplot::BuildCorrectProblemsPage($r,$c);
           } elsif($GoToPage eq 'student_assessment') {
               &Apache::lonhtmlcommon::clear_breadcrumbs();
               &Apache::lonhtmlcommon::add_breadcrumb
                   ({href=>'/adm/statistics?reportselected=student_assessment',
                     text=>'Chart'});
               &Apache::lonstudentassessment::BuildStudentAssessmentPage($r,$c);
           } elsif($GoToPage eq 'grading_analysis') {
               &Apache::lonhtmlcommon::add_breadcrumb
                   ({href=>'/adm/statistics?reportselected=grading_anaylsis',
                     text=>'Grading Analysis'});
               &Apache::longradinganalysis::build_grading_analysis_page($r,$c);
    }
           #
           $r->print("</form>\n");
     }      }
     #      $r->print(&Apache::loncommon::end_page());
     $r->print("</form>\n");  
     $r->print("</body>\n</html>\n");  
     $r->rflush();      $r->rflush();
     #      #
     return OK;      return OK;

Removed from v.1.65  
changed lines
  Added in v.1.135


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>