[ Index ] |
PHP Cross Reference of Unnamed Project |
[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 * @package core 20 * @copyright 2016 Frédéric Massart - FMCorz.net 21 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 22 * @module core/chart_base 23 */ 24 define(['core/chart_series', 'core/chart_axis'], function(Series, Axis) { 25 26 /** 27 * Chart base. 28 * 29 * The constructor of a chart must never take any argument. 30 * 31 * {@link module:core/chart_base#_setDefault} to set the defaults on instantiation. 32 * 33 * @alias module:core/chart_base 34 * @class 35 */ 36 function Base() { 37 this._series = []; 38 this._labels = []; 39 this._xaxes = []; 40 this._yaxes = []; 41 42 this._setDefaults(); 43 } 44 45 /** 46 * The series constituting this chart. 47 * 48 * @protected 49 * @type {module:core/chart_series[]} 50 */ 51 Base.prototype._series = null; 52 53 /** 54 * The labels of the X axis when categorised. 55 * 56 * @protected 57 * @type {String[]} 58 */ 59 Base.prototype._labels = null; 60 61 /** 62 * The title of the chart. 63 * 64 * @protected 65 * @type {String} 66 */ 67 Base.prototype._title = null; 68 69 /** 70 * The X axes. 71 * 72 * @protected 73 * @type {module:core/chart_axis[]} 74 */ 75 Base.prototype._xaxes = null; 76 77 /** 78 * The Y axes. 79 * 80 * @protected 81 * @type {module:core/chart_axis[]} 82 */ 83 Base.prototype._yaxes = null; 84 85 /** 86 * Colours to pick from when automatically assigning them. 87 * 88 * @const 89 * @type {String[]} 90 */ 91 Base.prototype.COLORSET = ['#f3c300', '#875692', '#f38400', '#a1caf1', '#be0032', '#c2b280', '#7f180d', '#008856', 92 '#e68fac', '#0067a5']; 93 94 /** 95 * The type of chart. 96 * 97 * @abstract 98 * @type {String} 99 * @const 100 */ 101 Base.prototype.TYPE = null; 102 103 /** 104 * Add a series to the chart. 105 * 106 * This will automatically assign a color to the series if it does not have one. 107 * 108 * @param {module:core/chart_series} series The series to add. 109 */ 110 Base.prototype.addSeries = function(series) { 111 this._validateSeries(series); 112 this._series.push(series); 113 114 // Give a default color from the set. 115 if (series.getColor() === null) { 116 series.setColor(Base.prototype.COLORSET[this._series.length % Base.prototype.COLORSET.length]); 117 } 118 }; 119 120 /** 121 * Create a new instance of a chart from serialised data. 122 * 123 * the serialised attributes they offer and support. 124 * 125 * @static 126 * @method create 127 * @param {module:core/chart_base} Klass The class oject representing the type of chart to instantiate. 128 * @param {Object} data The data of the chart. 129 * @return {module:core/chart_base} 130 */ 131 Base.prototype.create = function(Klass, data) { 132 // TODO Not convinced about the usage of Klass here but I can't figure out a way 133 // to have a reference to the class in the sub classes, in PHP I'd do new self(). 134 var Chart = new Klass(); 135 136 Chart.setLabels(data.labels); 137 Chart.setTitle(data.title); 138 data.series.forEach(function(seriesData) { 139 Chart.addSeries(Series.prototype.create(seriesData)); 140 }); 141 data.axes.x.forEach(function(axisData, i) { 142 Chart.setXAxis(Axis.prototype.create(axisData), i); 143 }); 144 data.axes.y.forEach(function(axisData, i) { 145 Chart.setYAxis(Axis.prototype.create(axisData), i); 146 }); 147 return Chart; 148 }; 149 150 /** 151 * Get an axis. 152 * 153 * @private 154 * @param {String} xy Accepts the values 'x' or 'y'. 155 * @param {Number} [index=0] The index of the axis of its type. 156 * @param {Bool} [createIfNotExists=false] When true, create an instance if it does not exist. 157 * @return {module:core/chart_axis} 158 */ 159 Base.prototype.__getAxis = function(xy, index, createIfNotExists) { 160 var axes = xy === 'x' ? this._xaxes : this._yaxes, 161 setAxis = (xy === 'x' ? this.setXAxis : this.setYAxis).bind(this), 162 axis; 163 164 index = typeof index === 'undefined' ? 0 : index; 165 createIfNotExists = typeof createIfNotExists === 'undefined' ? false : createIfNotExists; 166 axis = axes[index]; 167 168 if (typeof axis === 'undefined') { 169 if (!createIfNotExists) { 170 throw new Error('Unknown axis.'); 171 } 172 axis = new Axis(); 173 setAxis(axis, index); 174 } 175 176 return axis; 177 }; 178 179 /** 180 * Get the labels of the X axis. 181 * 182 * @return {String[]} 183 */ 184 Base.prototype.getLabels = function() { 185 return this._labels; 186 }; 187 188 /** 189 * Get the series. 190 * 191 * @return {module:core/chart_series[]} 192 */ 193 Base.prototype.getSeries = function() { 194 return this._series; 195 }; 196 197 /** 198 * Get the title of the chart. 199 * 200 * @return {String} 201 */ 202 Base.prototype.getTitle = function() { 203 return this._title; 204 }; 205 206 /** 207 * Get the type of chart. 208 * 209 * @see module:core/chart_base#TYPE 210 * @return {String} 211 */ 212 Base.prototype.getType = function() { 213 if (!this.TYPE) { 214 throw new Error('The TYPE property has not been set.'); 215 } 216 return this.TYPE; 217 }; 218 219 /** 220 * Get the X axes. 221 * 222 * @return {module:core/chart_axis[]} 223 */ 224 Base.prototype.getXAxes = function() { 225 return this._xaxes; 226 }; 227 228 /** 229 * Get an X axis. 230 * 231 * @param {Number} [index=0] The index of the axis. 232 * @param {Bool} [createIfNotExists=false] Create the instance of it does not exist at index. 233 * @return {module:core/chart_axis} 234 */ 235 Base.prototype.getXAxis = function(index, createIfNotExists) { 236 return this.__getAxis('x', index, createIfNotExists); 237 }; 238 239 /** 240 * Get the Y axes. 241 * 242 * @return {module:core/chart_axis[]} 243 */ 244 Base.prototype.getYAxes = function() { 245 return this._yaxes; 246 }; 247 248 /** 249 * Get an Y axis. 250 * 251 * @param {Number} [index=0] The index of the axis. 252 * @param {Bool} [createIfNotExists=false] Create the instance of it does not exist at index. 253 * @return {module:core/chart_axis} 254 */ 255 Base.prototype.getYAxis = function(index, createIfNotExists) { 256 return this.__getAxis('y', index, createIfNotExists); 257 }; 258 259 /** 260 * Set the defaults for this chart type. 261 * 262 * Child classes can extend this to set defaults values on instantiation. 263 * 264 * emphasize and self-document the defaults values set by the chart type. 265 * 266 * @protected 267 */ 268 Base.prototype._setDefaults = function() { 269 // For the children to extend. 270 }; 271 272 /** 273 * Set the labels of the X axis. 274 * 275 * This requires for each series to contain strictly as many values as there 276 * are labels. 277 * 278 * @param {String[]} labels The labels. 279 */ 280 Base.prototype.setLabels = function(labels) { 281 if (labels.length && this._series.length && this._series[0].length != labels.length) { 282 throw new Error('Series must match label values.'); 283 } 284 this._labels = labels; 285 }; 286 287 /** 288 * Set the title of the chart. 289 * 290 * @param {String} title The title. 291 */ 292 Base.prototype.setTitle = function(title) { 293 this._title = title; 294 }; 295 296 /** 297 * Set an X axis. 298 * 299 * Note that this will override any predefined axis without warning. 300 * 301 * @param {module:core/chart_axis} axis The axis. 302 * @param {Number} [index=0] The index of the axis. 303 */ 304 Base.prototype.setXAxis = function(axis, index) { 305 index = typeof index === 'undefined' ? 0 : index; 306 this._validateAxis('x', axis, index); 307 this._xaxes[index] = axis; 308 }; 309 310 /** 311 * Set a Y axis. 312 * 313 * Note that this will override any predefined axis without warning. 314 * 315 * @param {module:core/chart_axis} axis The axis. 316 * @param {Number} [index=0] The index of the axis. 317 */ 318 Base.prototype.setYAxis = function(axis, index) { 319 index = typeof index === 'undefined' ? 0 : index; 320 this._validateAxis('y', axis, index); 321 this._yaxes[index] = axis; 322 }; 323 324 /** 325 * Validate an axis. 326 * 327 * @protected 328 * @param {String} xy X or Y axis. 329 * @param {module:core/chart_axis} axis The axis to validate. 330 * @param {Number} [index=0] The index of the axis. 331 */ 332 Base.prototype._validateAxis = function(xy, axis, index) { 333 index = typeof index === 'undefined' ? 0 : index; 334 if (index > 0) { 335 var axes = xy == 'x' ? this._xaxes : this._yaxes; 336 if (typeof axes[index - 1] === 'undefined') { 337 throw new Error('Missing ' + xy + ' axis at index lower than ' + index); 338 } 339 } 340 }; 341 342 /** 343 * Validate a series. 344 * 345 * @protected 346 * @param {module:core/chart_series} series The series to validate. 347 */ 348 Base.prototype._validateSeries = function(series) { 349 if (this._series.length && this._series[0].getCount() != series.getCount()) { 350 throw new Error('Series do not have an equal number of values.'); 351 352 } else if (this._labels.length && this._labels.length != series.getCount()) { 353 throw new Error('Series must match label values.'); 354 } 355 }; 356 357 return Base; 358 359 });
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |