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
 * Chart base.
19
 *
20
 * @package    core
21
 * @copyright  2016 Frédéric Massart - FMCorz.net
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
 
25
namespace core;
26
defined('MOODLE_INTERNAL') || die();
27
 
28
use coding_exception;
29
use JsonSerializable;
30
use renderable;
31
 
32
/**
33
 * Chart base class.
34
 *
35
 * @package    core
36
 * @copyright  2016 Frédéric Massart - FMCorz.net
37
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38
 */
39
class chart_base implements JsonSerializable, renderable {
40
 
41
    /** @var chart_series[] The series constituting this chart. */
42
    protected $series = [];
43
    /** @var string[] The labels for the X axis when categorised. */
44
    protected $labels = [];
45
    /** @var string The title of the chart. */
46
    protected $title = null;
47
    /** @var chart_axis[] The X axes. */
48
    protected $xaxes = [];
49
    /** @var chart_axis[] The Y axes. */
50
    protected $yaxes = [];
51
    /** @var array Options for the chart legend. */
52
    protected $legendoptions = [];
53
 
54
    /**
55
     * Constructor.
56
     *
57
     * Must not take any argument.
58
     *
59
     * Most of the time you do not want to extend this, rather extend the
60
     * method {@link self::set_defaults} to set the defaults on instantiation.
61
     */
62
    public function __construct() {
63
        $this->set_defaults();
64
    }
65
 
66
    /**
67
     * Add a series to the chart.
68
     *
69
     * @param chart_series $serie The serie.
70
     */
71
    public function add_series(chart_series $serie) {
72
        $this->series[] = $serie;
73
    }
74
 
75
    /**
76
     * Serialize the object.
77
     *
78
     * @return array
79
     */
80
    public function jsonSerialize(): array {
81
        global $CFG;
82
        return [
83
            'type' => $this->get_type(),
84
            'series' => $this->series,
85
            'labels' => $this->labels,
86
            'title' => $this->title,
87
            'axes' => [
88
                'x' => $this->xaxes,
89
                'y' => $this->yaxes,
90
            ],
91
            'legend_options' => !empty($this->legendoptions) ? $this->legendoptions : null,
92
            'config_colorset' => !empty($CFG->chart_colorset) ? $CFG->chart_colorset : null
93
        ];
94
    }
95
 
96
    /**
97
     * Get an axis.
98
     *
99
     * @param string $type Accepts values 'x' or 'y'.
100
     * @param int $index The index of this axis.
101
     * @param bool $createifnotexists Whether to create the axis if not found.
102
     * @return chart_axis
103
     */
104
    private function get_axis($type, $index, $createifnotexists) {
105
        $isx = $type === 'x';
106
        if ($isx) {
107
            $axis = isset($this->xaxes[$index]) ? $this->xaxes[$index] : null;
108
        } else {
109
            $axis = isset($this->yaxes[$index]) ? $this->yaxes[$index] : null;
110
        }
111
 
112
        if ($axis === null) {
113
            if (!$createifnotexists) {
114
                throw new coding_exception('Unknown axis.');
115
            }
116
 
117
            $axis = new chart_axis();
118
            if ($isx) {
119
                $this->set_xaxis($axis, $index);
120
            } else {
121
                $this->set_yaxis($axis, $index);
122
            }
123
        }
124
 
125
        return $axis;
126
    }
127
 
128
    /**
129
     * Get the labels of the X axis.
130
     *
131
     * @return string[]
132
     */
133
    public function get_labels() {
134
        return $this->labels;
135
    }
136
 
137
    /**
138
     * Get an array of options for the chart legend.
139
     *
140
     * @return array
141
     */
142
    public function get_legend_options() {
143
        return $this->legendoptions;
144
    }
145
 
146
    /**
147
     * Get the series.
148
     *
149
     * @return chart_series[]
150
     */
151
    public function get_series() {
152
        return $this->series;
153
    }
154
 
155
    /**
156
     * Get the title.
157
     *
158
     * @return string
159
     */
160
    public function get_title() {
161
        return $this->title;
162
    }
163
 
164
    /**
165
     * Get the chart type.
166
     *
167
     * @return string
168
     */
169
    public function get_type() {
170
        $classname = get_class($this);
171
        return substr($classname, strpos($classname, '_') + 1);
172
    }
173
 
174
    /**
175
     * Get the X axes.
176
     *
177
     * @return chart_axis[]
178
     */
179
    public function get_xaxes() {
180
        return $this->xaxes;
181
    }
182
 
183
    /**
184
     * Get an X axis.
185
     *
186
     * @param int $index The index of the axis.
187
     * @param bool $createifnotexists When true, create an instance of the axis if none exist at this index yet.
188
     * @return chart_axis
189
     */
190
    public function get_xaxis($index = 0, $createifnotexists = false) {
191
        return $this->get_axis('x', $index, $createifnotexists);
192
    }
193
 
194
    /**
195
     * Get the Y axes.
196
     *
197
     * @return chart_axis[]
198
     */
199
    public function get_yaxes() {
200
        return $this->yaxes;
201
    }
202
 
203
    /**
204
     * Get a Y axis.
205
     *
206
     * @param int $index The index of the axis.
207
     * @param bool $createifnotexists When true, create an instance of the axis if none exist at this index yet.
208
     * @return chart_axis
209
     */
210
    public function get_yaxis($index = 0, $createifnotexists = false) {
211
        return $this->get_axis('y', $index, $createifnotexists);
212
    }
213
 
214
    /**
215
     * Set the defaults for this chart type.
216
     *
217
     * Child classes can extend this to set default values on instantiation.
218
     *
219
     * In general the constructor could be used, but this method is here to
220
     * emphasize and self-document the default values set by the chart type.
221
     *
222
     * @return void
223
     */
224
    protected function set_defaults() {
225
    }
226
 
227
    /**
228
     * Set the chart labels.
229
     *
230
     * @param string[] $labels The labels.
231
     */
232
    public function set_labels(array $labels) {
233
        $this->labels = $labels;
234
    }
235
 
236
    /**
237
     * Set options for the chart legend.
238
     * See https://www.chartjs.org/docs/2.7.0/configuration/legend.html for options.
239
     *
240
     * Note: Setting onClick and onHover events is not directly supported through
241
     * this method. These config options must be set directly within Javascript
242
     * on the page.
243
     *
244
     * @param array $legendoptions Whether or not to display the chart's legend.
245
     */
246
    public function set_legend_options(array $legendoptions) {
247
        $this->legendoptions = $legendoptions;
248
    }
249
 
250
    /**
251
     * Set the title.
252
     *
253
     * @param string $title The title.
254
     */
255
    public function set_title($title) {
256
        $this->title = $title;
257
    }
258
 
259
    /**
260
     * Set an X axis.
261
     *
262
     * Note that this will override any predefined axis without warning.
263
     *
264
     * @param chart_axis $axis The axis.
265
     * @param int $index The index of the axis.
266
     */
267
    public function set_xaxis(chart_axis $axis, $index = 0) {
268
        $this->validate_axis('x', $axis, $index);
269
        return $this->xaxes[$index] = $axis;
270
    }
271
 
272
    /**
273
     * Set an Y axis.
274
     *
275
     * Note that this will override any predefined axis without warning.
276
     *
277
     * @param chart_axis $axis The axis.
278
     * @param int $index The index of the axis.
279
     */
280
    public function set_yaxis(chart_axis $axis, $index = 0) {
281
        $this->validate_axis('y', $axis, $index);
282
        return $this->yaxes[$index] = $axis;
283
    }
284
 
285
    /**
286
     * Validate an axis.
287
     *
288
     * We validate this from PHP because not doing it here could result in errors being
289
     * hard to trace down. For instance, if we were to add axis at keys without another
290
     * axis preceding, we would effectively contain the axes in an associative array
291
     * rather than a simple array, and that would have consequences on serialisation.
292
     *
293
     * @param string $xy Accepts x or y.
294
     * @param chart_axis $axis The axis to validate.
295
     * @param index $index The index of the axis.
296
     */
297
    protected function validate_axis($xy, chart_axis $axis, $index = 0) {
298
        if ($index > 0) {
299
            $axes = $xy == 'x' ? $this->xaxes : $this->yaxes;
300
            if (!isset($axes[$index - 1])) {
301
                throw new coding_exception('Missing ' . $xy . ' axis at index lower than ' . $index);
302
            }
303
        }
304
    }
305
 
306
}