From ec882623f3c7e0c31f5a9a52ec8f09237e1e849f Mon Sep 17 00:00:00 2001 From: Frederic Massart Date: Mon, 27 Jun 2016 15:13:53 +0800 Subject: [PATCH] MDL-55026 quiz_overview: Convert chart to the new library Part of MDL-54987 epic. --- mod/quiz/renderer.php | 11 ++ mod/quiz/report/overview/overviewgraph.php | 160 +++++-------------------- mod/quiz/report/overview/report.php | 87 ++++++++++++-- mod/quiz/report/overview/tests/report_test.php | 28 +++++ 4 files changed, 147 insertions(+), 139 deletions(-) rewrite mod/quiz/report/overview/overviewgraph.php (78%) diff --git a/mod/quiz/renderer.php b/mod/quiz/renderer.php index cddf86334ed..526f2f581f4 100644 --- a/mod/quiz/renderer.php +++ b/mod/quiz/renderer.php @@ -1234,6 +1234,17 @@ class mod_quiz_renderer extends plugin_renderer_base { } /** + * Outputs a chart. + * + * @param \core\chart_base $chart The chart. + * @param string $title The title to display above the graph. + * @return string HTML fragment for the graph. + */ + public function chart(\core\chart_base $chart, $title) { + return $this->heading($title, 3) . html_writer::tag('div', $this->render($chart), array('class' => 'graph')); + } + + /** * Output a graph, or a message saying that GD is required. * @param moodle_url $url the URL of the graph. * @param string $title the title to display above the graph. diff --git a/mod/quiz/report/overview/overviewgraph.php b/mod/quiz/report/overview/overviewgraph.php dissimilarity index 78% index 9202369c03c..3538464690d 100644 --- a/mod/quiz/report/overview/overviewgraph.php +++ b/mod/quiz/report/overview/overviewgraph.php @@ -1,129 +1,31 @@ -. - -/** - * This file renders the quiz overview graph. - * - * @package quiz_overview - * @copyright 2008 Jamie Pratt - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - - -require_once(__DIR__ . '/../../../../config.php'); -require_once($CFG->libdir . '/graphlib.php'); -require_once($CFG->dirroot . '/mod/quiz/locallib.php'); -require_once($CFG->dirroot . '/mod/quiz/report/reportlib.php'); - -$quizid = required_param('id', PARAM_INT); -$groupid = optional_param('groupid', 0, PARAM_INT); - -$quiz = $DB->get_record('quiz', array('id' => $quizid)); -$course = $DB->get_record('course', array('id' => $quiz->course)); -$cm = get_coursemodule_from_instance('quiz', $quizid); - -require_login($course, false, $cm); -$modcontext = context_module::instance($cm->id); -require_capability('mod/quiz:viewreports', $modcontext); - -if ($groupid && $groupmode = groups_get_activity_groupmode($cm)) { - // Groups are being used. - $groups = groups_get_activity_allowed_groups($cm); - if (!array_key_exists($groupid, $groups)) { - print_error('errorinvalidgroup', 'group', null, $groupid); - } - $group = $groups[$groupid]; - $groupusers = get_users_by_capability($modcontext, - array('mod/quiz:reviewmyattempts', 'mod/quiz:attempt'), - '', '', '', '', $group->id, '', false); - if (!$groupusers) { - print_error('nostudentsingroup'); - } - $groupusers = array_keys($groupusers); -} else { - $groupusers = array(); -} - -$line = new graph(800, 600); -$line->parameter['title'] = ''; -$line->parameter['y_label_left'] = get_string('participants'); -$line->parameter['x_label'] = get_string('grade'); -$line->parameter['y_label_angle'] = 90; -$line->parameter['x_label_angle'] = 0; -$line->parameter['x_axis_angle'] = 60; - -// The following two lines seem to silence notice warnings from graphlib.php. -$line->y_tick_labels = null; -$line->offset_relation = null; - -// We will make size > 1 to get an overlap effect when showing groups. -$line->parameter['bar_size'] = 1; -// Don't forget to increase spacing so that graph doesn't become one big block of colour. -$line->parameter['bar_spacing'] = 10; - -// Pick a sensible number of bands depending on quiz maximum grade. -$bands = $quiz->grade; -while ($bands > 20 || $bands <= 10) { - if ($bands > 50) { - $bands /= 5; - } else if ($bands > 20) { - $bands /= 2; - } - if ($bands < 4) { - $bands *= 5; - } else if ($bands <= 10) { - $bands *= 2; - } -} - -// See MDL-34589. Using doubles as array keys causes problems in PHP 5.4, -// hence the explicit cast to int. -$bands = (int) ceil($bands); -$bandwidth = $quiz->grade / $bands; -$bandlabels = array(); -for ($i = 1; $i <= $bands; $i++) { - $bandlabels[] = quiz_format_grade($quiz, ($i - 1) * $bandwidth) . ' - ' . - quiz_format_grade($quiz, $i * $bandwidth); -} -$line->x_data = $bandlabels; - -$line->y_format['allusers'] = array( - 'colour' => 'red', - 'bar' => 'fill', - 'shadow_offset' => 1, - 'legend' => get_string('allparticipants') -); -$line->y_data['allusers'] = quiz_report_grade_bands($bandwidth, $bands, $quizid, $groupusers); - -$line->y_order = array('allusers'); - -$ymax = max($line->y_data['allusers']); -$line->parameter['y_min_left'] = 0; -$line->parameter['y_max_left'] = $ymax; -$line->parameter['y_decimal_left'] = 0; - -// Pick a sensible number of gridlines depending on max value on graph. -$gridlines = $ymax; -while ($gridlines >= 10) { - if ($gridlines >= 50) { - $gridlines /= 5; - } else { - $gridlines /= 2; - } -} - -$line->parameter['y_axis_gridlines'] = $gridlines + 1; -$line->draw(); +. + +/** + * This file renders the quiz overview graph. + * + * @package quiz_overview + * @copyright 2008 Jamie Pratt + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @deprecated since Moodle 3.2 + */ + + +require_once(__DIR__ . '/../../../../config.php'); +require_once($CFG->libdir . '/filelib.php'); + +debugging('This way of generating the chart is deprecated, refer to quiz_overview_report::display().', DEBUG_DEVELOPER); +send_file_not_found(); diff --git a/mod/quiz/report/overview/report.php b/mod/quiz/report/overview/report.php index af8cacfa7da..f14a5d1ce78 100644 --- a/mod/quiz/report/overview/report.php +++ b/mod/quiz/report/overview/report.php @@ -232,24 +232,25 @@ class quiz_overview_report extends quiz_attempts_report { if (!$table->is_downloading() && $options->usercanseegrades) { $output = $PAGE->get_renderer('mod_quiz'); + list($bands, $bandwidth) = self::get_bands_count_and_width($quiz); + $labels = self::get_bands_labels($bands, $bandwidth, $quiz); + if ($currentgroup && $groupstudents) { list($usql, $params) = $DB->get_in_or_equal($groupstudents); $params[] = $quiz->id; - if ($DB->record_exists_select('quiz_grades', "userid $usql AND quiz = ?", - $params)) { - $imageurl = new moodle_url('/mod/quiz/report/overview/overviewgraph.php', - array('id' => $quiz->id, 'groupid' => $currentgroup)); - $graphname = get_string('overviewreportgraphgroup', 'quiz_overview', - groups_get_group_name($currentgroup)); - echo $output->graph($imageurl, $graphname); + if ($DB->record_exists_select('quiz_grades', "userid $usql AND quiz = ?", $params)) { + $data = quiz_report_grade_bands($bandwidth, $bands, $quiz->id, $groupstudents); + $chart = self::get_chart($labels, $data); + $graphname = get_string('overviewreportgraphgroup', 'quiz_overview', groups_get_group_name($currentgroup)); + echo $output->chart($chart, $graphname); } } if ($DB->record_exists('quiz_grades', array('quiz'=> $quiz->id))) { - $imageurl = new moodle_url('/mod/quiz/report/overview/overviewgraph.php', - array('id' => $quiz->id)); + $data = quiz_report_grade_bands($bandwidth, $bands, $quiz->id, []); + $chart = self::get_chart($labels, $data); $graphname = get_string('overviewreportgraph', 'quiz_overview'); - echo $output->graph($imageurl, $graphname); + echo $output->chart($chart, $graphname); } } return true; @@ -566,4 +567,70 @@ class quiz_overview_report extends quiz_attempts_report { quiz_update_all_final_grades($quiz); quiz_update_grades($quiz); } + + /** + * Get the bands configuration for the quiz. + * + * This returns the configuration for having between 11 and 20 bars in + * a chart based on the maximum grade to be given on a quiz. The width of + * a band is the number of grade points it encapsulates. + * + * @param object $quiz The quiz object. + * @return array Contains the number of bands, and their width. + */ + public static function get_bands_count_and_width($quiz) { + $bands = $quiz->grade; + while ($bands > 20 || $bands <= 10) { + if ($bands > 50) { + $bands /= 5; + } else if ($bands > 20) { + $bands /= 2; + } + if ($bands < 4) { + $bands *= 5; + } else if ($bands <= 10) { + $bands *= 2; + } + } + // See MDL-34589. Using doubles as array keys causes problems in PHP 5.4, hence the explicit cast to int. + $bands = (int) ceil($bands); + return [$bands, $quiz->grade / $bands]; + } + + /** + * Get the bands labels. + * + * @param int $bands The number of bands. + * @param int $bandwidth The band width. + * @param object $quiz The quiz object. + * @return string[] The labels. + */ + public static function get_bands_labels($bands, $bandwidth, $quiz) { + $bandlabels = []; + for ($i = 1; $i <= $bands; $i++) { + $bandlabels[] = quiz_format_grade($quiz, ($i - 1) * $bandwidth) . ' - ' . quiz_format_grade($quiz, $i * $bandwidth); + } + return $bandlabels; + } + + /** + * Get a chart. + * + * @param string[] $labels Chart labels. + * @param int[] $data The data. + * @return \core\chart_base + */ + protected static function get_chart($labels, $data) { + $chart = new \core\chart_bar(); + $chart->set_labels($labels); + $chart->get_xaxis(0, true)->set_label(get_string('grade')); + + $yaxis = $chart->get_yaxis(0, true); + $yaxis->set_label(get_string('participants')); + $yaxis->set_stepsize(max(1, round(max($data) / 10))); + + $series = new \core\chart_series(get_string('participants'), $data); + $chart->add_series($series); + return $chart; + } } diff --git a/mod/quiz/report/overview/tests/report_test.php b/mod/quiz/report/overview/tests/report_test.php index 094faa6471b..f583b302d1b 100644 --- a/mod/quiz/report/overview/tests/report_test.php +++ b/mod/quiz/report/overview/tests/report_test.php @@ -126,4 +126,32 @@ class quiz_overview_report_testcase extends advanced_testcase { $this->assertArrayHasKey($student3->id . '#0', $table->rawdata); $this->assertEquals(0, $table->rawdata[$student3->id . '#0']->gradedattempt); } + + /** + * Bands provider. + * @return array + */ + public function get_bands_count_and_width_provider() { + return [ + [10, [20, .5]], + [20, [20, 1]], + [30, [15, 2]], + // TODO MDL-55068 Handle bands better when grade is 50. + // [50, [10, 5]], + [100, [20, 5]], + [200, [20, 10]], + ]; + } + + /** + * Test bands. + * @dataProvider get_bands_count_and_width_provider + */ + public function test_get_bands_count_and_width($grade, $expected) { + $this->resetAfterTest(true); + $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz'); + $quiz = $quizgenerator->create_instance(['course' => SITEID, 'grade' => $grade]); + $this->assertEquals($expected, quiz_overview_report::get_bands_count_and_width($quiz)); + } + } -- 2.11.4.GIT