Annotation of loncom/interface/lonstatistics.pm, revision 1.65
1.1 albertel 1: # The LearningOnline Network with CAPA
2: #
1.65 ! matthew 3: # $Id: lonstatistics.pm,v 1.64 2003/03/07 18:46:38 matthew Exp $
1.1 albertel 4: #
5: # Copyright Michigan State University Board of Trustees
6: #
7: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
8: #
9: # LON-CAPA is free software; you can redistribute it and/or modify
10: # it under the terms of the GNU General Public License as published by
11: # the Free Software Foundation; either version 2 of the License, or
12: # (at your option) any later version.
13: #
14: # LON-CAPA is distributed in the hope that it will be useful,
15: # but WITHOUT ANY WARRANTY; without even the implied warranty of
16: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17: # GNU General Public License for more details.
18: #
19: # You should have received a copy of the GNU General Public License
20: # along with LON-CAPA; if not, write to the Free Software
21: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22: #
23: # /home/httpd/html/adm/gpl.txt
24: #
25: # http://www.lon-capa.org/
26: #
27: # (Navigate problems for statistical reports
1.14 minaeibi 28: #
1.1 albertel 29: ###
30:
1.59 matthew 31: =pod
32:
33: =head1 NAME
34:
35: lonstatistics
36:
37: =head1 SYNOPSIS
38:
39: Main handler for statistics and chart.
40:
41: =head1 PACKAGES USED
42:
1.60 matthew 43: use strict;
44: use Apache::Constants qw(:common :http);
45: use Apache::lonnet();
46: use Apache::lonhomework;
47: use Apache::loncommon;
48: use Apache::loncoursedata;
49: use Apache::lonhtmlcommon;
50: use Apache::lonproblemanalysis;
51: use Apache::lonproblemstatistics;
52: use Apache::lonstudentassessment;
53: use Apache::lonpercentage;
1.59 matthew 54:
55: =over 4
56:
57: =cut
58:
1.55 minaeibi 59: package Apache::lonstatistics;
1.1 albertel 60:
1.30 stredwic 61: use strict;
1.1 albertel 62: use Apache::Constants qw(:common :http);
1.61 matthew 63: use vars qw(
64: @FullClasslist
65: @Students
66: @Sections
67: @SelectedSections
68: %StudentData
69: @StudentDataOrder
70: @SelectedStudentData
71: $top_map
72: @Sequences
73: @SelectedMaps
74: @Assessments);
75:
1.1 albertel 76: use Apache::lonnet();
77: use Apache::lonhomework;
1.12 minaeibi 78: use Apache::loncommon;
1.29 stredwic 79: use Apache::loncoursedata;
80: use Apache::lonhtmlcommon;
1.61 matthew 81: use Apache::lonproblemanalysis();
82: use Apache::lonproblemstatistics();
83: use Apache::lonstudentassessment();
1.49 stredwic 84: use Apache::lonpercentage;
1.65 ! matthew 85: use Time::HiRes;
1.60 matthew 86:
87: #######################################################
88: #######################################################
89:
90: =pod
91:
92: =item Package Variables
93:
94: =item @FullClasslist The full classlist
95:
96: =item @Students The students we are concerned with for this invocation
97:
98: =item @Sections The sections available in this class
99:
100: =item $curr_student The student currently being examined
101:
102: =item $prev_student The student previous in the classlist
103:
104: =item $next_student The student next in the classlist
105:
106: =over
107:
108: =cut
109:
110: #######################################################
111: #######################################################
112: #
113: # Classlist variables
114: #
1.59 matthew 115: my $curr_student;
116: my $prev_student;
117: my $next_student;
118:
119: #######################################################
120: #######################################################
121:
122: =pod
123:
124: =item &clear_classlist_variables()
125:
126: undef the following package variables:
127:
128: =over
129:
1.60 matthew 130: =item @FullClasslist
131:
132: =item @Students
1.59 matthew 133:
1.60 matthew 134: =item @Sections
1.59 matthew 135:
1.60 matthew 136: =item @SelectedSections
1.59 matthew 137:
1.61 matthew 138: =item %StudentData
139:
140: =item @StudentDataOrder
141:
142: =item @SelectedStudentData
143:
1.60 matthew 144: =item $curr_student
1.59 matthew 145:
1.60 matthew 146: =item $prev_student
1.59 matthew 147:
1.60 matthew 148: =item $next_student
1.59 matthew 149:
150: =back
151:
152: =cut
153:
154: #######################################################
155: #######################################################
156: sub clear_classlist_variables {
157: undef(@FullClasslist);
158: undef(@Students);
159: undef(@Sections);
1.60 matthew 160: undef(@SelectedSections);
1.61 matthew 161: undef(%StudentData);
162: undef(@SelectedStudentData);
1.59 matthew 163: undef($curr_student);
164: undef($prev_student);
165: undef($next_student);
166: }
167:
168: #######################################################
169: #######################################################
170:
171: =pod
172:
173: =item &PrepareClasslist()
174:
175: Build up the classlist information. The classlist information is kept in
176: the following package variables:
177:
178: =over
179:
1.60 matthew 180: =item @FullClasslist
181:
182: =item @Students
1.59 matthew 183:
1.60 matthew 184: =item @Sections
1.59 matthew 185:
1.60 matthew 186: =item @SelectedSections
1.59 matthew 187:
1.61 matthew 188: =item %StudentData
189:
190: =item @SelectedStudentData
191:
1.60 matthew 192: =item $curr_student
1.59 matthew 193:
1.60 matthew 194: =item $prev_student
1.59 matthew 195:
1.60 matthew 196: =item $next_student
1.59 matthew 197:
198: =back
199:
200: $curr_student, $prev_student, and $next_student may not be defined, depending
201: upon the calling context.
202:
203: =cut
204:
205: #######################################################
206: #######################################################
207: sub PrepareClasslist {
208: my $r = shift;
209: my %Sections;
210: &clear_classlist_variables();
211: #
212: # Retrieve the classlist
213: my $cid = $ENV{'request.course.id'};
214: my $cdom = $ENV{'course.'.$cid.'.domain'};
215: my $cnum = $ENV{'course.'.$cid.'.num'};
216: my ($classlist,$field_names) = &Apache::loncoursedata::get_classlist($cid,
217: $cdom,$cnum);
1.60 matthew 218: if (exists($ENV{'form.Section'})) {
1.59 matthew 219: if (ref($ENV{'form.Section'})) {
1.61 matthew 220: @SelectedSections = @{$ENV{'form.Section'}};
221: } elsif ($ENV{'form.Section'} !~ /^\s*$/) {
222: @SelectedSections = ($ENV{'form.Section'});
223: }
224: }
225: @SelectedSections = ('all') if (! @SelectedSections);
226: foreach (@SelectedSections) {
227: if ($_ eq 'all') {
228: @SelectedSections = ('all');
1.59 matthew 229: }
230: }
1.61 matthew 231: #
232: # Set up %StudentData
233: @StudentDataOrder = qw/fullname username domain id section status/;
234: foreach my $field (@StudentDataOrder) {
235: $StudentData{$field}->{'title'} = $field;
1.63 matthew 236: $StudentData{$field}->{'base_width'} = length($field);
1.61 matthew 237: $StudentData{$field}->{'width'} =
238: $StudentData{$field}->{'base_width'};
239: }
240:
1.59 matthew 241: #
242: # Process the classlist
243: while (my ($student,$student_data) = each (%$classlist)) {
244: my $studenthash = ();
245: for (my $i=0; $i< scalar(@$field_names);$i++) {
1.61 matthew 246: my $field = $field_names->[$i];
247: # Store the data
248: $studenthash->{$field}=$student_data->[$i];
249: # Keep track of the width of the fields
250: next if (! exists($StudentData{$field}));
1.63 matthew 251: my $length = length($student_data->[$i]);
1.61 matthew 252: if ($StudentData{$field}->{'width'} < $length) {
253: $StudentData{$field}->{'width'} = $length;
254: }
1.59 matthew 255: }
256: push (@FullClasslist,$studenthash);
257: #
258: # Build up a list of sections
259: my $section = $studenthash->{'section'};
1.60 matthew 260: if (! defined($section) || $section =~/^\s*$/ || $section == -1) {
261: $studenthash->{'section'} = 'none';
262: $section = $studenthash->{'section'};
263: }
1.59 matthew 264: $Sections{$section}++;
265: #
266: # Only put in the list those students we are interested in
1.60 matthew 267: foreach my $sect (@SelectedSections) {
1.61 matthew 268: if (($sect eq 'all') || ($section eq $sect)) {
1.60 matthew 269: push (@Students,$studenthash);
270: last;
271: }
1.59 matthew 272: }
273: }
274: #
275: # Put the consolidated section data in the right place
1.60 matthew 276: @Sections = sort {$a cmp $b} keys(%Sections);
1.61 matthew 277: unshift(@Sections,'all'); # Put 'all' at the front of the list
1.59 matthew 278: #
279: # Sort the Students
280: my $sortby = 'fullname';
1.60 matthew 281: $sortby = $ENV{'form.sort'} if (exists($ENV{'form.sort'}));
282: my @TmpStudents = sort { $a->{$sortby} cmp $b->{$sortby} ||
283: $a->{'fullname'} cmp $b->{'fullname'} } @Students;
284: @Students = @TmpStudents;
1.59 matthew 285: #
286: # Now deal with that current student thing....
287: if (exists($ENV{'form.StudentAssessmentStudent'})) {
288: my ($current_uname,$current_dom) =
289: split(':',$ENV{'form.StudentAssessmentStudent'});
290: my $i;
291: for ($i = 0; $i<=$#Students; $i++) {
292: next if (($Students[$i]->{'username'} ne $current_uname) ||
293: ($Students[$i]->{'domain'} ne $current_dom));
1.60 matthew 294: $curr_student = $Students[$i];
1.59 matthew 295: last; # If we get here, we have our student.
296: }
297: if ($i == 0) {
298: $prev_student = 'none';
299: } else {
300: $prev_student = $Students[$i-1];
301: }
302: if ($i == $#Students) {
303: $next_student = 'none';
304: } else {
305: $next_student = $Students[$i+1];
306: }
307: }
1.61 matthew 308: #
309: if (exists($ENV{'form.StudentData'})) {
310: if (ref($ENV{'form.StudentData'}) eq 'ARRAY') {
311: @SelectedStudentData = @{$ENV{'form.StudentData'}};
312: } else {
313: @SelectedStudentData = ($ENV{'form.StudentData'});
314: }
315: } else {
316: @SelectedStudentData = ('fullname');
317: }
318: foreach (@SelectedStudentData) {
319: if ($_ eq 'all') {
320: @SelectedStudentData = ('all');
321: last;
322: }
323: }
324: #
325: return;
326: }
327:
328: #######################################################
329: #######################################################
330:
331: =pod
332:
333: =item ¤t_student()
334:
335: Returns a pointer to a hash containing data about the currently
336: selected student.
337:
338: =cut
339:
340: #######################################################
341: #######################################################
342: sub current_student {
343: if (defined($curr_student)) {
344: return $curr_student;
345: } else {
346: return 'All Students';
347: }
348: }
349:
350: #######################################################
351: #######################################################
352:
353: =pod
354:
355: =item &previous_student()
356:
357: Returns a pointer to a hash containing data about the student prior
358: in the list of students. Or something.
359:
360: =cut
361:
362: #######################################################
363: #######################################################
364: sub previous_student {
365: if (defined($prev_student)) {
366: return $prev_student;
367: } else {
368: return 'No Student Selected';
369: }
1.59 matthew 370: }
371:
372: #######################################################
373: #######################################################
1.61 matthew 374:
375: =pod
376:
377: =item &next_student()
378:
379: Returns a pointer to a hash containing data about the next student
380: to be viewed.
381:
382: =cut
383:
384: #######################################################
385: #######################################################
386: sub next_student {
387: if (defined($next_student)) {
388: return $next_student;
389: } else {
390: return 'No Student Selected';
391: }
392: }
1.60 matthew 393:
394: #######################################################
395: #######################################################
396:
397: =pod
398:
399: =item &clear_sequence_variables()
400:
401: =cut
402:
403: #######################################################
404: #######################################################
405: sub clear_sequence_variables {
406: undef($top_map);
407: undef(@Sequences);
408: undef(@Assessments);
409: }
410:
411: #######################################################
412: #######################################################
413:
414: =pod
415:
1.61 matthew 416: =item &SetSelectedMaps($elementname)
417:
418: Sets the @SelectedMaps array from $ENV{'form.'.$elementname};
419:
420: =cut
421:
422: #######################################################
423: #######################################################
424: sub SetSelectedMaps {
425: my $elementname = shift;
426: if (exists($ENV{'form.'.$elementname})) {
427: if (ref($ENV{'form.'.$elementname})) {
428: @SelectedMaps = @{$ENV{'form.'.$elementname}};
429: } else {
430: @SelectedMaps = ($ENV{'form.'.$elementname});
431: }
432: } else {
433: @SelectedMaps = ('all');
434: }
1.64 matthew 435: }
436:
437:
438: #######################################################
439: #######################################################
440:
441: =pod
442:
443: =item &Sequences_with_Assess()
444:
445: Returns an array containing the subset of @Sequences which contain
446: assessments.
447:
448: =cut
449:
450: #######################################################
451: #######################################################
452: sub Sequences_with_Assess {
453: my @Sequences_to_Show;
454: foreach my $map_symb (@SelectedMaps) {
455: foreach my $sequence (@Sequences) {
456: next if ($sequence->{'symb'} ne $map_symb && $map_symb ne 'all');
457: next if ($sequence->{'num_assess'} < 1);
458: push (@Sequences_to_Show,$sequence);
459: }
460: }
461: return @Sequences_to_Show;
1.61 matthew 462: }
463:
464: #######################################################
465: #######################################################
466:
467: =pod
468:
1.60 matthew 469: =item &PrepareCourseData($r)
470:
471: =cut
472:
473: #######################################################
474: #######################################################
475: sub PrepareCourseData {
476: my ($r) = @_;
477: &clear_sequence_variables();
1.61 matthew 478: my ($top,$sequences,$assessments) =
479: &Apache::loncoursedata::get_sequence_assessment_data();
1.60 matthew 480: if (! defined($top) || ! ref($top)) {
481: # There has been an error, better report it
482: &Apache::lonnet::logthis('top is undefined');
483: return;
484: }
485: $top_map = $top if (ref($top));
486: @Sequences = @{$sequences} if (ref($sequences) eq 'ARRAY');
1.61 matthew 487: @Assessments = @{$assessments} if (ref($assessments) eq 'ARRAY');
488: #
489: # Compute column widths
490: foreach my $seq (@Sequences) {
1.63 matthew 491: my $name_length = length($seq->{'title'});
1.61 matthew 492: my $num_parts = $seq->{'num_assess_parts'};
493: #
494: # The number of columns needed for the summation text:
495: # " 1/5" = 1+3 columns, " 10/99" = 1+5 columns
1.63 matthew 496: my $sum_length = 1+1+2*(length($num_parts));
1.61 matthew 497: my $num_col = $num_parts+$sum_length;
498: if ($num_col < $name_length) {
499: $num_col = $name_length;
500: }
501: $seq->{'base_width'} = $name_length;
502: $seq->{'width'} = $num_col;
503: }
504: return;
505: }
506:
507: #######################################################
508: #######################################################
1.60 matthew 509:
510: =pod
511:
1.61 matthew 512: =item &log_sequence($sequence,$recursive,$padding)
513:
514: Write data about the sequence to a logfile. If $recursive is not
515: undef the data is written recursively. $padding is used for recursive
516: calls.
517:
518: =cut
519:
520: #######################################################
521: #######################################################
522: sub log_sequence {
523: my ($seq,$recursive,$padding) = @_;
524: $padding = '' if (! defined($padding));
525: if (ref($seq) ne 'HASH') {
526: &Apache::lonnet::logthis('log_sequence passed bad sequnce');
527: return;
528: }
529: &Apache::lonnet::logthis($padding.'sequence '.$seq->{'title'});
530: while (my($key,$value) = each(%$seq)) {
531: next if ($key eq 'contents');
532: if (ref($value) eq 'ARRAY') {
533: for (my $i=0;$i< scalar(@$value);$i++) {
534: &Apache::lonnet::logthis($padding.$key.'['.$i.']='.
535: $value->[$i]);
536: }
537: } else {
538: &Apache::lonnet::logthis($padding.$key.'='.$value);
539: }
540: }
541: if (defined($recursive)) {
542: &Apache::lonnet::logthis($padding.'-'x20);
543: &Apache::lonnet::logthis($padding.'contains:');
544: foreach my $item (@{$seq->{'contents'}}) {
545: if ($item->{'type'} eq 'container') {
546: &log_sequence($item,$recursive,$padding.' ');
547: } else {
548: &Apache::lonnet::logthis($padding.'title = '.$item->{'title'});
549: while (my($key,$value) = each(%$item)) {
550: next if ($key eq 'title');
551: if (ref($value) eq 'ARRAY') {
552: for (my $i=0;$i< scalar(@$value);$i++) {
553: &Apache::lonnet::logthis($padding.$key.'['.$i.']='.
554: $value->[$i]);
555: }
556: } else {
557: &Apache::lonnet::logthis($padding.$key.'='.$value);
558: }
559: }
560: }
1.60 matthew 561: }
1.61 matthew 562: &Apache::lonnet::logthis($padding.'end contents of '.$seq->{'title'});
563: &Apache::lonnet::logthis($padding.'-'x20);
1.60 matthew 564: }
1.61 matthew 565: return;
566: }
567:
568: ##############################################
569: ##############################################
570:
571: =pod
572:
573: =item &StudentDataSelect($elementname,$status,$numvisible,$selected)
574:
575: Returns html for a selection box allowing the user to choose one (or more)
576: of the fields of student data available (fullname, username, id, section, etc)
577:
578: =over 4
579:
580: =item $elementname The name of the HTML form element
581:
582: =item $status 'multiple' or 'single' selection box
583:
584: =item $numvisible The number of options to be visible
585:
586: =back
1.60 matthew 587:
588: =cut
589:
1.61 matthew 590: ##############################################
591: ##############################################
592: sub StudentDataSelect {
593: my ($elementname,$status,$numvisible)=@_;
594: if ($numvisible < 1) {
595: return;
596: }
597: #
598: # Build the form element
599: my $Str = "\n";
600: $Str .= '<select name="'.$elementname.'" ';
601: if ($status ne 'single') {
602: $Str .= 'multiple="true" ';
603: }
604: $Str .= 'size="'.$numvisible.'" >'."\n";
605: #
606: # Deal with 'all'
607: $Str .= ' <option value="all" ';
608: foreach (@SelectedStudentData) {
609: if ($_ eq 'all') {
610: $Str .= 'selected ';
611: last;
612: }
613: }
614: $Str .= ">all</option>\n";
615: #
616: # Loop through the student data fields
617: foreach my $item (@StudentDataOrder) {
618: $Str .= ' <option value="'.$item.'" ';
619: foreach (@SelectedStudentData) {
620: if ($item eq $_ ) {
621: $Str .= 'selected ';
622: last;
623: }
624: }
625: $Str .= '>'.$item."</option>\n";
626: }
627: $Str .= "</select>\n";
628: return $Str;
1.60 matthew 629: }
630:
631: ##############################################
632: ##############################################
633:
634: =pod
635:
1.61 matthew 636: =item &MapSelect($elementname,$status,$numvisible,$restriction)
1.60 matthew 637:
638: Returns html for a selection box allowing the user to choose one (or more)
639: of the sequences in the course. The values of the sequences are the symbs.
640: If the top sequence is selected, the value 'top' will result.
641:
642: =over 4
643:
644: =item $elementname The name of the HTML form element
645:
646: =item $status 'multiple' or 'single' selection box
647:
648: =item $numvisible The number of options to be visible
649:
650: =item $restriction Code reference to subroutine which returns true or
651: false. The code must expect a reference to a sequence data structure.
652:
653: =back
654:
655: =cut
656:
657: ##############################################
658: ##############################################
659: sub MapSelect {
1.61 matthew 660: my ($elementname,$status,$numvisible,$restriction)=@_;
1.60 matthew 661: if ($numvisible < 1) {
662: return;
663: }
664: #
665: # Set up array of selected items
1.61 matthew 666: &SetSelectedMaps($elementname);
1.60 matthew 667: #
668: # Set up the restriction call
669: if (! defined($restriction)) {
670: $restriction = sub { 1; };
671: }
672: #
673: # Build the form element
674: my $Str = "\n";
675: $Str .= '<select name="'.$elementname.'" ';
676: if ($status ne 'single') {
677: $Str .= 'multiple="true" ';
678: }
679: $Str .= 'size="'.$numvisible.'" >'."\n";
680: #
1.61 matthew 681: # Deal with 'all'
682: foreach (@SelectedMaps) {
683: if ($_ eq 'all') {
684: @SelectedMaps = ('all');
685: last;
686: }
687: }
688: #
689: # Put in option for 'all'
690: $Str .= ' <option value="all" ';
691: foreach (@SelectedMaps) {
692: if ($_ eq 'all') {
693: $Str .= 'selected ';
694: last;
695: }
696: }
697: $Str .= ">all</option>\n";
698: #
1.60 matthew 699: # Loop through the sequences
1.61 matthew 700: foreach my $seq (@Sequences) {
701: next if (! $restriction->($seq));
702: $Str .= ' <option value="'.$seq->{'symb'}.'" ';
703: foreach (@SelectedMaps) {
704: if ($seq->{'symb'} eq $_) {
1.60 matthew 705: $Str .= 'selected ';
706: last;
707: }
708: }
1.61 matthew 709: $Str .= '>'.$seq->{'title'}."</option>\n";
1.60 matthew 710: }
711: $Str .= "</select>\n";
712: return $Str;
713: }
714:
715: ##############################################
716: ##############################################
717:
718: =pod
719:
720: =item &SectionSelect($elementname,$status,$numvisible)
721:
722: Returns html for a selection box allowing the user to choose one (or more)
723: of the sections in the course.
724:
725: =over 4
726:
727: =item $elementname The name of the HTML form element
728:
729: =item $status 'multiple' or 'single' selection box
730:
731: =item $numvisible The number of options to be visible
732:
733: =item $selected Array ref to the names of the already selected sections.
734: If undef, $ENV{'form.'.$elementname} is used.
735: If $ENV{'form.'.$elementname} is also empty, none will be selected.
736:
737: =item $restriction Code reference to subroutine which returns true or
738: false. The code must expect a reference to a sequence data structure.
739:
740: =back
741:
742: =cut
743:
744: ##############################################
745: ##############################################
746: sub SectionSelect {
747: my ($elementname,$status,$numvisible)=@_;
748: if ($numvisible < 1) {
749: return;
750: }
751: #
752: # Build the form element
753: my $Str = "\n";
754: $Str .= '<select name="'.$elementname.'" ';
755: if ($status ne 'single') {
756: $Str .= 'multiple="true" ';
757: }
758: $Str .= 'size="'.$numvisible.'" >'."\n";
759: #
760: # Loop through the sequences
761: foreach my $s (@Sections) {
762: $Str .= ' <option value="'.$s.'" ';
763: foreach (@SelectedSections) {
1.61 matthew 764: if ($s eq $_) {
1.60 matthew 765: $Str .= 'selected ';
766: last;
767: }
768: }
769: $Str .= '>'.$s."</option>\n";
770: }
771: $Str .= "</select>\n";
772: return $Str;
773: }
774:
1.61 matthew 775: ##################################################
776: ##################################################
1.60 matthew 777: sub DisplayClasslist {
778: my ($r)=@_;
779: #
780: my @Fields = ('fullname','username','domain','id','section');
781: #
782: my $Str='';
783: $Str .= '<table border="0"><tr><td bgcolor="#777777">'."\n";
784: $Str .= '<table border="0" cellpadding="3"><tr bgcolor="#e6ffff">'."\n";
785: foreach my $field (@Fields) {
1.65 ! matthew 786: $Str .= '<th><a href="/adm/statistics?reportSelected=classlist&sort='.$field.'">'.$field.
1.60 matthew 787: '</a></th>';
788: }
789: $Str .= '</tr>'."\n";
790: #
791: my $alternate = 0;
1.65 ! matthew 792: foreach my $student (@Students) { # @Students is a package variable
1.60 matthew 793: my $sname = $student->{'username'}.':'.$student->{'domain'};
794: if($alternate) {
795: $Str .= '<tr bgcolor="#ffffe6">';
796: } else {
797: $Str .= '<tr bgcolor="#ffffc6">';
798: }
799: $alternate = ($alternate + 1) % 2;
800: #
801: foreach my $field (@Fields) {
802: $Str .= '<td>';
803: if ($field eq 'fullname') {
804: $Str .= '<a href="/adm/statistics?reportSelected=';
1.65 ! matthew 805: $Str .= &Apache::lonnet::escape('student_assessment');
1.60 matthew 806: $Str .= '&StudentAssessmentStudent=';
1.61 matthew 807: $Str .= &Apache::lonnet::escape($sname).'">';
1.60 matthew 808: $Str .= $student->{$field}.' ';
809: $Str .= '</a>';
810: } else {
811: $Str .= $student->{$field};
812: }
813: $Str .= '</td>';
814: }
815: $Str .= "</tr>\n";
816: }
817: $Str .= '</table></td></tr></table>'."\n";
818: #
819: $r->print($Str);
820: $r->rflush();
821: #
822: return;
823: }
824:
1.65 ! matthew 825: ##############################################
! 826: ##############################################
1.33 stredwic 827: sub CreateMainMenu {
1.65 ! matthew 828: my ($status,$reports,$current)=@_;
! 829: #
1.33 stredwic 830: my $Str = '';
1.65 ! matthew 831: #
1.33 stredwic 832: $Str .= '<table border="0"><tbody><tr>'."\n";
1.63 matthew 833: $Str .= '<td></td>'."\n";
1.57 minaeibi 834: $Str .= '<td align="center"><b>Select a Report</b></td>'."\n";
835: $Str .= '<td align="center"><b>Student Status</b></td></tr>'."\n";
1.33 stredwic 836: $Str .= '<tr>'."\n";
1.65 ! matthew 837: #
1.33 stredwic 838: $Str .= '<td align="center"><input type="submit" name="Refresh" ';
1.63 matthew 839: $Str .= 'value="Update Display" /></td>'."\n";
1.65 ! matthew 840: #
1.33 stredwic 841: $Str .= '<td align="center">';
1.65 ! matthew 842: $Str .= '<select name="reportSelected" >'."\n";
1.33 stredwic 843: foreach (sort(keys(%$reports))) {
1.65 ! matthew 844: $Str .= '<option value="'.$_.'"';
! 845: if($current eq $_) {
! 846: $Str .= ' selected';
1.33 stredwic 847: }
848: $Str .= '>'.$reports->{$_}.'</option>'."\n";
849: }
850: $Str .= '</select></td>'."\n";
1.65 ! matthew 851: #
1.33 stredwic 852: $Str .= '<td align="center">';
853: $Str .= &Apache::lonhtmlcommon::StatusOptions($status, 'Statistics');
854: $Str .= '</td>'."\n";
1.65 ! matthew 855: #
1.33 stredwic 856: $Str .= '</tr></tbody></table>'."\n";
857: $Str .= '<hr>'."\n";
1.65 ! matthew 858: #
1.33 stredwic 859: return $Str;
860: }
861:
1.65 ! matthew 862: ##############################################
! 863: ##############################################
1.1 albertel 864: sub handler {
1.31 minaeibi 865: my $r=shift;
1.65 ! matthew 866: my $c = $r->connection();
! 867: #
! 868: # Check for overloading
1.51 www 869: my $loaderror=&Apache::lonnet::overloaderror($r);
870: if ($loaderror) { return $loaderror; }
871: $loaderror=
872: &Apache::lonnet::overloaderror($r,
873: $ENV{'course.'.$ENV{'request.course.id'}.'.home'});
874: if ($loaderror) { return $loaderror; }
1.65 ! matthew 875: #
! 876: # Check for access
1.27 stredwic 877: unless(&Apache::lonnet::allowed('vgr',$ENV{'request.course.id'})) {
878: $ENV{'user.error.msg'}=
879: $r->uri.":vgr:0:0:Cannot view grades for complete course";
1.55 minaeibi 880: return HTTP_NOT_ACCEPTABLE;
1.27 stredwic 881: }
1.65 ! matthew 882: #
1.27 stredwic 883: # Set document type for header only
884: if($r->header_only) {
885: if ($ENV{'browser.mathml'}) {
886: $r->content_type('text/xml');
887: } else {
888: $r->content_type('text/html');
889: }
890: &Apache::loncommon::no_cache($r);
891: $r->send_http_header;
892: return OK;
893: }
1.65 ! matthew 894: #
! 895: # Send the header
1.27 stredwic 896: $r->content_type('text/html');
897: $r->send_http_header;
1.65 ! matthew 898: #
! 899: # Extract form elements from query string
1.60 matthew 900: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.65 ! matthew 901: ['sort','reportSelected',
1.61 matthew 902: 'StudentAssessmentStudent']);
1.65 ! matthew 903: if (! exists($ENV{'form.reportSelected'})) {
! 904: $ENV{'form.reportSelected'} = 'student_assessment';
! 905: }
! 906: #
! 907: # Give the LON-CAPA page header
! 908: $r->print(&Apache::lonhtmlcommon::Title('Course Statistics and Charts'));
! 909: $r->rflush();
! 910: #
! 911: # Set up the statistics and chart environment
1.59 matthew 912: &PrepareClasslist($r);
1.60 matthew 913: &PrepareCourseData($r);
1.65 ! matthew 914: #
! 915: # Begin form output
! 916: $r->print('<form name="Statistics" ');
! 917: $r->print('method="post" action="/adm/statistics">');
! 918: #
! 919: # Print main menu
! 920: my %reports = ('classlist' => 'Class list',
! 921: 'problem_statistics' => 'Problem Statistics',
! 922: 'student_assessment' => 'Student Assessment',
! 923: 'percentage' => 'Correct-problems Plot',
! 924: 'option_response' => 'Option Response Analysis',
! 925: # 'activitylog' => 'Activity Log',
! 926: );
! 927: $r->print(&CreateMainMenu($ENV{'form.status'},
! 928: \%reports,$ENV{'form.reportSelected'}));
! 929: $r->rflush();
! 930: #
! 931: my $GoToPage = $ENV{'form.reportSelected'};
! 932: if($GoToPage eq 'activitylog') {
! 933: # &Apache::lonproblemstatistics::Activity();
! 934: } elsif($GoToPage eq 'problem_statistics') {
! 935: &Apache::lonproblemstatistics::BuildProblemStatisticsPage($r,$c);
! 936: } elsif($GoToPage eq 'option_response') {
! 937: # &Apache::lonproblemanalysis::BuildProblemAnalysisPage($r,$c);
! 938: } elsif($GoToPage eq 'student_assessment') {
! 939: &Apache::lonstudentassessment::BuildStudentAssessmentPage($r,$c);
! 940: } elsif($GoToPage eq 'DoDiffGraph' || $GoToPage eq 'PercentWrongGraph') {
! 941: # &Apache::lonproblemstatistics::BuildGraphicChart($r,$c);
! 942: } elsif($GoToPage eq 'classlist') {
! 943: &DisplayClasslist($r);
! 944: } elsif($GoToPage eq 'Correct-problems Plot') {
! 945: # &Apache::lonpercentage::BuildPercentageGraph($r,$c);
! 946: }
! 947: #
! 948: $r->print("</form>\n");
! 949: $r->print("</body>\n</html>\n");
! 950: $r->rflush();
! 951: #
1.27 stredwic 952: return OK;
1.1 albertel 953: }
1.65 ! matthew 954:
1.1 albertel 955: 1;
1.59 matthew 956:
1.65 ! matthew 957: #######################################################
! 958: #######################################################
! 959:
1.59 matthew 960: =pod
961:
962: =back
963:
964: =cut
1.65 ! matthew 965:
! 966: #######################################################
! 967: #######################################################
1.59 matthew 968:
1.1 albertel 969: __END__
1.31 minaeibi 970:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>