Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
/**
18
 * Library draw chart function.
19
 * @package mod_questionnaire
20
 * @copyright  2016 Mike Churchward (mike.churchward@poetgroup.org)
21
 * @author     Mike Churchward
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
 
25
/**
26
 * This is the function.
27
 * @param string $feedbacktype
28
 * @param array $labels
29
 * @param string $groupname
30
 * @param bool $allresponses
31
 * @param null|string $charttype
32
 * @param null|array $score
33
 * @param null|array $allscore
34
 * @param null|string $globallabel
35
 * @return string
36
 */
37
function draw_chart($feedbacktype, $labels, $groupname,
38
                    $allresponses, $charttype=null, $score=null, $allscore=null, $globallabel=null) {
39
    global $PAGE;
40
 
41
    $pageoutput = '';
42
 
43
    if ($allresponses) {
44
        $nbvalues = count($allscore);
45
    } else {
46
        $nbvalues = count($score);
47
    }
48
    $nblabels = count($labels);
49
    $charttitlefont = "Verdana";
50
    $charttitlesize = 10;
51
    $charttitlesize2 = 10;
52
    if ($PAGE->pagetype == 'mod-questionnaire-myreport') {
53
        $charttitle = get_string('yourresponse', 'questionnaire');
54
    } else {
55
        $charttitle = get_string('thisresponse', 'questionnaire');
56
    }
57
    $charttitle2 = $groupname;
58
 
59
    // Gradient colors if needed.
60
    // TODO make gradient colors customizable in the settings.
61
    $chartcolorsgradient = "['Gradient(white:blue)', 'Gradient(white:red)', 'Gradient(white:green)', 'Gradient(white:pink)',
62
            'Gradient(white:yellow)', 'Gradient(white:cyan)', 'Gradient(white:navy)',
63
            'Gradient(white:gray)', 'Gradient(white:black)']";
64
 
65
    // We do not have labels other than global in this feedback type.
66
    if ($feedbacktype == 'global') {
67
        $labels = array($globallabel);
68
    }
69
 
70
    switch ($charttype) {
71
 
72
        case 'bipolar':
73
            // Global feedback with only one score.
74
            if ($feedbacktype == 'global') {
75
                if ($score) {
76
                    if ($allresponses) {
77
                        $score = null;
78
                    } else {
79
                        $score2 = $score;
80
                        $score = array($score2[0]);
81
                        $oppositescore = array($score2[1]);
82
                    }
83
                }
84
 
85
                if ($allscore) {
86
                    $allscore2 = $allscore;
87
                    $allscore = array($allscore2[0]);
88
                    $alloppositescore = array($allscore2[1]);
89
                }
90
                $nblabels = 1.5;     // For a single horizontal bar with 1.5 height.
91
                $nbvalues = 1;       // Only one hbar.
92
            } else {
93
                if ($score) {
94
                    $oppositescore = array();
95
                    foreach ($score as $sc) {
96
                        $oppositescore[] = 100 - $sc;
97
                    }
98
                }
99
                if ($allscore) {
100
                    $alloppositescore = array();
101
                    foreach ($allscore as $sc) {
102
                        $alloppositescore[] = 100 - $sc;
103
                    }
104
                }
105
            }
106
            foreach ($labels as $key => $label) {
107
                $lb = explode("|", $label);
108
                // Just in case there is no pipe separator in label.
109
                if (count($lb) > 1) {
110
                    $left = $lb[0];
111
                    $right = $lb[1];
112
                    // Lib core_text and diff needed for non-ascii characters.
113
                    $lenleft = core_text::strlen($left);
114
                    $diffleft = strlen($left) - $lenleft;
115
                    $lenright = core_text::strlen($right);
116
                    $diffright = strlen($right) - $lenright;
117
                    if ($lenleft < $lenright) {
118
                        $padlength = $lenright + $diffleft;
119
                        $left = str_pad($left, $padlength, ' ', STR_PAD_LEFT);
120
                    }
121
                    if ($lenleft > $lenright) {
122
                        $padlength = $lenleft + $diffright;
123
                        $right = str_pad($right, $padlength, ' ', STR_PAD_RIGHT);
124
                    }
125
                    $labels[$key] = $left .' '.$right;
126
                }
127
            }
128
            // Find length of longest label.
129
            $maxlen = 0;
130
            foreach ($labels as $label) {
131
                $labellen = core_text::strlen($label);
132
                if ($labellen > $maxlen) {
133
                    $maxlen = $labellen;
134
                }
135
            }
136
 
137
            $labels = json_encode($labels, JSON_UNESCAPED_UNICODE);
138
            // JSON_UNESCAPED_UNICODE available since php 5.4, used to correctly treat French accents etc.
139
 
140
            // The bar colors :: use green for "positive" (left column) and pink for "negative" (right column).
141
            $chartcolors = array();
142
            $chartcolors2 = array();
143
            if ($score) {
144
 
145
                for ($i = 0; $i < $nbvalues; $i++) {
146
                    if ($score[$i] != 0) {
147
                        $chartcolors[] = 'lightgreen';
148
                    }
149
                }
150
                for ($i = $nbvalues; $i < $nbvalues * 2; $i++) {
151
                    $chartcolors[] = 'pink';
152
                }
153
            }
154
            if ($allscore) {
155
 
156
                for ($i = 0; $i < $nbvalues; $i++) {
157
                    if ($allscore[$i] != 0) {
158
                        $chartcolors2[] = 'lightgreen';
159
                    }
160
                }
161
                for ($i = $nbvalues; $i < $nbvalues * 2; $i++) {
162
                    $chartcolors2[] = 'pink';
163
                }
164
            }
165
 
166
            // Encode all arrays for javascript compatibility.
167
            $chartcolors = json_encode($chartcolors);
168
            if ($allscore) {
169
                $chartcolors2 = json_encode($chartcolors2);
170
            }
171
            if ($score) {
172
                $score = json_encode($score);
173
                $oppositescore = json_encode($oppositescore);
174
            }
175
 
176
            if ($allscore) {
177
                $allscore = json_encode($allscore);
178
                $alloppositescore = json_encode($alloppositescore);
179
            }
180
            $canvasheight = ($nblabels * 25) + 60;
181
            $canvaswidth = max(300, (100 + ($maxlen * 7)));
182
            if (!$allresponses) {
183
                $pageoutput .= '
184
                        <canvas id="cvs" width="'.$canvaswidth.'" height="'.$canvasheight.'">[No canvas support]</canvas>
185
                    ';
186
            }
187
            if ($allscore) {
188
                $pageoutput .= '
189
                        <canvas id="cvs2" width="'.$canvaswidth.'" height="'.$canvasheight.'">[No canvas support]</canvas>
190
                    ';
191
            }
192
            $pageoutput .= '
193
                    <script>
194
                        window.onload = function () {';
195
            if (!$allresponses) {
196
                $pageoutput .= '
197
                            var chart = new RGraph.Bipolar("cvs", '.$score.', '.$oppositescore.');
198
                            chart.Set("chart.title", "'.$charttitle.'");
199
                            chart.Set("chart.title.font", "'.$charttitlefont.'");
200
                            chart.Set("chart.title.size", "'.$charttitlesize.'");
201
                            chart.Set("chart.labels", '.$labels.');
202
                            chart.Set("chart.gutter.center", 0);
203
                            chart.Set("chart.gutter.left", 10);
204
                            chart.Set("chart.gutter.top", 40);
205
                            chart.Set("chart.gutter.bottom", 20);
206
                            chart.Set("chart.xmax", 100);
207
                            chart.Set("chart.text.size", 10);
208
                            chart.Set("chart.text.font", "Courier");
209
                            chart.Set("chart.colors", '.$chartcolors.');
210
                            chart.Set("chart.colors.sequential", true);
211
                            chart.Draw();';
212
            }
213
            if ($allscore) {
214
                $pageoutput .= '
215
                            var chart = new RGraph.Bipolar("cvs2", '.$allscore.', '.$alloppositescore.');
216
                            chart.Set("chart.title", "'.$charttitle2.'");
217
                            chart.Set("chart.title.font", "'.$charttitlefont.'");
218
                            chart.Set("chart.title.size", "'.$charttitlesize2.'");
219
                            chart.Set("chart.labels", '.$labels.');
220
                            chart.Set("chart.gutter.center", 0);
221
                            chart.Set("chart.gutter.left", 10);
222
                            chart.Set("chart.gutter.right", 15);
223
                            chart.Set("chart.gutter.top", 40);
224
                            chart.Set("chart.gutter.bottom", 20);
225
                            chart.Set("chart.xmax", 100);
226
                            chart.Set("chart.text.size", 10);
227
                            chart.Set("chart.text.font", "Courier");
228
                            chart.Set("chart.colors", '.$chartcolors2.');
229
                            chart.Set("chart.colors.sequential", true);
230
                            chart.Draw();
231
                        ';
232
            }
233
            $pageoutput .= '
234
                    }
235
                    </script>
236
                ';
237
            break;
238
 
239
        case 'hbar':
240
            // The bar colors.
241
            $chartcolors = array();
242
            $chartcolors = json_encode($chartcolors);
243
            $sequential = 'true';
244
            // Global feedback with only one score.
245
            if ($feedbacktype == 'global') {
246
                $lb = explode("|", $globallabel);
247
                // Just in case there is no pipe separator in label.
248
                if (count($lb) > 1) {
249
                    $labels = '';
250
                    $left = $lb[0];
251
                    $right = $lb[1];
252
                    $lenleft = core_text::strlen($left);
253
                    $lenright = core_text::strlen($right);
254
                    if ($lenleft < $lenright) {
255
                        $padlength = $lenright;
256
                        $left = str_pad($left, $padlength, ' ', STR_PAD_LEFT);
257
                    }
258
                    if ($lenleft > $lenright) {
259
                        $padlength = $lenleft;
260
                        $right = str_pad($right, $padlength, ' ', STR_PAD_RIGHT);
261
                    }
262
                    $labels[0] = $left;
263
                    $labels[1] = $right;
264
                }
265
 
266
            } else {
267
                if ($nblabels > $nbvalues) {
268
                    for ($i = 1; $i < $nblabels - 1; $i++) {
269
                        unset($labels[$i]);
270
                    }
271
                }
272
                $sequential = 'false';
273
            }
274
            $nblabels = count($labels) + 1;
275
            $score = json_encode($score);
276
            if ($allscore) {
277
                $allscore = json_encode($allscore);
278
            }
279
            // Find length of longest label.
280
            $maxlen = 0;
281
            foreach ($labels as $label) {
282
                $labellen = core_text::strlen($label);
283
                if ($labellen > $maxlen) {
284
                    $maxlen = $labellen;
285
                }
286
            }
287
            foreach ($labels as $value) {
288
                $output[] = '"'.$value.'"';
289
            }
290
            $labels = '[' . implode(',', $output) . ']';
291
            $canvasheight = ($nblabels * 20) + 60;
292
            $charttextfont = 'Courier';
293
            $gutterleft = ($maxlen * 8) + 5;
294
            $canvaswidth = 400 + $gutterleft;
295
            if (!$allresponses) {
296
                $pageoutput .= '
297
                    <canvas id="cvs" width="'.$canvaswidth.'" height="'.$canvasheight.'">[No canvas support]</canvas>
298
                    ';
299
            }
300
            if ($allscore) {
301
                $pageoutput .= '
302
                        <canvas id="cvs2" width="'.$canvaswidth.'" height="'.$canvasheight.'">[No canvas support]</canvas>
303
                    ';
304
            }
305
            $pageoutput .= '
306
                    <script>
307
                        window.onload = function () {';
308
            if (!$allresponses) {
309
                $pageoutput .= '
310
                            var chart = new RGraph.HBar("cvs", '.$score.');
311
                            chart.Set("chart.title", "'.$charttitle.'");
312
                            chart.Set("chart.title.font", "'.$charttitlefont.'");
313
                            chart.Set("chart.title.size", "'.$charttitlesize.'");
314
                            chart.Set("chart.title.x", 400);
315
                            chart.Set("gutter.left", "'.$gutterleft.'");
316
                            chart.Set("gutter.right", 2);
317
                            chart.Set("chart.text.font", "'.$charttextfont.'");
318
                            chart.Set("labels", '.$labels.');
319
                            chart.Set("chart.colors", '.$chartcolorsgradient.');
320
                            chart.Set("chart.colors.sequential", '.$sequential.');
321
                            chart.Set("xmax",100);
322
                            chart.Draw();
323
                            ';
324
            }
325
            if ($allscore) {
326
                $pageoutput .= '
327
                            var chart = new RGraph.HBar("cvs2", '.$allscore.');
328
                            chart.Set("chart.title", "'.$charttitle2.'");
329
                            chart.Set("chart.title.font", "'.$charttitlefont.'");
330
                            chart.Set("chart.title.size", "'.$charttitlesize.'");
331
                            chart.Set("chart.title.x", 400);
332
                            chart.Set("gutter.left", "'.$gutterleft.'");
333
                            chart.Set("gutter.right", 2);
334
                            chart.Set("chart.text.font", "'.$charttextfont.'");
335
                            chart.Set("labels", '.$labels.');
336
                            chart.Set("chart.colors", '.$chartcolorsgradient.');
337
                            chart.Set("chart.colors.sequential",  '.$sequential.');
338
                            chart.Set("xmax",100);
339
                            chart.Draw();
340
                            ';
341
            }
342
            $pageoutput .= '
343
                    }
344
                    </script>
345
                ';
346
            break;
347
 
348
        case 'radar':
349
            $score = json_encode($score);
350
            foreach ($labels as $key => $label) {
351
                if ($key != 0) {
352
                    $labels[$key] = wordwrap($label, 20, "\\r\\n");
353
                } else {
354
                    $labels[$key] = $label ."\\r\\n";
355
                }
356
            }
357
            foreach ($labels as $value) {
358
                $output[] = '"'.$value.'"';
359
            }
360
            $labels = '[' . implode(',', $output) . ']';
361
            if ($allscore) {
362
                $allscore = json_encode($allscore);
363
            }
364
            if (!$allresponses) {
365
                $pageoutput .= '
366
                        <canvas id="cvs" width="550" height="400">[No canvas support]</canvas>
367
                        ';
368
            }
369
            if ($allscore) {
370
                $pageoutput .= '
371
                    <canvas id="cvs2" width="550" height="400">[No canvas support]</canvas>
372
                    ';
373
            }
374
            $pageoutput .= '
375
                    <script>
376
                        window.onload = function () {';
377
            if (!$allresponses) {
378
                $pageoutput .= '
379
                            var chart = new RGraph.Radar("cvs", '.$score.');
380
                            chart.Set("chart.title", "'.$charttitle.'");
381
                            chart.Set("chart.labels", '.$labels.');
382
                            chart.Set("chart.labels.offset", 15);
383
                            chart.Set("chart.radius", 150);
384
                            chart.Set("chart.ymax", 100);
385
                            chart.Set("chart.labels.axes","n");
386
                            chart.Draw();
387
                            ';
388
            }
389
            if ($allscore) {
390
                $pageoutput .= '
391
                            var chart = new RGraph.Radar("cvs2", '.$allscore.');
392
                            chart.Set("chart.title", "'.$charttitle2.'");
393
                            chart.Set("chart.labels", '.$labels.');
394
                            chart.Set("chart.labels.offset", 15);
395
                            chart.Set("chart.radius", 150);
396
                            chart.Set("chart.ymax", 100);
397
                            chart.Set("chart.labels.axes","n");
398
                            chart.Draw();
399
                            ';
400
            }
401
            $pageoutput .= '
402
                            }
403
                            </script>
404
                    ';
405
            break;
406
 
407
        case 'rose':
408
            if ($score != 'null') {
409
                $score = json_encode($score);
410
            }
411
 
412
            foreach ($labels as $key => $label) {
413
                $labels[$key] = wordwrap($label, 8, "\\r\\n");
414
            }
415
            foreach ($labels as $value) {
416
                $output[] = '"'.$value.'"';
417
            }
418
            $labels = '[' . implode(',', $output) . ']';
419
 
420
            if ($allscore) {
421
                $allscore = json_encode($allscore);
422
            }
423
            $size = 400;
424
            if (!$allresponses) {
425
                $pageoutput .= '
426
                        <canvas id="cvs" width="'.$size.'" height="'.$size.'">[No canvas support]</canvas>
427
                    ';
428
            }
429
            if ($allscore) {
430
                $pageoutput .= '&nbsp;&nbsp;&nbsp;
431
                        <canvas id="cvs2" width="'.$size.'" height="'.$size.'">[No canvas support]</canvas>
432
                    ';
433
            }
434
            $pageoutput .= '
435
                    <script>
436
                        window.onload = function () {';
437
            if (!$allresponses) {
438
                $pageoutput .= '
439
                            var chart = new RGraph.Rose("cvs", '.$score.');
440
                            chart.Set("chart.title", "'.$charttitle.'");
441
                            chart.Set("chart.title.font", "'.$charttitlefont.'");
442
                            chart.Set("chart.title.size", "'.$charttitlesize.'");
443
                            chart.Set("chart.title.vpos", 0.2);
444
                            chart.Set("chart.labels", '.$labels.');
445
                            chart.Set("chart.labels.offset", 10);
446
                            chart.Set("chart.background.grid.spokes", '.$nblabels.');
447
                            chart.Set("chart.labels.axes","n");
448
                            chart.Set("chart.radius", 100);
449
                            chart.Set("chart.ymax", 100);
450
                            chart.Set("chart.background.axes", false);
451
                            chart.Set("chart.colors.sequential", true);
452
                            chart.Set("chart.colors", ["Gradient(white:red)","Gradient(white:green)","Gradient(white:blue)",
453
                            "Gradient(white:gray)","Gradient(white:purple)","Gradient(white:pink)",
454
                                            "Gradient(white:orange)","Gradient(white:black)"]);
455
                            chart.Draw();
456
                            ';
457
            }
458
            if ($allscore) {
459
                $pageoutput .= '
460
                            var chart = new RGraph.Rose("cvs2", '.$allscore.');
461
                            chart.Set("chart.title", "'.$charttitle2.'");
462
                            chart.Set("chart.title.font", "'.$charttitlefont.'");
463
                            chart.Set("chart.title.size", "'.$charttitlesize.'");
464
                            chart.Set("chart.title.vpos", 0.2);
465
                            chart.Set("chart.labels", '.$labels.');
466
                            chart.Set("chart.labels.offset", 10);
467
                            chart.Set("chart.background.grid.spokes", '.$nblabels.');
468
                            chart.Set("chart.labels.axes","n");
469
                            chart.Set("chart.radius", 100);
470
                            chart.Set("chart.ymax", 100);
471
                            chart.Set("chart.background.axes", false);
472
                            chart.Set("chart.colors.sequential", true);
473
                            chart.Set("chart.colors", ["Gradient(white:red)","Gradient(white:green)","Gradient(white:blue)",
474
                            "Gradient(white:gray)","Gradient(white:purple)","Gradient(white:pink)",
475
                                            "Gradient(white:orange)","Gradient(white:black)"]);
476
                            chart.Draw();
477
                            ';
478
            }
479
            $pageoutput .= '
480
                        }
481
                    </script>
482
                ';
483
            break;
484
 
485
        case 'vprogress':
486
            if (!$allresponses) {
487
                $score = $score[0];
488
            } else {
489
                $score = null;
490
            }
491
            $score = json_encode($score);
492
            if ($allscore) {
493
                $allscore = json_encode($allscore[0]);
494
            }
495
            // Check presence of pipe separator in label.
496
            $lb = explode("|", $globallabel);
497
            $maxlen = 0;
498
            if (count($lb) > 1) {
499
                $labels = array_reverse($lb);
500
                // Find length of longest label.
501
                $maxlen = 0;
502
                foreach ($labels as $label) {
503
                    $labellen = core_text::strlen($label);
504
                    if ($labellen > $maxlen) {
505
                        $maxlen = $labellen;
506
                    }
507
                }
508
                foreach ($labels as $value) {
509
                    $output[] = '"'.$value.'"';
510
                }
511
                $labels = '[' . implode(',', $output) . ']';
512
            } else {
513
                $labels = '';
514
            }
515
            $charttextfont = 'Courier';
516
            $gutterright = 150 + ($maxlen * 3);
517
            $canvaswidth = 250 + ($maxlen * 3);
518
 
519
            if (!$allresponses) {
520
                $pageoutput .= '
521
                        <canvas id="cvs" width="'.$canvaswidth.'" height="400">[No canvas support]</canvas>
522
                    ';
523
            }
524
            if ($allscore) {
525
                $pageoutput .= '
526
                        <canvas id="cvs2" width="250" height="400">[No canvas support]</canvas>
527
                    ';
528
            }
529
            $pageoutput .= '
530
                    <script>
531
                        window.onload = function () {';
532
 
533
            if (!$allresponses) {
534
                $pageoutput .= '
535
                        var chart = new RGraph.VProgress("cvs", '.$score.',100);
536
                        chart.Set("chart.gutter.top", 30);
537
                        chart.Set("chart.gutter.left", 50);
538
                        chart.Set("chart.gutter.right", "'.$gutterright.'");
539
                        chart.Set("scale.decimals", 0);
540
                        chart.Set("chart.text.font", "'.$charttextfont.'");
541
                        chart.Set("chart.title", "'.$charttitle.'");
542
                        chart.Set("chart.title.font", "'.$charttitlefont.'");
543
                        chart.Set("chart.title.size", "'.$charttitlesize.'");
544
                        ';
545
 
546
                if ($labels) {
547
                    $pageoutput .= '
548
                                chart.Set("chart.labels.specific", '.$labels.');
549
                                ';
550
                }
551
                $pageoutput .= '
552
                                chart.Draw();
553
                              ';
554
            }
555
            if ($allscore) {
556
                // Display participants graph.
557
                $pageoutput .= '
558
                            var chart = new RGraph.VProgress("cvs2", '.$allscore.',100);
559
                            chart.Set("chart.gutter.top", 30);
560
                            chart.Set("chart.gutter.left", 50);
561
                            chart.Set("chart.gutter.right", 150);
562
                            chart.Set("chart.title", "'.$charttitle2.'");
563
                            chart.Set("chart.text.font", "'.$charttextfont.'");
564
                            chart.Set("chart.title.font", "'.$charttitlefont.'");
565
                            chart.Set("chart.title.size", "'.$charttitlesize.'");
566
                            chart.Set("scale.decimals", 0);
567
                            chart.Draw();
568
                        ';
569
            }
570
            $pageoutput .= '
571
                        }
572
                    </script>
573
                ';
574
            break;
575
    }
576
 
577
    return $pageoutput;
578
}