[ Index ]

PHP Cross Reference of Moodle 310

title

Body

[close]

/lib/amd/src/ -> chart_base.js (source)

   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  });


Generated: Wed Jan 22 11:59:49 2025 Cross-referenced by PHPXref 0.7.1