Completed
Push — master ( 29ac34...d08799 )
by Carlos
05:13
created

AreaChart::getSql()   C

Complexity

Conditions 12
Paths 19

Size

Total Lines 45
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 31
c 1
b 0
f 0
dl 0
loc 45
rs 6.9666
cc 12
nc 19
nop 1

How to fix   Complexity   

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:

1
<?php
2
/**
3
 * This file is part of FacturaScripts
4
 * Copyright (C) 2019 Carlos Garcia Gomez <[email protected]>
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU Lesser General Public License as
8
 * published by the Free Software Foundation, either version 3 of the
9
 * License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
 * GNU Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public License
17
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18
 */
19
namespace FacturaScripts\Core\Lib\ReportChart;
20
21
use FacturaScripts\Core\Base\DataBase;
22
use FacturaScripts\Dinamic\Model\Report;
23
24
/**
25
 * Description of AreaChart
26
 *
27
 * @author Carlos Garcia Gomez <[email protected]>
28
 */
29
class AreaChart
30
{
31
32
    /**
33
     *
34
     * @var Report
35
     */
36
    protected $report;
37
38
    /**
39
     * 
40
     * @param Report $report
41
     */
42
    public function __construct($report)
43
    {
44
        $this->report = $report;
45
    }
46
47
    /**
48
     * 
49
     * @return array
50
     */
51
    public function getData(): array
52
    {
53
        $sources = $this->getDataSources();
54
        if (empty($sources)) {
55
            return [];
56
        }
57
58
        $labels = [];
59
60
        /// mix data of sources
61
        $mix = [];
62
        $num = 1;
63
        $countSources = count($sources);
64
        foreach ($sources as $source) {
65
            foreach ($source as $row) {
66
                $xcol = $row['xcol'];
67
                if (!isset($mix[$xcol])) {
68
                    $labels[] = $xcol;
69
70
                    $newItem = ['xcol' => $xcol];
71
                    for ($count = 1; $count <= $countSources; $count++) {
72
                        $newItem['ycol' . $count] = 0;
73
                    }
74
                    $mix[$xcol] = $newItem;
75
                }
76
77
                $mix[$xcol]['ycol' . $num] = $row['ycol'];
78
            }
79
            $num++;
80
        }
81
82
        sort($labels);
83
        ksort($mix);
84
85
        $datasets = [];
86
        foreach (array_keys($sources) as $pos => $label) {
87
            $num = 1 + $pos;
88
            $data = [];
89
            foreach ($mix as $row) {
90
                $data[] = $row['ycol' . $num];
91
            }
92
93
            $datasets[] = ['label' => $label, 'data' => $data];
94
        }
95
96
        return ['labels' => $labels, 'datasets' => $datasets];
97
    }
98
99
    /**
100
     * 
101
     * @return string
102
     */
103
    public function render(): string
104
    {
105
        $data = $this->getData();
106
        if (empty($data)) {
107
            return '';
108
        }
109
110
        $canvasId = 'chart' . mt_rand();
111
        $html = '<canvas id="' . $canvasId . '" height="60"/>'
112
            . "<script>var ctx = document.getElementById('" . $canvasId . "').getContext('2d');"
113
            . "var myChart = new Chart(ctx, {
114
    type: 'line',
115
    data: {
116
        labels: ['" . implode("','", $data['labels']) . "'],
117
        datasets: [" . $this->renderDatasets($data['datasets']) . "]
118
    },
119
    options: {}
120
});</script>";
121
122
        return $html;
123
    }
124
125
    /**
126
     * 
127
     * @return array
128
     */
129
    protected function getDataSources(): array
130
    {
131
        $dataBase = new DataBase();
132
        $sql = $this->getSql($this->report);
133
        if (empty($sql) || !$dataBase->tableExists($this->report->table)) {
134
            return [];
135
        }
136
137
        $sources = [];
138
        $sources[$this->report->name] = $dataBase->select($sql);
139
140
        $comparedReport = new Report();
141
        if (!empty($this->report->compared) && $comparedReport->loadFromCode($this->report->compared)) {
142
            $sources[$comparedReport->name] = $dataBase->select($this->getSql($comparedReport));
143
        }
144
145
        return $sources;
146
    }
147
148
    /**
149
     * 
150
     * @param Report $report
151
     *
152
     * @return string
153
     */
154
    protected function getSql($report): string
155
    {
156
        if (empty($report->table) || empty($report->xcolumn)) {
157
            return '';
158
        }
159
160
        $xcol = $report->xcolumn;
161
        switch ($report->xoperation) {
162
            case 'DAY':
163
                $xcol = "DATE_FORMAT(" . $report->xcolumn . ", '%Y-%m-%d')";
164
                break;
165
166
            case 'WEEK':
167
                $xcol = "DATE_FORMAT(" . $report->xcolumn . ", '%Y-%u')";
168
                break;
169
170
            case 'MONTH':
171
                $xcol = "DATE_FORMAT(" . $report->xcolumn . ", '%Y-%m')";
172
                break;
173
174
            case 'UNIXTIME_DAY':
175
                $xcol = "DATE_FORMAT(FROM_UNIXTIME(" . $report->xcolumn . "), '%Y-%m-%d')";
176
                break;
177
178
            case 'UNIXTIME_WEEK':
179
                $xcol = "DATE_FORMAT(FROM_UNIXTIME(" . $report->xcolumn . "), '%Y-%u')";
180
                break;
181
182
            case 'UNIXTIME_MONTH':
183
                $xcol = "DATE_FORMAT(FROM_UNIXTIME(" . $report->xcolumn . "), '%Y-%m')";
184
                break;
185
186
            case 'UNIXTIME_YEAR':
187
                $xcol = "DATE_FORMAT(FROM_UNIXTIME(" . $report->xcolumn . "), '%Y')";
188
                break;
189
190
            case 'YEAR':
191
                $xcol = "DATE_FORMAT(" . $report->xcolumn . ", '%Y')";
192
                break;
193
        }
194
195
        $ycol = empty($report->ycolumn) ? 'COUNT(*)' : 'SUM(' . $report->ycolumn . ')';
196
197
        return 'SELECT ' . $xcol . ' as xcol, ' . $ycol . ' as ycol'
198
            . ' FROM ' . $report->table . ' GROUP BY xcol ORDER BY xcol ASC;';
199
    }
200
201
    /**
202
     * 
203
     * @param array $datasets
204
     *
205
     * @return string
206
     */
207
    protected function renderDatasets($datasets): string
208
    {
209
        $colors = ['255, 99, 132', '54, 162, 235', '255, 206, 86'];
210
211
        $items = [];
212
        $num = 0;
213
        foreach ($datasets as $dataset) {
214
            $color = isset($colors[$num]) ? $colors[$num] : '255, 206, 86';
215
            $num++;
216
217
            $items[] = "{
218
            label: '" . $dataset['label'] . "',
219
            data: [" . implode(",", $dataset['data']) . "],
220
            backgroundColor: [
221
                'rgba(" . $color . ", 0.2)'
222
            ],
223
            borderColor: [
224
                'rgba(" . $color . ", 1)'
225
            ],
226
            borderWidth: 1
227
        }";
228
        }
229
230
        return implode(',', $items);
231
    }
232
}
233