| [ Index ] |
PHP Cross Reference of Moodle 310 |
[Summary view] [Print] [Text view]
1 // This file is part of Moodle - http://moodle.org/ 2 // 3 // Moodle is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU General Public License as published by 5 // the Free Software Foundation, either version 3 of the License, or 6 // (at your option) any later version. 7 // 8 // Moodle is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU General Public License for more details. 12 // 13 // You should have received a copy of the GNU General Public License 14 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 15 16 /** 17 * Chart base. 18 * 19 * @copyright 2016 Frédéric Massart - FMCorz.net 20 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 21 * @module core/chart_base 22 */ 23 define(['core/chart_series', 'core/chart_axis'], function(Series, Axis) { 24 25 /** 26 * Chart base. 27 * 28 * The constructor of a chart must never take any argument. 29 * 30 * {@link module:core/chart_base#_setDefault} to set the defaults on instantiation. 31 * 32 * @class 33 */ 34 function Base() { 35 this._series = []; 36 this._labels = []; 37 this._xaxes = []; 38 this._yaxes = []; 39 40 this._setDefaults(); 41 } 42 43 /** 44 * The series constituting this chart. 45 * 46 * @protected 47 * @type {module:core/chart_series[]} 48 */ 49 Base.prototype._series = null; 50 51 /** 52 * The labels of the X axis when categorised. 53 * 54 * @protected 55 * @type {String[]} 56 */ 57 Base.prototype._labels = null; 58 59 /** 60 * Options for chart legend display. 61 * 62 * @protected 63 * @type {Object} 64 */ 65 Base.prototype._legendOptions = null; 66 67 /** 68 * The title of the chart. 69 * 70 * @protected 71 * @type {String} 72 */ 73 Base.prototype._title = null; 74 75 /** 76 * The X axes. 77 * 78 * @protected 79 * @type {module:core/chart_axis[]} 80 */ 81 Base.prototype._xaxes = null; 82 83 /** 84 * The Y axes. 85 * 86 * @protected 87 * @type {module:core/chart_axis[]} 88 */ 89 Base.prototype._yaxes = null; 90 91 /** 92 * Colours to pick from when automatically assigning them. 93 * 94 * @const 95 * @type {String[]} 96 */ 97 Base.prototype.COLORSET = ['#f3c300', '#875692', '#f38400', '#a1caf1', '#be0032', '#c2b280', '#7f180d', '#008856', 98 '#e68fac', '#0067a5']; 99 100 /** 101 * Set of colours defined by setting $CFG->chart_colorset to be picked when automatically assigning them. 102 * 103 * @type {String[]} 104 * @protected 105 */ 106 Base.prototype._configColorSet = null; 107 108 /** 109 * The type of chart. 110 * 111 * @abstract 112 * @type {String} 113 * @const 114 */ 115 Base.prototype.TYPE = null; 116 117 /** 118 * Add a series to the chart. 119 * 120 * This will automatically assign a color to the series if it does not have one. 121 * 122 * @param {module:core/chart_series} series The series to add. 123 */ 124 Base.prototype.addSeries = function(series) { 125 this._validateSeries(series); 126 this._series.push(series); 127 128 // Give a default color from the set. 129 if (series.getColor() === null) { 130 var configColorSet = this.getConfigColorSet() || Base.prototype.COLORSET; 131 series.setColor(configColorSet[this._series.length % configColorSet.length]); 132 } 133 }; 134 135 /** 136 * Create a new instance of a chart from serialised data. 137 * 138 * the serialised attributes they offer and support. 139 * 140 * @static 141 * @method create 142 * @param {module:core/chart_base} Klass The class oject representing the type of chart to instantiate. 143 * @param {Object} data The data of the chart. 144 * @return {module:core/chart_base} 145 */ 146 Base.prototype.create = function(Klass, data) { 147 // TODO Not convinced about the usage of Klass here but I can't figure out a way 148 // to have a reference to the class in the sub classes, in PHP I'd do new self(). 149 var Chart = new Klass(); 150 Chart.setConfigColorSet(data.config_colorset); 151 Chart.setLabels(data.labels); 152 Chart.setTitle(data.title); 153 if (data.legend_options) { 154 Chart.setLegendOptions(data.legend_options); 155 } 156 data.series.forEach(function(seriesData) { 157 Chart.addSeries(Series.prototype.create(seriesData)); 158 }); 159 data.axes.x.forEach(function(axisData, i) { 160 Chart.setXAxis(Axis.prototype.create(axisData), i); 161 }); 162 data.axes.y.forEach(function(axisData, i) { 163 Chart.setYAxis(Axis.prototype.create(axisData), i); 164 }); 165 return Chart; 166 }; 167 168 /** 169 * Get an axis. 170 * 171 * @private 172 * @param {String} xy Accepts the values 'x' or 'y'. 173 * @param {Number} [index=0] The index of the axis of its type. 174 * @param {Bool} [createIfNotExists=false] When true, create an instance if it does not exist. 175 * @return {module:core/chart_axis} 176 */ 177 Base.prototype.__getAxis = function(xy, index, createIfNotExists) { 178 var axes = xy === 'x' ? this._xaxes : this._yaxes, 179 setAxis = (xy === 'x' ? this.setXAxis : this.setYAxis).bind(this), 180 axis; 181 182 index = typeof index === 'undefined' ? 0 : index; 183 createIfNotExists = typeof createIfNotExists === 'undefined' ? false : createIfNotExists; 184 axis = axes[index]; 185 186 if (typeof axis === 'undefined') { 187 if (!createIfNotExists) { 188 throw new Error('Unknown axis.'); 189 } 190 axis = new Axis(); 191 setAxis(axis, index); 192 } 193 194 return axis; 195 }; 196 197 /** 198 * Get colours defined by setting. 199 * 200 * @return {String[]} 201 */ 202 Base.prototype.getConfigColorSet = function() { 203 return this._configColorSet; 204 }; 205 206 /** 207 * Get the labels of the X axis. 208 * 209 * @return {String[]} 210 */ 211 Base.prototype.getLabels = function() { 212 return this._labels; 213 }; 214 215 /** 216 * Get whether to display the chart legend. 217 * 218 * @return {Bool} 219 */ 220 Base.prototype.getLegendOptions = function() { 221 return this._legendOptions; 222 }; 223 224 /** 225 * Get the series. 226 * 227 * @return {module:core/chart_series[]} 228 */ 229 Base.prototype.getSeries = function() { 230 return this._series; 231 }; 232 233 /** 234 * Get the title of the chart. 235 * 236 * @return {String} 237 */ 238 Base.prototype.getTitle = function() { 239 return this._title; 240 }; 241 242 /** 243 * Get the type of chart. 244 * 245 * @see module:core/chart_base#TYPE 246 * @return {String} 247 */ 248 Base.prototype.getType = function() { 249 if (!this.TYPE) { 250 throw new Error('The TYPE property has not been set.'); 251 } 252 return this.TYPE; 253 }; 254 255 /** 256 * Get the X axes. 257 * 258 * @return {module:core/chart_axis[]} 259 */ 260 Base.prototype.getXAxes = function() { 261 return this._xaxes; 262 }; 263 264 /** 265 * Get an X axis. 266 * 267 * @param {Number} [index=0] The index of the axis. 268 * @param {Bool} [createIfNotExists=false] Create the instance of it does not exist at index. 269 * @return {module:core/chart_axis} 270 */ 271 Base.prototype.getXAxis = function(index, createIfNotExists) { 272 return this.__getAxis('x', index, createIfNotExists); 273 }; 274 275 /** 276 * Get the Y axes. 277 * 278 * @return {module:core/chart_axis[]} 279 */ 280 Base.prototype.getYAxes = function() { 281 return this._yaxes; 282 }; 283 284 /** 285 * Get an Y axis. 286 * 287 * @param {Number} [index=0] The index of the axis. 288 * @param {Bool} [createIfNotExists=false] Create the instance of it does not exist at index. 289 * @return {module:core/chart_axis} 290 */ 291 Base.prototype.getYAxis = function(index, createIfNotExists) { 292 return this.__getAxis('y', index, createIfNotExists); 293 }; 294 295 /** 296 * Set colours defined by setting. 297 * 298 * @param {String[]} colorset An array of css colours. 299 * @protected 300 */ 301 Base.prototype.setConfigColorSet = function(colorset) { 302 this._configColorSet = colorset; 303 }; 304 305 /** 306 * Set the defaults for this chart type. 307 * 308 * Child classes can extend this to set defaults values on instantiation. 309 * 310 * emphasize and self-document the defaults values set by the chart type. 311 * 312 * @protected 313 */ 314 Base.prototype._setDefaults = function() { 315 // For the children to extend. 316 }; 317 318 /** 319 * Set the labels of the X axis. 320 * 321 * This requires for each series to contain strictly as many values as there 322 * are labels. 323 * 324 * @param {String[]} labels The labels. 325 */ 326 Base.prototype.setLabels = function(labels) { 327 if (labels.length && this._series.length && this._series[0].length != labels.length) { 328 throw new Error('Series must match label values.'); 329 } 330 this._labels = labels; 331 }; 332 333 /** 334 * Set options for chart legend display. 335 * 336 * @param {Object} legendOptions 337 */ 338 Base.prototype.setLegendOptions = function(legendOptions) { 339 if (typeof legendOptions !== 'object') { 340 throw new Error('Setting legend with non-object value:' + legendOptions); 341 } 342 this._legendOptions = legendOptions; 343 }; 344 345 /** 346 * Set the title of the chart. 347 * 348 * @param {String} title The title. 349 */ 350 Base.prototype.setTitle = function(title) { 351 this._title = title; 352 }; 353 354 /** 355 * Set an X axis. 356 * 357 * Note that this will override any predefined axis without warning. 358 * 359 * @param {module:core/chart_axis} axis The axis. 360 * @param {Number} [index=0] The index of the axis. 361 */ 362 Base.prototype.setXAxis = function(axis, index) { 363 index = typeof index === 'undefined' ? 0 : index; 364 this._validateAxis('x', axis, index); 365 this._xaxes[index] = axis; 366 }; 367 368 /** 369 * Set a Y axis. 370 * 371 * Note that this will override any predefined axis without warning. 372 * 373 * @param {module:core/chart_axis} axis The axis. 374 * @param {Number} [index=0] The index of the axis. 375 */ 376 Base.prototype.setYAxis = function(axis, index) { 377 index = typeof index === 'undefined' ? 0 : index; 378 this._validateAxis('y', axis, index); 379 this._yaxes[index] = axis; 380 }; 381 382 /** 383 * Validate an axis. 384 * 385 * @protected 386 * @param {String} xy X or Y axis. 387 * @param {module:core/chart_axis} axis The axis to validate. 388 * @param {Number} [index=0] The index of the axis. 389 */ 390 Base.prototype._validateAxis = function(xy, axis, index) { 391 index = typeof index === 'undefined' ? 0 : index; 392 if (index > 0) { 393 var axes = xy == 'x' ? this._xaxes : this._yaxes; 394 if (typeof axes[index - 1] === 'undefined') { 395 throw new Error('Missing ' + xy + ' axis at index lower than ' + index); 396 } 397 } 398 }; 399 400 /** 401 * Validate a series. 402 * 403 * @protected 404 * @param {module:core/chart_series} series The series to validate. 405 */ 406 Base.prototype._validateSeries = function(series) { 407 if (this._series.length && this._series[0].getCount() != series.getCount()) { 408 throw new Error('Series do not have an equal number of values.'); 409 410 } else if (this._labels.length && this._labels.length != series.getCount()) { 411 throw new Error('Series must match label values.'); 412 } 413 }; 414 415 return Base; 416 417 });
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Wed Jan 22 11:59:49 2025 | Cross-referenced by PHPXref 0.7.1 |