".$ENV{'course.'.$ENV{'request.course.id'}.'.description'}.
+ $r->print("".$env{'course.'.$env{'request.course.id'}.'.description'}.
" ".localtime(time)."
");
-
#
- # Set up progress window for 'final table' display only
- if ($show eq 'final table') {
- my $studentcount = scalar(@Apache::lonstatistics::Students);
- %prog_state=&Apache::lonhtmlcommon::Create_PrgWin
- ($r,'Summary Table Status',
- 'Summary Table Compilation Progress', $studentcount);
+ if ($chosen_output->{'base'} !~ /^final table/) {
+ $r->print("".&mt($chosen_output->{'shortdesc'})."
");
}
my $Str = "\n";
# First, the @StudentData fields need to be listed
@@ -483,28 +696,133 @@ sub html_initialize {
my $width=$Apache::lonstatistics::StudentData{$field}->{'width'};
$Str .= $title.' 'x($width-$base).$padding;
}
- # Now the selected sequences need to be listed
- foreach my $sequence (&Apache::lonstatistics::Sequences_with_Assess()){
- my $title = $sequence->{'title'};
- my $base = $sequence->{'base_width'};
- my $width = $sequence->{'width'};
- $Str .= $title.' 'x($width-$base).$padding;
- }
- $Str .= "total (of shown problems)
\n";
- $Str .= "";
#
- # Check for suppression of output
- if ($show eq 'final table') {
- $Str = '';
+ # Compute the column widths and output the sequence titles
+ my $total_count;
+ #
+ # Compute sequence widths
+ my $starttime = Time::HiRes::time;
+ foreach my $seq (@sequences) {
+ my $symb = $seq->symb;
+ my $title = $seq->compTitle;
+ $width{$symb}->{'width_sum'} = 0;
+ # Compute width of sum
+ if ($chosen_output->{'sequence_sum'}) {
+ if ($chosen_output->{'every_problem'}) {
+ # Use 1 digit for a space
+ $width{$symb}->{'width_sum'} += 1;
+ }
+ $total_count += &count_parts($navmap,$seq);
+ # Use 3 digits for the sum
+ $width{$symb}->{'width_sum'} += 3;
+ }
+ # Compute width of maximum
+ if ($chosen_output->{'sequence_max'}) {
+ if ($width{$symb}->{'width_sum'}>0) {
+ # One digit for the '/'
+ $width{$symb}->{'width_sum'} +=1;
+ }
+ # Use 3 digits for the total
+ $width{$symb}->{'width_sum'}+=3;
+ }
+ #
+ if ($chosen_output->{'every_problem'}) {
+ # one problem per digit
+ $width{$symb}->{'width_parts'}= &count_parts($navmap,$seq);
+ $width{$symb}->{'width_problem'} += $width{$symb}->{'width_parts'};
+ } else {
+ $width{$symb}->{'width_problem'} = 0;
+ }
+ $width{$symb}->{'width_total'} = $width{$symb}->{'width_problem'} +
+ $width{$symb}->{'width_sum'};
+ if ($width{$symb}->{'width_total'} < length(&HTML::Entities::decode($title))) {
+ $width{$symb}->{'width_total'} = length(&HTML::Entities::decode($title));
+ }
+ #
+ # Output the sequence titles
+ $Str .= $title.(' 'x($width{$symb}->{'width_total'}-
+ length($title)
+ )).$padding;
}
+ $total_sum_width = length($total_count)+1;
+ $Str .= " total
\n";
+ $Str .= "";
$r->print($Str);
$r->rflush();
+
+ $r->print(<
+// get the left offset of a given widget as an absolute position
+function getLeftOffset (element) {
+ return collect(element, "offsetLeft");
+}
+
+// get the top offset of a given widget as an absolute position
+function getTopOffset (element) {
+ return collect(element, "offsetTop");
+}
+
+function collect(element, att) {
+ var val = 0;
+ while(element) {
+ val += element[att];
+ element = element.offsetParent;
+ }
+ return val;
+}
+
+var currentDiv;
+var currentElement;
+function popup_score(element, score) {
+ popdown_score();
+ var left = getLeftOffset(element);
+ var top = getTopOffset(element);
+ var div = document.createElement("div");
+ div.className = "LC_chrt_popup";
+ div.appendChild(document.createTextNode(score));
+ div.style.position = "absolute";
+ div.style.top = (top - 25) + "px";
+ div.style.left = (left - 10) + "px";
+ currentDiv = div;
+ document.body.insertBefore(div, document.body.childNodes[0]);
+ element.className = "LC_chrt_popup_up";
+ currentElement = element;
+}
+
+function popdown_score() {
+ if (currentDiv) {
+ document.body.removeChild(currentDiv);
+ }
+ if (currentElement) {
+ currentElement.className = 'LC_chrt_popup_exists';
+ }
+ currentDiv = undefined;
+}
+
+JS
+
+ #
+ # Let the user know what we are doing
+ my $studentcount = scalar(@Apache::lonstatistics::Students);
+ if ($env{'form.SelectedStudent'}) {
+ $studentcount = '1';
+ }
+ #
+ # Initialize progress window
+ %prog_state=&Apache::lonhtmlcommon::Create_PrgWin
+ ($r,'HTML Chart Status',
+ 'HTML Chart Progress', $studentcount,
+ 'inline',undef,'Statistics','stats_status');
+ #
+ &Apache::lonhtmlcommon::Update_PrgWin($r,\%prog_state,
+ 'Processing first student');
return;
}
sub html_outputstudent {
my ($r,$student) = @_;
my $Str = '';
+ return if (! defined($navmap));
#
if($count++ % 5 == 0 && $count > 0) {
$r->print("
");
@@ -513,6 +831,10 @@ sub html_outputstudent {
my @to_show = &get_student_fields_to_show();
foreach my $field (@to_show) {
my $title=$student->{$field};
+ # Deal with 'comments' - how I love special cases
+ if ($field eq 'comments') {
+ $title = ''.&mt('Comments').'';
+ }
my $base = length($title);
my $width=$Apache::lonstatistics::StudentData{$field}->{'width'};
$Str .= $title.' 'x($width-$base).$padding;
@@ -521,14 +843,21 @@ sub html_outputstudent {
my %StudentsData;
my @tmp = &Apache::loncoursedata::get_current_state
($student->{'username'},$student->{'domain'},undef,
- $ENV{'request.course.id'});
- if ((scalar @tmp > 0) && ($tmp[0] !~ /^error:/)) {
+ $env{'request.course.id'});
+ if ((scalar @tmp > 0) && ($tmp[0] !~ /^error:(.*)/)) {
%StudentsData = @tmp;
- }
- if (scalar(@tmp) < 1) {
+ } else {
+ my $error = $1;
+ if (scalar(@tmp) < 1) {
+ $Str .= ''
+ .&mt('No Course Data')
+ .''."\n";
+ } else {
+ $Str .= ''
+ .&mt('Error getting student data ([_1])',$error)
+ .''."\n";
+ }
$nodata_count++;
- return if ($show eq 'final table');
- $Str .= 'No Course Data'."\n";
$r->print($Str);
$r->rflush();
return;
@@ -537,181 +866,173 @@ sub html_outputstudent {
# By sequence build up the data
my $studentstats;
my $PerformanceStr = '';
- foreach my $seq (&Apache::lonstatistics::Sequences_with_Assess()) {
- my ($performance,$score,$seq_max) =
- &StudentPerformanceOnSequence($student,\%StudentsData,
- $seq,$show_links);
- my $ratio = $score.'/'.$seq_max;
- #
- if ($show eq 'totals') {
- $performance = ' 'x(length($seq_max)-length($score)).$ratio;
- $performance .= ' 'x($seq->{'width'}-length($performance));
- } elsif ($show eq 'scores') {
- $performance = $score;
- $performance .= ' 'x($seq->{'width'}-length($performance));
+ foreach my $seq (@sequences) {
+ my $symb = $seq->symb;
+ my ($performance,$performance_length,$score,$seq_max,$rawdata);
+ if ($chosen_output->{'tries'}) {
+ ($performance,$performance_length,$score,$seq_max,$rawdata) =
+ &student_tries_on_sequence($student,\%StudentsData,
+ $navmap,$seq,$show_links);
} else {
- # Pad with extra spaces
- $performance .= ' 'x($seq->{'width'}-$seq_max-
- length($ratio)
- ).$ratio;
+ ($performance,$performance_length,$score,$seq_max,$rawdata) =
+ &student_performance_on_sequence($student,\%StudentsData,
+ $navmap,$seq,$show_links,
+ $chosen_output->{ignore_weight});
+ }
+ my $ratio='';
+ if ($chosen_output->{'every_problem'} &&
+ $chosen_output->{'sequence_sum'}) {
+ $ratio .= ' ';
+ }
+ if ($chosen_output->{'sequence_sum'} && $score ne ' ') {
+ my $score .= sprintf("%3.0f",$score);
+ $ratio .= (' 'x(3-length($score))).$score;
+ } elsif($chosen_output->{'sequence_sum'}) {
+ $ratio .= ' 'x3;
+ }
+ if ($chosen_output->{'sequence_max'}) {
+ if ($chosen_output->{'sequence_sum'}) {
+ $ratio .= '/';
+ }
+ $ratio .= sprintf("%3.0f",$seq_max);
}
#
+ if (! $chosen_output->{'every_problem'}) {
+ $performance = '';
+ $performance_length=0;
+ }
+ $performance .= ' 'x($width{$symb}->{'width_total'} -
+ $performance_length -
+ $width{$symb}->{'width_sum'}).
+ $ratio;
+ #
$Str .= $performance.$padding;
#
- $studentstats->{$seq->{'symb'}}->{'score'}= $score;
- $studentstats->{$seq->{'symb'}}->{'max'} = $seq_max;
+ $studentstats->{$symb}->{'score'}= $score;
+ $studentstats->{$symb}->{'max'} = $seq_max;
}
#
# Total it up and store the statistics info.
- my ($score,$max) = (0,0);
+ my ($score,$max);
while (my ($symb,$seq_stats) = each (%{$studentstats})) {
$Statistics->{$symb}->{'score'} += $seq_stats->{'score'};
- $Statistics->{$symb}->{'max'} += $seq_stats->{'max'};
- $score += $seq_stats->{'score'};
+ if ($Statistics->{$symb}->{'max'} < $seq_stats->{'max'}) {
+ $Statistics->{$symb}->{'max'} = $seq_stats->{'max'};
+ }
+ if ($seq_stats->{'score'} ne ' ') {
+ $score += $seq_stats->{'score'};
+ $Statistics->{$symb}->{'num_students'}++;
+ }
$max += $seq_stats->{'max'};
}
- $Str .= ' '.' 'x(length($max)-length($score)).$score.'/'.$max;
- $Str .= " \n";
- #
- # Check for suppressed output and update the progress window if so...
- if ($show eq 'final table') {
- $Str = '';
- &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,
- 'last student');
+ if (! defined($score)) {
+ $score = ' ' x $total_sum_width;
+ } else {
+ $score = sprintf("%.0f",$score);
+ $score = (' 'x(3-length($score))).$score;
}
+ $Str .= ' '.' 'x($total_sum_width-length($score)).$score.' / '.$max;
+ $Str .= " \n";
#
$r->print($Str);
#
$r->rflush();
+ &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,'last student');
return;
}
sub html_finish {
my ($r) = @_;
+ return if (! defined($navmap));
#
# Check for suppressed output and close the progress window if so
- if ($show eq 'final table') {
- &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);
- } else {
- $r->print("
\n");
+ $r->print("\n");
+ if ($chosen_output->{'summary_table'}) {
+ if ($single_student_mode) {
+ $r->print(&SingleStudentTotal());
+ } else {
+ $r->print(&StudentAverageTotal());
+ }
}
- $r->print(&StudentAverageTotal());
$r->rflush();
+ &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);
+ &html_cleanup();
return;
}
sub StudentAverageTotal {
- my $Str = "Summary Tables
\n";
- my $num_students = scalar(@Apache::lonstatistics::Students);
- my $total_ave = 0;
- my $total_max = 0;
- $Str .= '
'.&mt('LON-CAPA is unable to produce your Excel spreadsheet because your selections will result in more than 255 columns. Excel allows only 255 columns in a spreadsheet.').'
'.$/.
+ '