Completed
Push — master ( a75ecc...97ae17 )
by Adam
71:21 queued 52:34
created

AOR_Chart::getRGraphGroupedBarChart()   B

Complexity

Conditions 6
Paths 12

Size

Total Lines 56
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 0
Metric Value
c 3
b 1
f 0
dl 0
loc 56
rs 8.7592
cc 6
eloc 26
nc 12
nop 8

How to fix   Long Method    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/**
3
 * Advanced OpenReports, SugarCRM Reporting.
4
 * @package Advanced OpenReports for SugarCRM
5
 * @copyright SalesAgility Ltd http://www.salesagility.com
6
 *
7
 * This program is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
18
 * along with this program; if not, see http://www.gnu.org/licenses
19
 * or write to the Free Software Foundation,Inc., 51 Franklin Street,
20
 * Fifth Floor, Boston, MA 02110-1301  USA
21
 *
22
 * @author SalesAgility <[email protected]>
23
 */
24
25
class AOR_Chart extends Basic {
26
27
    var $colours = "['#1f78b4','#a6cee3','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a','#ffff99','#b15928','#144c73','#6caed1','#8acf4e','#20641c','#f8514f','#9e1214','#fc9d24','#b35900','#a880bb','#442763','#ffff4d','#733a1a']";
28
	var $new_schema = true;
29
	var $module_dir = 'AOR_Charts';
30
	var $object_name = 'AOR_Chart';
31
	var $table_name = 'aor_charts';
32
	var $importable = true;
33
	var $disable_row_level_security = true ;
34
	
35
	var $id;
36
	var $name;
37
	var $date_entered;
38
	var $date_modified;
39
	var $modified_user_id;
40
	var $modified_by_name;
41
	var $created_by;
42
	var $created_by_name;
43
	var $description;
44
	var $deleted;
45
	var $created_by_link;
46
	var $modified_user_link;
47
48
    var $type;
49
    var $x_field;
50
    var $y_field;
51
    var $noDataMessage = "No Results";
52
53
54
55
	function AOR_Chart(){
56
		parent::Basic();
57
	}
58
59
    function save_lines(array $post,AOR_Report $bean,$postKey){
60
        $seenIds = array();
61
        if(isset($post[$postKey.'id'])) {
62
            foreach ($post[$postKey . 'id'] as $key => $id) {
63
                if ($id) {
64
                    $aorChart = BeanFactory::getBean('AOR_Charts', $id);
65
                } else {
66
                    $aorChart = BeanFactory::newBean('AOR_Charts');
67
                }
68
                $aorChart->name = $post[$postKey . 'title'][$key];
69
                $aorChart->type = $post[$postKey . 'type'][$key];
70
                $aorChart->x_field = $post[$postKey . 'x_field'][$key];
71
                $aorChart->y_field = $post[$postKey . 'y_field'][$key];
72
                $aorChart->aor_report_id = $bean->id;
73
                $aorChart->save();
74
                $seenIds[] = $aorChart->id;
75
            }
76
        }
77
        //Any beans that exist but aren't in $seenIds must have been removed.
78
        foreach($bean->get_linked_beans('aor_charts','AOR_Charts') as $chart){
79
            if(!in_array($chart->id,$seenIds)){
80
                $chart->mark_deleted($chart->id);
81
            }
82
        }
83
    }
84
85
    private function getValidChartTypes(){
86
        return array('bar','line','pie','radar','rose', 'grouped_bar', 'stacked_bar');
87
    }
88
89
90
    private function getColour($seed,$rgbArray = false){
91
        $hash = md5($seed);
92
        $r = hexdec(substr($hash, 0, 2));
93
        $g = hexdec(substr($hash, 2, 2));
94
        $b = hexdec(substr($hash, 4, 2));
95
        if($rgbArray){
96
            return array('R'=>$r,'G'=>$g,'B'=>$b);
97
        }
98
        $highR = $r + 10;
99
        $highG = $g + 10;
100
        $highB = $b + 10;
101
        $main = '#'.str_pad(dechex($r),2,'0',STR_PAD_LEFT)
102
            .str_pad(dechex($g),2,'0',STR_PAD_LEFT)
103
            .str_pad(dechex($b),2,'0',STR_PAD_LEFT);
104
        $highlight = '#'.dechex($highR).dechex($highG).dechex($highB);
105
        return array('main'=>$main,'highlight'=>$highlight);
106
    }
107
108
    function buildChartImageBar($chartPicture,$recordImageMap = false){
109
        $scaleSettings = array("DrawSubTicks" => false, "LabelRotation" => 30, 'MinDivHeight' => 50);
110
        $chartPicture->drawScale($scaleSettings);
111
        $chartPicture->drawBarChart(array("RecordImageMap"=>$recordImageMap));
112
    }
113
114
    function buildChartImagePie($chartPicture,$chartData, $reportData,$imageHeight, $imageWidth, $xName,$recordImageMap){
115
        $PieChart = new pPie($chartPicture,$chartData);
116
        $x = 0;
117
        foreach($reportData as $row){
118
            $PieChart->setSliceColor($x,$this->getColour($row[$xName],true));
119
            $x++;
120
        }
121
        $PieChart->draw2DPie($imageWidth/3,$imageHeight/2,array("Border"=>TRUE,'Radius'=>200,''=>true,"RecordImageMap"=>$recordImageMap));
122
        $PieChart->drawPieLegend($imageWidth*0.7,$imageHeight/3, array('FontSize'=>10,"FontName"=>"modules/AOR_Charts/lib/pChart/fonts/verdana.ttf",'BoxSize'=>14));
123
    }
124
125
    function buildChartImageLine($chartPicture, $recordImageMap = false){
126
        $scaleSettings = array("XMargin"=>10,"YMargin"=>10,"GridR"=>200,"GridG"=>200,"GridB"=>200,'MinDivHeight' => 50,"LabelRotation" => 30);
127
        $chartPicture->drawScale($scaleSettings);
128
        $chartPicture->drawLineChart(array("RecordImageMap"=>$recordImageMap));
129
    }
130
131
    function buildChartImageRadar($chartPicture, $chartData,$recordImageMap){
132
        $SplitChart = new pRadar();
133
        $Options = array("LabelPos"=>RADAR_LABELS_HORIZONTAL,"RecordImageMap"=>$recordImageMap);
134
        $SplitChart->drawRadar($chartPicture,$chartData,$Options);
135
136
    }
137
138
    public function buildChartImage(array $reportData, array $fields,$asDataURI = true, $generateImageMapId = false){
139
        global $current_user;
140
        require_once 'modules/AOR_Charts/lib/pChart/pChart.php';
141
142
        if($generateImageMapId !== false){
143
            $generateImageMapId = $current_user->id."-".$generateImageMapId;
144
        }
145
146
        $html = '';
147
        if(!in_array($this->type, $this->getValidChartTypes())){
148
            return $html;
149
        }
150
        $x = $fields[$this->x_field];
151
        $y = $fields[$this->y_field];
152
        if(!$x || !$y){
153
            //Malformed chart object - missing an axis field
154
            return '';
155
        }
156
        $xName = str_replace(' ','_',$x->label) . $this->x_field;
157
        $yName = str_replace(' ','_',$y->label) . $this->y_field;
158
159
        $chartData = new pData();
160
        $chartData->loadPalette("modules/AOR_Charts/lib/pChart/palettes/navy.color", TRUE);
161
        $labels = array();
162
        foreach($reportData as $row){
163
            $chartData->addPoints($row[$yName],'data');
164
            $chartData->addPoints($row[$xName],'Labels');
165
            $labels[] = $row[$xName];
166
        }
167
168
        $chartData->setSerieDescription("Months","Month");
169
        $chartData->setAbscissa("Labels");
170
171
        $imageHeight = 700;
172
        $imageWidth = 700;
173
174
        $chartPicture = new pImage($imageWidth,$imageHeight,$chartData);
175
        if($generateImageMapId){
176
            $imageMapDir = create_cache_directory('modules/AOR_Charts/ImageMap/'.$current_user->id.'/');
177
            $chartPicture->initialiseImageMap($generateImageMapId,IMAGE_MAP_STORAGE_FILE,$generateImageMapId,$imageMapDir);
178
        }
179
180
        $chartPicture->Antialias = True;
181
182
        $chartPicture->drawFilledRectangle(0,0,$imageWidth-1,$imageHeight-1,array("R"=>240,"G"=>240,"B"=>240,"BorderR"=>0,"BorderG"=>0,"BorderB"=>0,));
183
184
        $chartPicture->setFontProperties(array("FontName"=>"modules/AOR_Charts/lib/pChart/fonts/verdana.ttf","FontSize"=>14));
185
186
        $chartPicture->drawText($imageWidth/2,20,$this->name,array("R"=>0,"G"=>0,"B"=>0,'Align'=>TEXT_ALIGN_TOPMIDDLE));
187
        $chartPicture->setFontProperties(array("FontName"=>"modules/AOR_Charts/lib/pChart/fonts/verdana.ttf","FontSize"=>6));
188
189
        $chartPicture->setGraphArea(60,60,$imageWidth-60,$imageHeight-100);
190
191
        switch($this->type){
192
            case 'radar':
193
                $this->buildChartImageRadar($chartPicture, $chartData, !empty($generateImageMapId));
194
                break;
195
            case 'pie':
196
                $this->buildChartImagePie($chartPicture,$chartData, $reportData,$imageHeight, $imageWidth, $xName, !empty($generateImageMapId));
197
                break;
198
            case 'line':
199
                $this->buildChartImageLine($chartPicture, !empty($generateImageMapId));
200
                break;
201
            case 'bar':
202
            default:
203
                $this->buildChartImageBar($chartPicture, !empty($generateImageMapId));
204
                break;
205
        }
206
        if($generateImageMapId) {
207
            $chartPicture->replaceImageMapTitle("data", $labels);
208
        }
209
        ob_start();
210
        $chartPicture->render('');
211
        $img = ob_get_clean();
212
        if($asDataURI){
213
            return 'data:image/png;base64,'.base64_encode($img);
214
        }else{
215
            return $img;
216
        }
217
    }
218
219
    public function buildChartHTML(array $reportData, array $fields,$index = 0, $chartType = AOR_Report::CHART_TYPE_PCHART, AOR_Field $mainGroupField = null){
220
        switch($chartType){
221
            case AOR_Report::CHART_TYPE_PCHART:
222
                return $this->buildChartHTMLPChart($reportData,$fields,$index);
223
            case AOR_Report::CHART_TYPE_CHARTJS:
224
                return $this->buildChartHTMLChartJS($reportData,$fields);
225
            case AOR_Report::CHART_TYPE_RGRAPH:
226
                return $this->buildChartHTMLRGraph($reportData,$fields, $mainGroupField);
227
        }
228
        return '';
229
    }
230
231
232
    private function buildChartHTMLRGraph(array $reportData, array $fields, AOR_Field $mainGroupField = null){
233
        $html = '';
234
        if(!in_array($this->type, $this->getValidChartTypes())){
235
            return $html;
236
        }
237
        $x = $fields[$this->x_field];
238
        $y = $fields[$this->y_field];
239
        if(!$x || !$y){
240
            //Malformed chart object - missing an axis field
241
            return '';
242
        }
243
        $xName = str_replace(' ','_',$x->label) . $this->x_field;
244
        $yName = str_replace(' ','_',$y->label) . $this->y_field;
245
246
        $defaultHeight = 500;
247
        $defaultWidth = 900;
248
249
        switch($this->type){
250
            /*
251
             //Polar was not implemented for the previous library (it is not in the getValidChartTypes method)
252
            case 'polar':
253
                $chartFunction = 'PolarArea';
254
                $data = $this->getPolarChartData($reportData, $xName,$yName);
255
                $config = $this->getPolarChartConfig();
256
                break;
257
            */
258
            case 'radar':
259
                $chartFunction = 'Radar';
260
                $data = $this->getRGraphBarChartData($reportData, $xName,$yName);
261
                $config = $this->getRadarChartConfig();
262
                $chart = $this->getRGraphRadarChart(json_encode($data['data']), json_encode($data['labels']),json_encode($data['tooltips']), $this->name, $this->id, $defaultHeight,$defaultWidth);
263
                break;
264
            case 'pie':
265
                $chartFunction = 'Pie';
266
                $data = $this->getRGraphBarChartData($reportData, $xName,$yName);
267
                $config = $this->getPieChartConfig();
268
                $chart = $this->getRGraphPieChart(json_encode($data['data']), json_encode($data['labels']),json_encode($data['tooltips']), $this->name, $this->id,  $defaultHeight,$defaultWidth);
269
                break;
270
            case 'line':
271
                $chartFunction = 'Line';
272
                $data = $this->getRGraphBarChartData($reportData, $xName,$yName);
273
                $config = $this->getLineChartConfig();
274
                $chart = $this->getRGraphLineChart(json_encode($data['data']), json_encode($data['labels']),json_encode($data['tooltips']), $this->name, $this->id,  $defaultHeight,$defaultWidth);
275
                break;
276
            case 'rose':
277
                $chartFunction = 'Rose';
278
                $data = $this->getRGraphBarChartData($reportData, $xName,$yName);
279
                $config = $this->getRoseChartConfig();
280
                $chart = $this->getRGraphRoseChart(json_encode($data['data']), json_encode($data['labels']),json_encode($data['tooltips']), $this->name, $this->id,  $defaultHeight,$defaultWidth);
281
                break;
282
            case 'grouped_bar':
283
                $chartFunction = 'Grouped bar';
284
                $data = $this->getRGraphGroupedBarChartData($reportData, $xName,$yName, $mainGroupField);
285
                $config = $this->getGroupedBarChartConfig();
286
                $chart = $this->getRGraphGroupedBarChart(json_encode($data['data']), json_encode($data['labels']), json_encode($data['tooltips']), $this->name, $this->id,  $defaultHeight,$defaultWidth, true);
287
                break;
288
            case 'stacked_bar':
289
                $chartFunction = 'Stacked bar';
290
                $data = $this->getRGraphGroupedBarChartData($reportData, $xName,$yName, $mainGroupField);
291
                $config = $this->getStackedBarChartConfig();
292
                $chart = $this->getRGraphGroupedBarChart(json_encode($data['data']), json_encode($data['labels']), json_encode($data['tooltips']), $this->name, $this->id,  $defaultHeight,$defaultWidth, false);
293
                break;
294
            case 'bar':
295
            default:
296
                $chartFunction = 'Bar';
297
                $data = $this->getRGraphBarChartData($reportData, $xName,$yName);
298
                $config = $this->getBarChartConfig();
299
                $chart = $this->getRGraphBarChart(json_encode($data['data']), json_encode($data['labels']), json_encode($data['tooltips']), $this->name, $this->id,  $defaultHeight,$defaultWidth);
300
                break;
301
        }
302
303
        return $chart;
304
    }
305
306
    private function getRGraphRoseChart($chartDataValues, $chartLabelValues,$chartTooltips, $chartName, $chartId, $chartHeight = 400, $chartWidth = 400)
307
    {
308
        $dataArray = json_decode($chartDataValues);
309
        if(!is_array($dataArray)||count($dataArray) < 1)
310
        {
311
            return "<h3>$this->noDataMessage</h3>";
312
        }
313
        $html = '';
314
        $html .= "<canvas id='$chartId' width='$chartWidth' height='$chartHeight' class='resizableCanvas'></canvas>";
315
        $html .= <<<EOF
316
        <script>
317
            new RGraph.Rose({
318
            id: '$chartId',
319
            options:{
320
                //title: '$chartName',
321
                //labels: $chartLabelValues,
322
                //textSize:8,
323
                textSize:10,
324
                //titleSize:10,
325
                 tooltips:$chartTooltips,
326
                tooltipsEvent:'onmousemove',
327
                tooltipsCssClass: 'rgraph_chart_tooltips_css',
328
                colors: $this->colours,
329
                colorsSequential:true
330
            },
331
            data: $chartDataValues
332
        }).draw();
333
        </script>
334
EOF;
335
        return $html;
336
    }
337
338
339
340
    //I have not used a parameter for getRGraphBarChart to say whether to group etc, as the future development could be quite different
341
    //for both, hence the separate methods.  However, the $grouped parameter allows us to specify whether the chart is grouped (true)
342
    //or stacked (false)
343
    private function getRGraphGroupedBarChart($chartDataValues, $chartLabelValues,$chartTooltips, $chartName, $chartId, $chartHeight = 400, $chartWidth = 400, $grouped = false)
344
    {
345
        //$keys = array_keys($chartTooltips);
346
347
348
        $i=0;
349
        foreach($chartDataValues as $rowKey => $row) {
350
            foreach($row as $key => $value) {
351
                $_tooltips[$rowKey][$key] = $chartTooltips[$i];
352
                $i++;
353
            }
354
        }
355
356
357
        $dataArray = json_decode($chartDataValues);
358
        $grouping = 'grouped'; //$mainGroupField->label; //'grouped';
359
        if(!$grouped)
360
            $grouping='stacked';
361
        if(!is_array($dataArray)||count($dataArray) < 1)
362
        {
363
            return "<h3>$this->noDataMessage</h3>";
364
        }
365
        $html = '';
366
        $html .= "<canvas id='$chartId' width='$chartWidth' height='$chartHeight' class='resizableCanvas'></canvas>";
367
        $html .= <<<EOF
368
        <script>
369
            new RGraph.Bar({
370
            id: '$chartId',
371
            data: $chartDataValues,
372
            options: {
373
                grouping:'$grouping',
374
                backgroundGrid:false,
375
                backgroundGrid:false,
376
                gutterBottom: 150,
377
                //gutterTop:40,
378
                //gutterLeft:30,
379
                title: '$chartName',
380
381
                tooltips:$chartTooltips,
382
                tooltipsEvent:'onmousemove',
383
                tooltipsCssClass: 'rgraph_chart_tooltips_css',
384
385
                gutterLeft:50,
386
                shadow:false,
387
                titleSize:10,
388
                labels: $chartLabelValues,
389
                textSize:10,
390
                textAngle: 90,
391
                colors: $this->colours,
392
                ymax:calculateMaxYForSmallNumbers($chartDataValues)
393
            }
394
        }).draw();
395
        </script>
396
EOF;
397
        return $html;
398
    }
399
400
401
402
    private function getRGraphBarChart($chartDataValues, $chartLabelValues,$chartTooltips, $chartName, $chartId, $chartHeight = 400, $chartWidth = 400)
403
    {
404
        $dataArray = json_decode($chartDataValues);
405
        if(!is_array($dataArray)||count($dataArray) < 1)
406
        {
407
            return "<h3>$this->noDataMessage</h3>";
408
        }
409
        $html = '';
410
        $html .= "<canvas id='$chartId' width='$chartWidth' height='$chartHeight' class='resizableCanvas'></canvas>";
411
        $html .= <<<EOF
412
        <script>
413
            new RGraph.Bar({
414
            id: '$chartId',
415
            data: $chartDataValues,
416
            options: {
417
            title: '$chartName',
418
                gutterBottom: 150,
419
                gutterLeft:50,
420
                //gutterTop:50,
421
                //title: '$chartName',
422
                labels: $chartLabelValues,
423
                colorsSequential:true,
424
                textAngle: 90,
425
                textSize:10,
426
                titleSize:10,
427
                backgroundGrid:false,
428
429
                tooltips:$chartTooltips,
430
                tooltipsCssClass: 'rgraph_chart_tooltips_css',
431
                tooltipsEvent:'onmousemove',
432
433
                colors: $this->colours,
434
                ymax:calculateMaxYForSmallNumbers($chartDataValues)
435
            }
436
        }).draw();
437
        </script>
438
EOF;
439
        return $html;
440
    }
441
442
    private function getRGraphRadarChart($chartDataValues, $chartLabelValues,$chartTooltips, $chartName, $chartId, $chartHeight = 400, $chartWidth = 400)
443
    {
444
        $dataArray = json_decode($chartDataValues);
445
        if(!is_array($dataArray)||count($dataArray) < 1)
446
        {
447
            return "<h3>$this->noDataMessage</h3>";
448
        }
449
        $html = '';
450
        $html .= "<canvas id='$chartId' width='$chartWidth' height='$chartHeight' class='resizableCanvas'></canvas>";
451
        $html .= <<<EOF
452
        <script>
453
            new RGraph.Radar({
454
            id: '$chartId',
455
            data: $chartDataValues,
456
            options: {
457
                title: '$chartName',
458
                labels: $chartLabelValues,
459
                textSize:10,
460
461
462
                tooltips:$chartTooltips,
463
                tooltipsEvent:'onmousemove',
464
                tooltipsCssClass: 'rgraph_chart_tooltips_css',
465
466
                colors: $this->colours,
467
                ymax:calculateMaxYForSmallNumbers($chartDataValues)
468
            }
469
        }).draw();
470
        </script>
471
EOF;
472
        return $html;
473
    }
474
475
    private function getRGraphPieChart($chartDataValues, $chartLabelValues,$chartTooltips, $chartName, $chartId, $chartHeight = 400, $chartWidth = 400)
476
    {
477
        $dataArray = json_decode($chartDataValues);
478
        if(!is_array($dataArray)||count($dataArray) < 1)
479
        {
480
            return "<h3>$this->noDataMessage</h3>";
481
        }
482
/*
483
        if($chartHeight > 400)
484
            $chartHeight = 400;
485
        if($chartWidth > 600)
486
            $chartWidth = 400;
487
*/
488
        $html = '';
489
        $html .= "<canvas id='$chartId' width='$chartWidth' height='$chartHeight' class='resizableCanvas'></canvas>";
490
        $html .= <<<EOF
491
        <script>
492
            new RGraph.Pie({
493
            id: '$chartId',
494
            data: $chartDataValues,
495
            options: {
496
                title: '$chartName',
497
                textSize:10,
498
                titleSize:10,
499
                 tooltips:$chartTooltips,
500
                tooltipsEvent:'onmousemove',
501
                tooltipsCssClass: 'rgraph_chart_tooltips_css',
502
                labels: $chartLabelValues,
503
                colors: $this->colours
504
            }
505
        }).draw();
506
        </script>
507
EOF;
508
        return $html;
509
    }
510
511
    private function getRGraphLineChart($chartDataValues, $chartLabelValues,$chartTooltips, $chartName, $chartId, $chartHeight = 400, $chartWidth = 400)
512
    {
513
        $dataArray = json_decode($chartDataValues);
514
        if(!is_array($dataArray)||count($dataArray) < 1)
515
        {
516
            return "<h3>$this->noDataMessage</h3>";
517
        }
518
        $html = '';
519
        $html .= "<canvas id='$chartId' width='$chartWidth' height='$chartHeight' class='resizableCanvas'></canvas>";
520
        $html .= <<<EOF
521
        <script>
522
            new RGraph.Line({
523
            id: '$chartId',
524
            data: $chartDataValues,
525
            options: {
526
                title: '$chartName',
527
                gutterBottom: 150,
528
                //gutterTop:50,
529
                tickmarks:'encircle',
530
                textSize:10,
531
                titleSize:10,
532
                gutterLeft:70,
533
                //title: '$chartName',
534
                labels: $chartLabelValues,
535
536
                 tooltips:$chartTooltips,
537
                tooltipsEvent:'onmousemove',
538
                tooltipsCssClass: 'rgraph_chart_tooltips_css',
539
540
                tickmarks:'circle',
541
542
                textAngle: 90,
543
                //titleSize:10,
544
                backgroundGrid:false,
545
                colors: $this->colours,
546
                ymax:calculateMaxYForSmallNumbers($chartDataValues),
547
            }
548
        }).draw();
549
        </script>
550
EOF;
551
        return $html;
552
    }
553
554
    private function buildChartHTMLChartJS(array $reportData, array $fields){
555
        $html = '';
556
        if(!in_array($this->type, $this->getValidChartTypes())){
557
            return $html;
558
        }
559
        $x = $fields[$this->x_field];
560
        $y = $fields[$this->y_field];
561
        if(!$x || !$y){
562
            //Malformed chart object - missing an axis field
563
            return '';
564
        }
565
        $xName = str_replace(' ','_',$x->label) . $this->x_field;
566
        $yName = str_replace(' ','_',$y->label) . $this->y_field;
567
568
        switch($this->type){
569
            case 'polar':
570
                $chartFunction = 'PolarArea';
571
                $data = $this->getPolarChartData($reportData, $xName,$yName);
572
                $config = $this->getPolarChartConfig();
573
                break;
574
            case 'radar':
575
                $chartFunction = 'Radar';
576
                $data = $this->getRadarChartData($reportData, $xName,$yName);
577
                $config = $this->getRadarChartConfig();
578
                break;
579
            case 'pie':
580
                $chartFunction = 'Pie';
581
                $data = $this->getPieChartData($reportData, $xName,$yName);
582
                $config = $this->getPieChartConfig();
583
                break;
584
            case 'line':
585
                $chartFunction = 'Line';
586
                $data = $this->getLineChartData($reportData, $xName,$yName);
587
                $config = $this->getLineChartConfig();
588
                break;
589
            case 'bar':
590
            default:
591
                $chartFunction = 'Bar';
592
                $data = $this->getBarChartData($reportData, $xName,$yName);
593
                $config = $this->getBarChartConfig();
594
                break;
595
        }
596
        $data = json_encode($data);
597
        $config = json_encode($config);
598
        $chartId = 'chart'.$this->id;
599
        $html .= "<h3>{$this->name}</h3>";
600
        $html .= "<canvas id='{$chartId}' width='400' height='400'></canvas>";
601
        $html .= <<<EOF
602
        <script>
603
        $(document).ready(function(){
604
            SUGAR.util.doWhen("typeof Chart != 'undefined'", function(){
605
                var data = {$data};
606
                var ctx = document.getElementById("{$chartId}").getContext("2d");
607
                console.log('Creating new chart');
608
                var config = {$config};
609
                var chart = new Chart(ctx).{$chartFunction}(data, config);
610
                var legend = chart.generateLegend();
611
                $('#{$chartId}').after(legend);
612
            });
613
        });
614
        </script>
615
EOF;
616
        return $html;
617
    }
618
619
    private function buildChartHTMLPChart(array $reportData, array $fields,$index = 0){
620
        $html = '';
621
        $imgUri = $this->buildChartImage($reportData,$fields,true,$index);
622
        $img = "<img id='{$this->id}_img' src='{$imgUri}'>";
623
        $html .= $img;
624
        $html .= <<<EOF
625
<script>
626
SUGAR.util.doWhen("typeof addImage != 'undefined'", function(){
627
    addImage('{$this->id}_img','{$this->id}_img_map','index.php?module=AOR_Charts&action=getImageMap&to_pdf=1&imageMapId={$index}');
628
});
629
</script>
630
EOF;
631
        return $html;
632
    }
633
634
    private function getShortenedLabel($label, $maxLabelSize = 20)
635
    {
636
        if(strlen($label) > $maxLabelSize)
637
        {
638
            return substr($label,0,$maxLabelSize).'...';
639
        }
640
        else
641
            return $label;
642
    }
643
644
645
    private function getRGraphGroupedBarChartData($reportData, $xName,$yName, AOR_Field $mainGroupField = null){
646
647
648
        // get z-axis name
649
650
        $zName = null;
651
        foreach($reportData[0] as $key => $value) {
652
            $field = str_replace(' ', '_', is_null($mainGroupField) ? 'no data' : $mainGroupField->label);
653
            if (preg_match('/^' . $field . '[0-9]+/', $key)) {
654
                $zName = $key;
655
                break;
656
            }
657
        }
658
659
660
661
        // get grouped values
662
663
        $data = array();
664
        $tooltips = array();
665
666
        $usedKeys = array();
667
        foreach($reportData as $key => $row) {
668
            $filter = $row[$xName];
669
            foreach($reportData as $key2 => $row2) {
670
                if($row2[$xName] == $filter && !in_array($key, $usedKeys)) {
671
                    $data      [ $row[$xName]  ]   [] = (float) $row[$yName];
672
                    $tooltips  [ $row[$xName]  ]   [] = $row[$zName];
673
                    $usedKeys[] = $key;
674
                }
675
            }
676
        }
677
678
        $_data = array();
679
        foreach($data as $label => $values) {
680
            foreach($values as $key => $value) {
681
                $_data[$label][$tooltips[$label][$key]] = $value;
682
            }
683
        }
684
        $data = $_data;
685
686
687
        // make data format for charts
688
689
        $_data = array();
690
        $_labels = array();
691
        $_tooltips = array();
692
        foreach($data as $label => $values) {
693
            $_labels[] = $this->getShortenedLabel($label);
694
            $_values = array();
695
            foreach($values as $tooltip => $value) {
696
                $_tooltips[] = $tooltip . " ($value)";
697
                $_values[] = $value;
698
            }
699
            $_data[] = $_values;
700
        }
701
702
703
        $chart = array(
704
            'data' => $_data,
705
            'labels' => $_labels,
706
            'tooltips' => $_tooltips,
707
        );
708
709
        return $chart;
710
711
712
    }
713
714
    private function getRGraphBarChartData($reportData, $xName,$yName){
715
        $chart['labels']=array();
716
        $chart['data']=array();
717
        $chart['tooltips']=array();
718
        foreach($reportData as $row){
719
            $chart['labels'][] = $this->getShortenedLabel($row[$xName]);
720
            $chart['tooltips'][] = $row[$xName];
721
            $chart['data'][] = (float)$row[$yName];
722
723
        }
724
        return $chart;
725
    }
726
727
728
    private function getBarChartData($reportData, $xName,$yName){
729
        $data = array();
730
        $data['labels'] = array();
731
        $datasetData = array();
732
        foreach($reportData as $row){
733
            $data['labels'][] = $row[$xName];
734
            $datasetData[] = $row[$yName];
735
        }
736
737
        $data['datasets'] = array();
738
        $data['datasets'][] = array(
739
            'fillColor' => "rgba(151,187,205,0.2)",
740
            'strokeColor' => "rgba(151,187,205,1)",
741
            'pointColor' => "rgba(151,187,205,1)",
742
            'pointStrokeColor' => "#fff",
743
            'pointHighlightFill' => "#fff",
744
            'pointHighlightStroke' => "rgba(151,187,205,1)4",
745
            'data'=>$datasetData);
746
        return $data;
747
    }
748
749
    private function getLineChartData($reportData, $xName,$yName){
750
        return $this->getBarChartData($reportData, $xName,$yName);
751
    }
752
753
    private function getBarChartConfig(){
754
        return array();
755
    }
756
    private function getLineChartConfig(){
757
        return $this->getBarChartConfig();
758
    }
759
760
    private function getGroupedBarChartConfig()
761
    {
762
        return $this->getBarChartConfig();
763
    }
764
765
    private function getStackedBarChartConfig()
766
    {
767
        return $this->getBarChartConfig();
768
    }
769
770
    private function getRoseChartConfig(){
771
        return $this->getBarChartConfig();
772
    }
773
774
    private function getRadarChartData($reportData, $xName,$yName){
775
        return $this->getBarChartData($reportData, $xName,$yName);
776
    }
777
778
    private function getPolarChartData($reportData, $xName,$yName){
779
        return $this->getPieChartData($reportData, $xName,$yName);
780
    }
781
782
    private function getRadarChartConfig(){
783
        return array();
784
    }
785
786
    private function getPolarChartConfig(){
787
        return $this->getPieChartConfig();
788
    }
789
    private function getPieChartConfig(){
790
        $config = array();
791
        $config['legendTemplate'] = "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\">&nbsp;&nbsp;&nbsp;&nbsp;</span>&nbsp;<%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>";
792
        return $config;
793
    }
794
795
    private function getPieChartData($reportData, $xName,$yName){
796
        $data = array();
797
798
        foreach($reportData as $row){
799
            if(!$row[$yName]){
800
                continue;
801
            }
802
            $colour = $this->getColour($row[$xName]);
803
            $data[] = array(
804
                'value' => (int)$row[$yName],
805
                'label' => $row[$xName],
806
                'color' => $colour['main'],
807
                'highlight' => $colour['highlight'],
808
            );
809
        }
810
        return $data;
811
    }
812
813
814
}
815