AutorÃa | Ultima modificación | Ver Log |
<?php// This file is part of Moodle - http://moodle.org///// Moodle is free software: you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation, either version 3 of the License, or// (at your option) any later version.//// Moodle is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with Moodle. If not, see <http://www.gnu.org/licenses/>./*** Library draw chart function.* @package mod_questionnaire* @copyright 2016 Mike Churchward (mike.churchward@poetgroup.org)* @author Mike Churchward* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*//*** This is the function.* @param string $feedbacktype* @param array $labels* @param string $groupname* @param bool $allresponses* @param null|string $charttype* @param null|array $score* @param null|array $allscore* @param null|string $globallabel* @return string*/function draw_chart($feedbacktype, $labels, $groupname,$allresponses, $charttype=null, $score=null, $allscore=null, $globallabel=null) {global $PAGE;$pageoutput = '';if ($allresponses) {$nbvalues = count($allscore);} else {$nbvalues = count($score);}$nblabels = count($labels);$charttitlefont = "Verdana";$charttitlesize = 10;$charttitlesize2 = 10;if ($PAGE->pagetype == 'mod-questionnaire-myreport') {$charttitle = get_string('yourresponse', 'questionnaire');} else {$charttitle = get_string('thisresponse', 'questionnaire');}$charttitle2 = $groupname;// Gradient colors if needed.// TODO make gradient colors customizable in the settings.$chartcolorsgradient = "['Gradient(white:blue)', 'Gradient(white:red)', 'Gradient(white:green)', 'Gradient(white:pink)','Gradient(white:yellow)', 'Gradient(white:cyan)', 'Gradient(white:navy)','Gradient(white:gray)', 'Gradient(white:black)']";// We do not have labels other than global in this feedback type.if ($feedbacktype == 'global') {$labels = array($globallabel);}switch ($charttype) {case 'bipolar':// Global feedback with only one score.if ($feedbacktype == 'global') {if ($score) {if ($allresponses) {$score = null;} else {$score2 = $score;$score = array($score2[0]);$oppositescore = array($score2[1]);}}if ($allscore) {$allscore2 = $allscore;$allscore = array($allscore2[0]);$alloppositescore = array($allscore2[1]);}$nblabels = 1.5; // For a single horizontal bar with 1.5 height.$nbvalues = 1; // Only one hbar.} else {if ($score) {$oppositescore = array();foreach ($score as $sc) {$oppositescore[] = 100 - $sc;}}if ($allscore) {$alloppositescore = array();foreach ($allscore as $sc) {$alloppositescore[] = 100 - $sc;}}}foreach ($labels as $key => $label) {$lb = explode("|", $label);// Just in case there is no pipe separator in label.if (count($lb) > 1) {$left = $lb[0];$right = $lb[1];// Lib core_text and diff needed for non-ascii characters.$lenleft = core_text::strlen($left);$diffleft = strlen($left) - $lenleft;$lenright = core_text::strlen($right);$diffright = strlen($right) - $lenright;if ($lenleft < $lenright) {$padlength = $lenright + $diffleft;$left = str_pad($left, $padlength, ' ', STR_PAD_LEFT);}if ($lenleft > $lenright) {$padlength = $lenleft + $diffright;$right = str_pad($right, $padlength, ' ', STR_PAD_RIGHT);}$labels[$key] = $left .' '.$right;}}// Find length of longest label.$maxlen = 0;foreach ($labels as $label) {$labellen = core_text::strlen($label);if ($labellen > $maxlen) {$maxlen = $labellen;}}$labels = json_encode($labels, JSON_UNESCAPED_UNICODE);// JSON_UNESCAPED_UNICODE available since php 5.4, used to correctly treat French accents etc.// The bar colors :: use green for "positive" (left column) and pink for "negative" (right column).$chartcolors = array();$chartcolors2 = array();if ($score) {for ($i = 0; $i < $nbvalues; $i++) {if ($score[$i] != 0) {$chartcolors[] = 'lightgreen';}}for ($i = $nbvalues; $i < $nbvalues * 2; $i++) {$chartcolors[] = 'pink';}}if ($allscore) {for ($i = 0; $i < $nbvalues; $i++) {if ($allscore[$i] != 0) {$chartcolors2[] = 'lightgreen';}}for ($i = $nbvalues; $i < $nbvalues * 2; $i++) {$chartcolors2[] = 'pink';}}// Encode all arrays for javascript compatibility.$chartcolors = json_encode($chartcolors);if ($allscore) {$chartcolors2 = json_encode($chartcolors2);}if ($score) {$score = json_encode($score);$oppositescore = json_encode($oppositescore);}if ($allscore) {$allscore = json_encode($allscore);$alloppositescore = json_encode($alloppositescore);}$canvasheight = ($nblabels * 25) + 60;$canvaswidth = max(300, (100 + ($maxlen * 7)));if (!$allresponses) {$pageoutput .= '<canvas id="cvs" width="'.$canvaswidth.'" height="'.$canvasheight.'">[No canvas support]</canvas>';}if ($allscore) {$pageoutput .= '<canvas id="cvs2" width="'.$canvaswidth.'" height="'.$canvasheight.'">[No canvas support]</canvas>';}$pageoutput .= '<script>window.onload = function () {';if (!$allresponses) {$pageoutput .= 'var chart = new RGraph.Bipolar("cvs", '.$score.', '.$oppositescore.');chart.Set("chart.title", "'.$charttitle.'");chart.Set("chart.title.font", "'.$charttitlefont.'");chart.Set("chart.title.size", "'.$charttitlesize.'");chart.Set("chart.labels", '.$labels.');chart.Set("chart.gutter.center", 0);chart.Set("chart.gutter.left", 10);chart.Set("chart.gutter.top", 40);chart.Set("chart.gutter.bottom", 20);chart.Set("chart.xmax", 100);chart.Set("chart.text.size", 10);chart.Set("chart.text.font", "Courier");chart.Set("chart.colors", '.$chartcolors.');chart.Set("chart.colors.sequential", true);chart.Draw();';}if ($allscore) {$pageoutput .= 'var chart = new RGraph.Bipolar("cvs2", '.$allscore.', '.$alloppositescore.');chart.Set("chart.title", "'.$charttitle2.'");chart.Set("chart.title.font", "'.$charttitlefont.'");chart.Set("chart.title.size", "'.$charttitlesize2.'");chart.Set("chart.labels", '.$labels.');chart.Set("chart.gutter.center", 0);chart.Set("chart.gutter.left", 10);chart.Set("chart.gutter.right", 15);chart.Set("chart.gutter.top", 40);chart.Set("chart.gutter.bottom", 20);chart.Set("chart.xmax", 100);chart.Set("chart.text.size", 10);chart.Set("chart.text.font", "Courier");chart.Set("chart.colors", '.$chartcolors2.');chart.Set("chart.colors.sequential", true);chart.Draw();';}$pageoutput .= '}</script>';break;case 'hbar':// The bar colors.$chartcolors = array();$chartcolors = json_encode($chartcolors);$sequential = 'true';// Global feedback with only one score.if ($feedbacktype == 'global') {$lb = explode("|", $globallabel);// Just in case there is no pipe separator in label.if (count($lb) > 1) {$labels = '';$left = $lb[0];$right = $lb[1];$lenleft = core_text::strlen($left);$lenright = core_text::strlen($right);if ($lenleft < $lenright) {$padlength = $lenright;$left = str_pad($left, $padlength, ' ', STR_PAD_LEFT);}if ($lenleft > $lenright) {$padlength = $lenleft;$right = str_pad($right, $padlength, ' ', STR_PAD_RIGHT);}$labels[0] = $left;$labels[1] = $right;}} else {if ($nblabels > $nbvalues) {for ($i = 1; $i < $nblabels - 1; $i++) {unset($labels[$i]);}}$sequential = 'false';}$nblabels = count($labels) + 1;$score = json_encode($score);if ($allscore) {$allscore = json_encode($allscore);}// Find length of longest label.$maxlen = 0;foreach ($labels as $label) {$labellen = core_text::strlen($label);if ($labellen > $maxlen) {$maxlen = $labellen;}}foreach ($labels as $value) {$output[] = '"'.$value.'"';}$labels = '[' . implode(',', $output) . ']';$canvasheight = ($nblabels * 20) + 60;$charttextfont = 'Courier';$gutterleft = ($maxlen * 8) + 5;$canvaswidth = 400 + $gutterleft;if (!$allresponses) {$pageoutput .= '<canvas id="cvs" width="'.$canvaswidth.'" height="'.$canvasheight.'">[No canvas support]</canvas>';}if ($allscore) {$pageoutput .= '<canvas id="cvs2" width="'.$canvaswidth.'" height="'.$canvasheight.'">[No canvas support]</canvas>';}$pageoutput .= '<script>window.onload = function () {';if (!$allresponses) {$pageoutput .= 'var chart = new RGraph.HBar("cvs", '.$score.');chart.Set("chart.title", "'.$charttitle.'");chart.Set("chart.title.font", "'.$charttitlefont.'");chart.Set("chart.title.size", "'.$charttitlesize.'");chart.Set("chart.title.x", 400);chart.Set("gutter.left", "'.$gutterleft.'");chart.Set("gutter.right", 2);chart.Set("chart.text.font", "'.$charttextfont.'");chart.Set("labels", '.$labels.');chart.Set("chart.colors", '.$chartcolorsgradient.');chart.Set("chart.colors.sequential", '.$sequential.');chart.Set("xmax",100);chart.Draw();';}if ($allscore) {$pageoutput .= 'var chart = new RGraph.HBar("cvs2", '.$allscore.');chart.Set("chart.title", "'.$charttitle2.'");chart.Set("chart.title.font", "'.$charttitlefont.'");chart.Set("chart.title.size", "'.$charttitlesize.'");chart.Set("chart.title.x", 400);chart.Set("gutter.left", "'.$gutterleft.'");chart.Set("gutter.right", 2);chart.Set("chart.text.font", "'.$charttextfont.'");chart.Set("labels", '.$labels.');chart.Set("chart.colors", '.$chartcolorsgradient.');chart.Set("chart.colors.sequential", '.$sequential.');chart.Set("xmax",100);chart.Draw();';}$pageoutput .= '}</script>';break;case 'radar':$score = json_encode($score);foreach ($labels as $key => $label) {if ($key != 0) {$labels[$key] = wordwrap($label, 20, "\\r\\n");} else {$labels[$key] = $label ."\\r\\n";}}foreach ($labels as $value) {$output[] = '"'.$value.'"';}$labels = '[' . implode(',', $output) . ']';if ($allscore) {$allscore = json_encode($allscore);}if (!$allresponses) {$pageoutput .= '<canvas id="cvs" width="550" height="400">[No canvas support]</canvas>';}if ($allscore) {$pageoutput .= '<canvas id="cvs2" width="550" height="400">[No canvas support]</canvas>';}$pageoutput .= '<script>window.onload = function () {';if (!$allresponses) {$pageoutput .= 'var chart = new RGraph.Radar("cvs", '.$score.');chart.Set("chart.title", "'.$charttitle.'");chart.Set("chart.labels", '.$labels.');chart.Set("chart.labels.offset", 15);chart.Set("chart.radius", 150);chart.Set("chart.ymax", 100);chart.Set("chart.labels.axes","n");chart.Draw();';}if ($allscore) {$pageoutput .= 'var chart = new RGraph.Radar("cvs2", '.$allscore.');chart.Set("chart.title", "'.$charttitle2.'");chart.Set("chart.labels", '.$labels.');chart.Set("chart.labels.offset", 15);chart.Set("chart.radius", 150);chart.Set("chart.ymax", 100);chart.Set("chart.labels.axes","n");chart.Draw();';}$pageoutput .= '}</script>';break;case 'rose':if ($score != 'null') {$score = json_encode($score);}foreach ($labels as $key => $label) {$labels[$key] = wordwrap($label, 8, "\\r\\n");}foreach ($labels as $value) {$output[] = '"'.$value.'"';}$labels = '[' . implode(',', $output) . ']';if ($allscore) {$allscore = json_encode($allscore);}$size = 400;if (!$allresponses) {$pageoutput .= '<canvas id="cvs" width="'.$size.'" height="'.$size.'">[No canvas support]</canvas>';}if ($allscore) {$pageoutput .= ' <canvas id="cvs2" width="'.$size.'" height="'.$size.'">[No canvas support]</canvas>';}$pageoutput .= '<script>window.onload = function () {';if (!$allresponses) {$pageoutput .= 'var chart = new RGraph.Rose("cvs", '.$score.');chart.Set("chart.title", "'.$charttitle.'");chart.Set("chart.title.font", "'.$charttitlefont.'");chart.Set("chart.title.size", "'.$charttitlesize.'");chart.Set("chart.title.vpos", 0.2);chart.Set("chart.labels", '.$labels.');chart.Set("chart.labels.offset", 10);chart.Set("chart.background.grid.spokes", '.$nblabels.');chart.Set("chart.labels.axes","n");chart.Set("chart.radius", 100);chart.Set("chart.ymax", 100);chart.Set("chart.background.axes", false);chart.Set("chart.colors.sequential", true);chart.Set("chart.colors", ["Gradient(white:red)","Gradient(white:green)","Gradient(white:blue)","Gradient(white:gray)","Gradient(white:purple)","Gradient(white:pink)","Gradient(white:orange)","Gradient(white:black)"]);chart.Draw();';}if ($allscore) {$pageoutput .= 'var chart = new RGraph.Rose("cvs2", '.$allscore.');chart.Set("chart.title", "'.$charttitle2.'");chart.Set("chart.title.font", "'.$charttitlefont.'");chart.Set("chart.title.size", "'.$charttitlesize.'");chart.Set("chart.title.vpos", 0.2);chart.Set("chart.labels", '.$labels.');chart.Set("chart.labels.offset", 10);chart.Set("chart.background.grid.spokes", '.$nblabels.');chart.Set("chart.labels.axes","n");chart.Set("chart.radius", 100);chart.Set("chart.ymax", 100);chart.Set("chart.background.axes", false);chart.Set("chart.colors.sequential", true);chart.Set("chart.colors", ["Gradient(white:red)","Gradient(white:green)","Gradient(white:blue)","Gradient(white:gray)","Gradient(white:purple)","Gradient(white:pink)","Gradient(white:orange)","Gradient(white:black)"]);chart.Draw();';}$pageoutput .= '}</script>';break;case 'vprogress':if (!$allresponses) {$score = $score[0];} else {$score = null;}$score = json_encode($score);if ($allscore) {$allscore = json_encode($allscore[0]);}// Check presence of pipe separator in label.$lb = explode("|", $globallabel);$maxlen = 0;if (count($lb) > 1) {$labels = array_reverse($lb);// Find length of longest label.$maxlen = 0;foreach ($labels as $label) {$labellen = core_text::strlen($label);if ($labellen > $maxlen) {$maxlen = $labellen;}}foreach ($labels as $value) {$output[] = '"'.$value.'"';}$labels = '[' . implode(',', $output) . ']';} else {$labels = '';}$charttextfont = 'Courier';$gutterright = 150 + ($maxlen * 3);$canvaswidth = 250 + ($maxlen * 3);if (!$allresponses) {$pageoutput .= '<canvas id="cvs" width="'.$canvaswidth.'" height="400">[No canvas support]</canvas>';}if ($allscore) {$pageoutput .= '<canvas id="cvs2" width="250" height="400">[No canvas support]</canvas>';}$pageoutput .= '<script>window.onload = function () {';if (!$allresponses) {$pageoutput .= 'var chart = new RGraph.VProgress("cvs", '.$score.',100);chart.Set("chart.gutter.top", 30);chart.Set("chart.gutter.left", 50);chart.Set("chart.gutter.right", "'.$gutterright.'");chart.Set("scale.decimals", 0);chart.Set("chart.text.font", "'.$charttextfont.'");chart.Set("chart.title", "'.$charttitle.'");chart.Set("chart.title.font", "'.$charttitlefont.'");chart.Set("chart.title.size", "'.$charttitlesize.'");';if ($labels) {$pageoutput .= 'chart.Set("chart.labels.specific", '.$labels.');';}$pageoutput .= 'chart.Draw();';}if ($allscore) {// Display participants graph.$pageoutput .= 'var chart = new RGraph.VProgress("cvs2", '.$allscore.',100);chart.Set("chart.gutter.top", 30);chart.Set("chart.gutter.left", 50);chart.Set("chart.gutter.right", 150);chart.Set("chart.title", "'.$charttitle2.'");chart.Set("chart.text.font", "'.$charttextfont.'");chart.Set("chart.title.font", "'.$charttitlefont.'");chart.Set("chart.title.size", "'.$charttitlesize.'");chart.Set("scale.decimals", 0);chart.Draw();';}$pageoutput .= '}</script>';break;}return $pageoutput;}