MDL-55108 core: Document the charting library
authorFrederic Massart <fred@moodle.com>
Mon, 4 Jul 2016 04:01:25 +0000 (12:01 +0800)
committerDan Poltawski <dan@moodle.com>
Mon, 25 Jul 2016 09:42:59 +0000 (10:42 +0100)
Part of MDL-54987 epic.

17 files changed:
lib/amd/build/chart_builder.min.js
lib/amd/build/chart_output.min.js
lib/amd/build/chart_output_chartjs.min.js
lib/amd/src/chart_axis.js
lib/amd/src/chart_bar.js
lib/amd/src/chart_base.js
lib/amd/src/chart_builder.js
lib/amd/src/chart_line.js
lib/amd/src/chart_output.js
lib/amd/src/chart_output_base.js
lib/amd/src/chart_output_chartjs.js
lib/amd/src/chart_pie.js
lib/amd/src/chart_series.js
lib/classes/chart_axis.php
lib/classes/chart_bar.php
lib/classes/chart_base.php
lib/classes/chart_series.php

index 1f58ab4..c746f31 100644 (file)
Binary files a/lib/amd/build/chart_builder.min.js and b/lib/amd/build/chart_builder.min.js differ
index e72d12c..65c0f11 100644 (file)
Binary files a/lib/amd/build/chart_output.min.js and b/lib/amd/build/chart_output.min.js differ
index ff3210f..0acc1c9 100644 (file)
Binary files a/lib/amd/build/chart_output_chartjs.min.js and b/lib/amd/build/chart_output_chartjs.min.js differ
index 69db868..1ec5234 100644 (file)
  * @package    core
  * @copyright  2016 Frédéric Massart - FMCorz.net
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @module     core/chart_axis
  */
 define([], function() {
 
     /**
-     * Chart axis.
+     * Chart axis class.
+     *
+     * This is used to represent an axis, whether X or Y.
+     *
+     * @alias module:core/chart_axis
+     * @class
      */
     function Axis() {
         // Please eslint no-empty-function.
     }
 
+    /**
+     * Default axis position.
+     * @const {Null}
+     */
     Axis.prototype.POS_DEFAULT = null;
+
+    /**
+     * Bottom axis position.
+     * @const {String}
+     */
     Axis.prototype.POS_BOTTOM = 'bottom';
+
+    /**
+     * Left axis position.
+     * @const {String}
+     */
     Axis.prototype.POS_LEFT = 'left';
+
+    /**
+     * Right axis position.
+     * @const {String}
+     */
     Axis.prototype.POS_RIGHT = 'right';
+
+    /**
+     * Top axis position.
+     * @const {String}
+     */
     Axis.prototype.POS_TOP = 'top';
 
+    /**
+     * Label of the axis.
+     * @type {String}
+     * @protected
+     */
     Axis.prototype._label = null;
+
+    /**
+     * Labels of the ticks.
+     * @type {String[]}
+     * @protected
+     */
     Axis.prototype._labels = null;
+
+    /**
+     * Maximum value of the axis.
+     * @type {Number}
+     * @protected
+     */
     Axis.prototype._max = null;
+
+    /**
+     * Minimum value of the axis.
+     * @type {Number}
+     * @protected
+     */
     Axis.prototype._min = null;
+
+    /**
+     * Position of the axis.
+     * @type {String}
+     * @protected
+     */
     Axis.prototype._position = null;
+
+    /**
+     * Steps on the axis.
+     * @type {Number}
+     * @protected
+     */
     Axis.prototype._stepSize = null;
 
+    /**
+     * Create a new instance of an axis from serialised data.
+     *
+     * @static
+     * @method create
+     * @param {Object} obj The data of the axis.
+     * @return {module:core/chart_axis}
+     */
     Axis.prototype.create = function(obj) {
         var s = new Axis();
         s.setPosition(obj.position);
@@ -53,34 +126,90 @@ define([], function() {
         return s;
     };
 
+    /**
+     * Get the label of the axis.
+     *
+     * @method getLabel
+     * @return {String}
+     */
     Axis.prototype.getLabel = function() {
         return this._label;
     };
 
+    /**
+     * Get the labels of the ticks of the axis.
+     *
+     * @method getLabels
+     * @return {String[]}
+     */
     Axis.prototype.getLabels = function() {
         return this._labels;
     };
 
+    /**
+     * Get the maximum value of the axis.
+     *
+     * @method getMax
+     * @return {Number}
+     */
     Axis.prototype.getMax = function() {
         return this._max;
     };
 
+    /**
+     * Get the minimum value of the axis.
+     *
+     * @method getMin
+     * @return {Number}
+     */
     Axis.prototype.getMin = function() {
         return this._min;
     };
 
+    /**
+     * Get the position of the axis.
+     *
+     * @method getPosition
+     * @return {String}
+     */
     Axis.prototype.getPosition = function() {
         return this._position;
     };
 
+    /**
+     * Get the step size of the axis.
+     *
+     * @method getStepSize
+     * @return {Number}
+     */
     Axis.prototype.getStepSize = function() {
         return this._stepSize;
     };
 
+    /**
+     * Set the label of the axis.
+     *
+     * @method setLabel
+     * @param {String} label The label.
+     */
     Axis.prototype.setLabel = function(label) {
         this._label = label || null;
     };
 
+    /**
+     * Set the labels of the values on the axis.
+     *
+     * This automatically sets the [_stepSize]{@link module:core/chart_axis#_stepSize},
+     * [_min]{@link module:core/chart_axis#_min} and [_max]{@link module:core/chart_axis#_max}
+     * to define a scale from 0 to the number of labels when none of the previously
+     * mentioned values have been modified.
+     *
+     * You can use other values so long that your values in a series are mapped
+     * to the values represented by your _min, _max and _stepSize.
+     *
+     * @method setLabels
+     * @param {String[]} labels The labels.
+     */
     Axis.prototype.setLabels = function(labels) {
         this._labels = labels || null;
 
@@ -95,14 +224,45 @@ define([], function() {
         }
     };
 
+    /**
+     * Set the maximum value on the axis.
+     *
+     * When this is not set (or set to null) it is left for the output
+     * library to best guess what should be used.
+     *
+     * @method setMax
+     * @param {Number} max The value.
+     */
     Axis.prototype.setMax = function(max) {
         this._max = typeof max !== 'undefined' ? max : null;
     };
 
+    /**
+     * Set the minimum value on the axis.
+     *
+     * When this is not set (or set to null) it is left for the output
+     * library to best guess what should be used.
+     *
+     * @method setMin
+     * @param {Number} min The value.
+     */
     Axis.prototype.setMin = function(min) {
         this._min = typeof min !== 'undefined' ? min : null;
     };
 
+    /**
+     * Set the position of the axis.
+     *
+     * This does not validate whether or not the constant used is valid
+     * as the axis itself is not aware whether it represents the X or Y axis.
+     *
+     * The output library has to have a fallback in case the values are incorrect.
+     * When this is not set to {@link module:core/chart_axis#POS_DEFAULT} it is up
+     * to the output library to choose what position fits best.
+     *
+     * @method setPosition
+     * @param {String} position The value.
+     */
     Axis.prototype.setPosition = function(position) {
         if (position != this.POS_DEFAULT
                 && position != this.POS_BOTTOM
@@ -114,6 +274,14 @@ define([], function() {
         this._position = position;
     };
 
+    /**
+     * Set the stepSize on the axis.
+     *
+     * This is used to determine where ticks are displayed on the axis between min and max.
+     *
+     * @method setStepSize
+     * @param {Number} stepSize The value.
+     */
     Axis.prototype.setStepSize = function(stepSize) {
         if (typeof stepSize === 'undefined' || stepSize === null) {
             stepSize = null;
index 4b6fdcc..d01faf4 100644 (file)
  * @package    core
  * @copyright  2016 Frédéric Massart - FMCorz.net
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @module     core/chart_bar
  */
 define(['core/chart_base'], function(Base) {
 
     /**
      * Bar chart.
+     *
+     * @alias module:core/chart_bar
+     * @extends {module:core/chart_base}
+     * @class
      */
     function Bar() {
         Base.prototype.constructor.apply(this, arguments);
     }
     Bar.prototype = Object.create(Base.prototype);
 
+    /** @override */
     Bar.prototype.TYPE = 'bar';
 
+    /** @override */
     Bar.prototype._setDefaults = function() {
         Base.prototype._setDefaults.apply(this, arguments);
         var axis = this.getYAxis(0, true);
index 1c9fc02..c99efcf 100644 (file)
  * @package    core
  * @copyright  2016 Frédéric Massart - FMCorz.net
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @module     core/chart_base
  */
 define(['core/chart_series', 'core/chart_axis'], function(Series, Axis) {
 
     /**
      * Chart base.
+     *
+     * The constructor of a chart must never take any argument.
+     *
+     * {@link module:core/chart_base#_setDefault} to set the defaults on instantiation.
+     *
+     * @alias module:core/chart_base
+     * @class
      */
     function Base() {
         this._series = [];
@@ -33,25 +41,92 @@ define(['core/chart_series', 'core/chart_axis'], function(Series, Axis) {
 
         this._setDefaults();
     }
+
+    /**
+     * The series constituting this chart.
+     *
+     * @protected
+     * @type {module:core/chart_series[]}
+     */
     Base.prototype._series = null;
+
+    /**
+     * The labels of the X axis when categorised.
+     *
+     * @protected
+     * @type {String[]}
+     */
     Base.prototype._labels = null;
+
+    /**
+     * The title of the chart.
+     *
+     * @protected
+     * @type {String}
+     */
     Base.prototype._title = null;
+
+    /**
+     * The X axes.
+     *
+     * @protected
+     * @type {module:core/chart_axis[]}
+     */
     Base.prototype._xaxes = null;
+
+    /**
+     * The Y axes.
+     *
+     * @protected
+     * @type {module:core/chart_axis[]}
+     */
     Base.prototype._yaxes = null;
 
+    /**
+     * Colours to pick from when automatically assigning them.
+     *
+     * @const
+     * @type {String[]}
+     */
     Base.prototype.COLORSET = ['red', 'green', 'blue', 'yellow', 'pink', 'orange'];
+
+    /**
+     * The type of chart.
+     *
+     * @abstract
+     * @type {String}
+     * @const
+     */
     Base.prototype.TYPE = null;
 
-    Base.prototype.addSeries = function(serie) {
-        this._validateSerie(serie);
-        this._series.push(serie);
+    /**
+     * Add a series to the chart.
+     *
+     * This will automatically assign a color to the series if it does not have one.
+     *
+     * @param {module:core/chart_series} series The series to add.
+     */
+    Base.prototype.addSeries = function(series) {
+        this._validateSerie(series);
+        this._series.push(series);
 
         // Give a default color from the set.
-        if (serie.getColor() === null) {
-            serie.setColor(Base.prototype.COLORSET[this._series.length % Base.prototype.COLORSET.length]);
+        if (series.getColor() === null) {
+            series.setColor(Base.prototype.COLORSET[this._series.length % Base.prototype.COLORSET.length]);
         }
     };
 
+    /**
+     * Create a new instance of a chart from serialised data.
+     *
+     * the serialised attributes they offer and support.
+     *
+     * @static
+     * @method create
+     * @param {module:core/chart_base} Klass The class oject representing the type of chart to instantiate.
+     * @param {Object} data The data of the chart.
+     * @return {module:core/chart_base}
+     */
     Base.prototype.create = function(Klass, data) {
         // TODO Not convinced about the usage of Klass here but I can't figure out a way
         // to have a reference to the class in the sub classes, in PHP I'd do new self().
@@ -71,6 +146,15 @@ define(['core/chart_series', 'core/chart_axis'], function(Series, Axis) {
         return Chart;
     };
 
+    /**
+     * Get an axis.
+     *
+     * @private
+     * @param {String} xy Accepts the values 'x' or 'y'.
+     * @param {Number} [index=0] The index of the axis of its type.
+     * @param {Bool} [createIfNotExists=false] When true, create an instance if it does not exist.
+     * @return {module:core/chart_axis}
+     */
     Base.prototype.__getAxis = function(xy, index, createIfNotExists) {
         var axes = xy === 'x' ? this._xaxes : this._yaxes,
             setAxis = (xy === 'x' ? this.setXAxis : this.setYAxis).bind(this),
@@ -91,18 +175,39 @@ define(['core/chart_series', 'core/chart_axis'], function(Series, Axis) {
         return axis;
     };
 
+    /**
+     * Get the labels of the X axis.
+     *
+     * @return {String[]}
+     */
     Base.prototype.getLabels = function() {
         return this._labels;
     };
 
+    /**
+     * Get the series.
+     *
+     * @return {module:core/chart_series[]}
+     */
     Base.prototype.getSeries = function() {
         return this._series;
     };
 
+    /**
+     * Get the title of the chart.
+     *
+     * @return {String}
+     */
     Base.prototype.getTitle = function() {
         return this._title;
     };
 
+    /**
+     * Get the type of chart.
+     *
+     * @see module:core/chart_base#TYPE
+     * @return {String}
+     */
     Base.prototype.getType = function() {
         if (!this.TYPE) {
             throw new Error('The TYPE property has not been set.');
@@ -110,26 +215,67 @@ define(['core/chart_series', 'core/chart_axis'], function(Series, Axis) {
         return this.TYPE;
     };
 
+    /**
+     * Get the X axes.
+     *
+     * @return {module:core/chart_axis[]}
+     */
     Base.prototype.getXAxes = function() {
         return this._xaxes;
     };
 
+    /**
+     * Get an X axis.
+     *
+     * @param {Number} [index=0] The index of the axis.
+     * @param {Bool} [createIfNotExists=false] Create the instance of it does not exist at index.
+     * @return {module:core/chart_axis}
+     */
     Base.prototype.getXAxis = function(index, createIfNotExists) {
         return this.__getAxis('x', index, createIfNotExists);
     };
 
+    /**
+     * Get the Y axes.
+     *
+     * @return {module:core/chart_axis[]}
+     */
     Base.prototype.getYAxes = function() {
         return this._yaxes;
     };
 
+    /**
+     * Get an Y axis.
+     *
+     * @param {Number} [index=0] The index of the axis.
+     * @param {Bool} [createIfNotExists=false] Create the instance of it does not exist at index.
+     * @return {module:core/chart_axis}
+     */
     Base.prototype.getYAxis = function(index, createIfNotExists) {
         return this.__getAxis('y', index, createIfNotExists);
     };
 
+    /**
+     * Set the defaults for this chart type.
+     *
+     * Child classes can extend this to set defaults values on instantiation.
+     *
+     * emphasize and self-document the defaults values set by the chart type.
+     *
+     * @protected
+     */
     Base.prototype._setDefaults = function() {
         // For the children to extend.
     };
 
+    /**
+     * Set the labels of the X axis.
+     *
+     * This requires for each series to contain strictly as many values as there
+     * are labels.
+     *
+     * @param {String[]} labels The labels.
+     */
     Base.prototype.setLabels = function(labels) {
         if (labels.length && this._series.length && this._series[0].length != labels.length) {
             throw new Error('Series must match label values.');
@@ -137,25 +283,52 @@ define(['core/chart_series', 'core/chart_axis'], function(Series, Axis) {
         this._labels = labels;
     };
 
+    /**
+     * Set the title of the chart.
+     *
+     * @param {String} title The title.
+     */
     Base.prototype.setTitle = function(title) {
         this._title = title;
     };
 
+    /**
+     * Set an X axis.
+     *
+     * Note that this will override any predefined axis without warning.
+     *
+     * @param {module:core/chart_axis} axis The axis.
+     * @param {Number} [index=0] The index of the axis.
+     */
     Base.prototype.setXAxis = function(axis, index) {
         index = typeof index === 'undefined' ? 0 : index;
         this._xaxes[index] = axis;
     };
 
+    /**
+     * Set a Y axis.
+     *
+     * Note that this will override any predefined axis without warning.
+     *
+     * @param {module:core/chart_axis} axis The axis.
+     * @param {Number} [index=0] The index of the axis.
+     */
     Base.prototype.setYAxis = function(axis, index) {
         index = typeof index === 'undefined' ? 0 : index;
         this._yaxes[index] = axis;
     };
 
-    Base.prototype._validateSerie = function(serie) {
-        if (this._series.length && this._series[0].getCount() != serie.getCount()) {
+    /**
+     * Validate a series.
+     *
+     * @protected
+     * @param {module:core/chart_series} series The series to validate.
+     */
+    Base.prototype._validateSerie = function(series) {
+        if (this._series.length && this._series[0].getCount() != series.getCount()) {
             throw new Error('Series do not have an equal number of values.');
 
-        } else if (this._labels.length && this._labels.length != serie.getCount()) {
+        } else if (this._labels.length && this._labels.length != series.getCount()) {
             throw new Error('Series must match label values.');
         }
     };
index 44553e2..5978c89 100644 (file)
 /**
  * Chart builder.
  *
- * This takes data, most likely generated in PHP, and creates a chart instance.
- *
  * @package    core
  * @copyright  2016 Frédéric Massart - FMCorz.net
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 define(['jquery'], function($) {
 
-    return {
+    /**
+     * Chart builder.
+     *
+     * @exports core/chart_builder
+     */
+    var module = {
+
+        /**
+         * Make a chart instance.
+         *
+         * This takes data, most likely generated in PHP, and creates a chart instance from it
+         * deferring most of the logic to {@link module:core/chart_base.create}.
+         *
+         * @param {Object} data The data.
+         * @return {Promise} A promise resolved with the chart instance.
+         */
         make: function(data) {
             var deferred = $.Deferred();
             require(['core/chart_' + data.type], function(Klass) {
@@ -35,4 +48,6 @@ define(['jquery'], function($) {
         }
     };
 
+    return module;
+
 });
index a4351c9..ff30a86 100644 (file)
  * @package    core
  * @copyright  2016 Frédéric Massart - FMCorz.net
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @module     core/chart_line
  */
 define(['core/chart_base'], function(Base) {
 
     /**
      * Line chart.
+     *
+     * @alias module:core/chart_line
+     * @extends {module:core/chart_base}
+     * @class
      */
     function Line() {
         Base.prototype.constructor.apply(this, arguments);
     }
     Line.prototype = Object.create(Base.prototype);
 
+    /** @override */
     Line.prototype.TYPE = 'line';
 
     return Line;
index b7d9477..6848841 100644 (file)
  */
 define(['core/chart_output_chartjs'], function(Output) {
 
-    return Output;
+    /**
+     * @exports module:core/chart_output
+     * @extends {module:core/chart_output_chartjs}
+     */
+    var defaultModule = Output;
+
+    return defaultModule;
 
 });
index 91c6ae5..ac256e7 100644 (file)
  * @package    core
  * @copyright  2016 Frédéric Massart - FMCorz.net
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @module     core/chart_output_base
  */
 define(['jquery'], function($) {
 
     /**
      * Chart output base.
      *
+     * The constructor of an output class must instantly generate and display the
+     * chart. It is also the responsability of the output module to check that
+     * the node received is of the appropriate type, if not a new node can be
+     * added within.
+     *
+     * The output module has total control over the content of the node and can
+     * clear it or output anything to it at will. A node should not be shared by
+     * two simultaneous output modules.
+     *
+     * @class
+     * @alias module:core/chart_output_base
      * @param {Node} node The node to output with/in.
      * @param {Chart} chart A chart object.
      */
@@ -35,6 +47,16 @@ define(['jquery'], function($) {
         this._chart = chart;
     }
 
+    /**
+     * Update method.
+     *
+     * This is the public method through which an output instance in informed
+     * that the chart instance has been updated and they need to update the
+     * chart rendering.
+     *
+     * @abstract
+     * @return {Void}
+     */
     Base.prototype.update = function() {
         throw new Error('Not supported.');
     };
index 54daedd..775589a 100644 (file)
@@ -19,6 +19,7 @@
  * @package    core
  * @copyright  2016 Frédéric Massart - FMCorz.net
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @module     core/chart_output_chartjs
  */
 define([
     'jquery',
@@ -29,6 +30,10 @@ define([
 
     /**
      * Chart output for Chart.js.
+     *
+     * @class
+     * @alias module:core/chart_output_chartjs
+     * @extends {module:core/chart_output_base}
      */
     function Output() {
         Base.prototype.constructor.apply(this, arguments);
@@ -42,32 +47,49 @@ define([
 
         this._build();
     }
-
     Output.prototype = Object.create(Base.prototype);
 
+    /**
+     * Reference to the chart config object.
+     *
+     * @type {Object}
+     * @protected
+     */
     Output.prototype._config = null;
+
+    /**
+     * Reference to the instance of chart.js.
+     *
+     * @type {Object}
+     * @protected
+     */
     Output.prototype._chartjs = null;
-    Output.prototype._canvas = null;
 
-    Output.prototype.getDatasets = function() {
-        var sets = this._chart.getSeries().map(function(series) {
-            return {
-                label: series.getLabel(),
-                data: series.getValues(),
-                type: series.getType(),
-                fill: false,
-                borderColor: series.getColor(),
-                backgroundColor: series.getColor()
-            };
-        });
-        return sets;
-    };
+    /**
+     * Reference to the canvas node.
+     *
+     * @type {Jquery}
+     * @protected
+     */
+    Output.prototype._canvas = null;
 
+    /**
+     * Builds the config and the chart.
+     *
+     * @protected
+     */
     Output.prototype._build = function() {
         this._config = this._makeConfig();
         this._chartjs = new Chartjs(this._canvas[0], this._config);
     };
 
+    /**
+     * Make the axis config.
+     *
+     * @protected
+     * @param {module:core/chart_axis} axis The axis.
+     * @return {Object} The axis config.
+     */
     Output.prototype._makeAxisConfig = function(axis) {
         var scaleData = {};
 
@@ -100,12 +122,19 @@ define([
         return scaleData;
     };
 
+    /**
+     * Make the config config.
+     *
+     * @protected
+     * @param {module:core/chart_axis} axis The axis.
+     * @return {Object} The axis config.
+     */
     Output.prototype._makeConfig = function() {
         var config = {
             type: this._chart.getType(),
             data: {
                 labels: this._chart.getLabels(),
-                datasets: this.getDatasets()
+                datasets: this._makeDatasetsConfig()
             },
             options: {
                 title: {
@@ -138,6 +167,27 @@ define([
         return config;
     };
 
+    /**
+     * Get the datasets configurations.
+     *
+     * @protected
+     * @return {Object[]}
+     */
+    Output.prototype._makeDatasetsConfig = function() {
+        var sets = this._chart.getSeries().map(function(series) {
+            return {
+                label: series.getLabel(),
+                data: series.getValues(),
+                type: series.getType(),
+                fill: false,
+                borderColor: series.getColor(),
+                backgroundColor: series.getColor()
+            };
+        });
+        return sets;
+    };
+
+    /** @override */
     Output.prototype.update = function() {
         $.extend(true, this._config, this._makeConfig());
         this._chartjs.update();
index 8325520..57756df 100644 (file)
  * @package    core
  * @copyright  2016 Frédéric Massart - FMCorz.net
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @module     core/chart_pie
  */
 define(['core/chart_base'], function(Base) {
 
     /**
      * Pie chart.
+     *
+     * @class
+     * @alias module:core/chart_pie
+     * @extends {module:core/chart_base}
      */
     function Pie() {
         Base.prototype.constructor.apply(this, arguments);
     }
     Pie.prototype = Object.create(Base.prototype);
 
+    /** @override */
     Pie.prototype.TYPE = 'pie';
 
+    /**
+     * Validate a series.
+     *
+     * Overrides parent implementation to validate that there is only
+     * one series per chart instance.
+     *
+     * @override
+     */
     Pie.prototype._validateSerie = function() {
         if (this._series.length >= 1) {
             throw new Error('Pie charts only support one serie.');
index 9df3176..73f827a 100644 (file)
  * @package    core
  * @copyright  2016 Frédéric Massart - FMCorz.net
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @module     core/chart_series
  */
 define([], function() {
 
     /**
      * Chart data series.
      *
+     * @class
+     * @alias module:core/chart_series
      * @param {String} label The series label.
      * @param {Number[]} values The values.
      */
@@ -43,14 +46,62 @@ define([], function() {
         this._values = values;
     }
 
+    /**
+     * The default type of series.
+     *
+     * @type {Null}
+     * @const
+     */
     Series.prototype.TYPE_DEFAULT = null;
+
+    /**
+     * Type of series 'line'.
+     *
+     * @type {String}
+     * @const
+     */
     Series.prototype.TYPE_LINE = 'line';
 
+    /**
+     * The color of the series.
+     *
+     * @type {String}
+     * @protected
+     */
     Series.prototype._color = null;
+
+    /**
+     * The label of the series.
+     *
+     * @type {String}
+     * @protected
+     */
     Series.prototype._label = null;
+
+    /**
+     * The type of the series.
+     *
+     * @type {String}
+     * @protected
+     */
     Series.prototype._type = Series.prototype.TYPE_DEFAULT;
+
+    /**
+     * The values in the series.
+     *
+     * @type {Number[]}
+     * @protected
+     */
     Series.prototype._values = null;
 
+    /**
+     * Create a new instance of a series from serialised data.
+     *
+     * @static
+     * @method create
+     * @param {Object} obj The data of the series.
+     * @return {module:core/chart_series}
+     */
     Series.prototype.create = function(obj) {
         var s = new Series(obj.label, obj.values);
         s.setColor(obj.color);
@@ -58,30 +109,65 @@ define([], function() {
         return s;
     };
 
+    /**
+     * Get the color.
+     *
+     * @return {String}
+     */
     Series.prototype.getColor = function() {
         return this._color;
     };
 
+    /**
+     * Get the number of values in the series.
+     *
+     * @return {Number}
+     */
     Series.prototype.getCount = function() {
         return this._values.length;
     };
 
+    /**
+     * Get the series label.
+     *
+     * @return {String}
+     */
     Series.prototype.getLabel = function() {
         return this._label;
     };
 
+    /**
+     * Get the series type.
+     *
+     * @return {String}
+     */
     Series.prototype.getType = function() {
         return this._type;
     };
 
+    /**
+     * Get the series values.
+     *
+     * @return {Number[]}
+     */
     Series.prototype.getValues = function() {
         return this._values;
     };
 
+    /**
+     * Set the series color.
+     *
+     * @param {String} color A CSS-compatible color.
+     */
     Series.prototype.setColor = function(color) {
         this._color = color || null;
     };
 
+    /**
+     * Set the type of the series.
+     *
+     * @param {String} type A type constant value.
+     */
     Series.prototype.setType = function(type) {
         if (type != this.TYPE_DEFAULT && type != this.TYPE_LINE) {
             throw new Error('Invalid serie type.');
index 58ee667..1703472 100644 (file)
@@ -38,46 +38,97 @@ use renderable;
  */
 class chart_axis implements JsonSerializable {
 
+    /** Default axis position. */
     const POS_DEFAULT = null;
+    /** Bottom axis position. */
     const POS_BOTTOM = 'bottom';
+    /** Left axis position. */
     const POS_LEFT = 'left';
+    /** Right axis position. */
     const POS_RIGHT = 'right';
+    /** Top axis position. */
     const POS_TOP = 'top';
 
+    /** @var string The axis label. */
     protected $label = null;
+    /** @var string[] The axis labels, tick values. */
     protected $labels = null;
+    /** @var float The maximum tick value. */
     protected $max = null;
+    /** @var float The minimum tick value. */
     protected $min = null;
+    /** @var string The axis position. */
     protected $position = self::POS_DEFAULT;
+    /** @var float The stepsize between ticks. */
     protected $stepsize = null;
 
+    /**
+     * Constructor.
+     *
+     * Must not take any argument.
+     */
     public function __construct() {
     }
 
+    /**
+     * Get the label.
+     *
+     * @return string
+     */
     public function get_label() {
         return $this->label;
     }
 
+    /**
+     * Get the labels.
+     *
+     * @return string[]
+     */
     public function get_labels() {
         return $this->labels;
     }
 
+    /**
+     * Get the max value.
+     *
+     * @return float
+     */
     public function get_max() {
         return $this->max;
     }
 
+    /**
+     * Get the min value.
+     *
+     * @return float
+     */
     public function get_min() {
         return $this->min;
     }
 
+    /**
+     * Get the axis position.
+     *
+     * @return string
+     */
     public function get_position() {
         return $this->position;
     }
 
+    /**
+     * Get the step size.
+     *
+     * @return float
+     */
     public function get_stepsize() {
         return $this->stepsize;
     }
 
+    /**
+     * Serialize the object.
+     *
+     * @return array
+     */
     public function jsonSerialize() {
         return [
             'label' => $this->label,
@@ -89,28 +140,58 @@ class chart_axis implements JsonSerializable {
         ];
     }
 
+    /**
+     * Set the label.
+     *
+     * @param string $label The label.
+     */
     public function set_label($label) {
-        return $this->label = $label;
+        $this->label = $label;
     }
 
+    /**
+     * Set the labels.
+     *
+     * @param string[] $labels The labels.
+     */
     public function set_labels($labels) {
-        return $this->labels = $labels;
+        $this->labels = $labels;
     }
 
+    /**
+     * Set the max value.
+     *
+     * @param float $max The max value.
+     */
     public function set_max($max) {
-        return $this->max = $max;
+        $this->max = $max;
     }
 
+    /**
+     * Set the min value.
+     *
+     * @param float $min The min value.
+     */
     public function set_min($min) {
-        return $this->min = $min;
+        $this->min = $min;
     }
 
+    /**
+     * Set the position.
+     *
+     * @param string $position Use constant self::POS_*.
+     */
     public function set_position($position) {
-        return $this->position = $position;
+        $this->position = $position;
     }
 
+    /**
+     * Set the step size.
+     *
+     * @param float $stepsize The step size.
+     */
     public function set_stepsize($stepsize) {
-        return $this->stepsize = $stepsize;
+        $this->stepsize = $stepsize;
     }
 
 }
index 46f895e..127563a 100644 (file)
@@ -34,6 +34,9 @@ defined('MOODLE_INTERNAL') || die();
  */
 class chart_bar extends chart_base {
 
+    /**
+     * Set the defaults.
+     */
     protected function set_defaults() {
         parent::set_defaults();
         $yaxis = $this->get_yaxis(0, true);
index ce0967f..acac8a4 100644 (file)
@@ -38,20 +38,43 @@ use renderable;
  */
 class chart_base implements JsonSerializable, renderable {
 
+    /** @var chart_series[] The series constituting this chart. */
     protected $series = [];
+    /** @var string[] The labels for the X axis when categorised. */
     protected $labels = [];
+    /** @var string The title of the chart. */
     protected $title = null;
+    /** @var chart_axis[] The X axes. */
     protected $xaxes = [];
+    /** @var chart_axis[] The Y axes. */
     protected $yaxes = [];
 
+    /**
+     * Constructor.
+     *
+     * Must not take any argument.
+     *
+     * Most of the time you do not want to extend this, rather extend the
+     * method {@link self::set_defaults} to set the defaults on instantiation.
+     */
     public function __construct() {
         $this->set_defaults();
     }
 
+    /**
+     * Add a series to the chart.
+     *
+     * @param chart_series $serie The serie.
+     */
     public function add_series(chart_series $serie) {
         $this->series[] = $serie;
     }
 
+    /**
+     * Serialize the object.
+     *
+     * @return array
+     */
     public function jsonSerialize() {
         return [
             'type' => $this->get_type(),
@@ -65,6 +88,14 @@ class chart_base implements JsonSerializable, renderable {
         ];
     }
 
+    /**
+     * Get an axis.
+     *
+     * @param string $type Accepts values 'x' or 'y'.
+     * @param int $index The index of this axis.
+     * @param bool $createifnotexists Whether to create the axis if not found.
+     * @return chart_axis
+     */
     private function get_axis($type, $index, $createifnotexists) {
         $isx = $type === 'x';
         if ($isx) {
@@ -89,55 +120,134 @@ class chart_base implements JsonSerializable, renderable {
         return $axis;
     }
 
+    /**
+     * Get the labels of the X axis.
+     *
+     * @return string[]
+     */
     public function get_labels() {
         return $this->labels;
     }
 
+    /**
+     * Get the series.
+     *
+     * @return chart_series[]
+     */
     public function get_series() {
         return $this->series;
     }
 
+    /**
+     * Get the title.
+     *
+     * @return string
+     */
     public function get_title() {
         return $this->title;
     }
 
+    /**
+     * Get the chart type.
+     *
+     * @return string
+     */
     public function get_type() {
         $classname = get_class($this);
         return substr($classname, strpos($classname, '_') + 1);
     }
 
+    /**
+     * Get the X axes.
+     *
+     * @return chart_axis[]
+     */
     public function get_xaxes() {
         return $this->xaxes;
     }
 
+    /**
+     * Get an X axis.
+     *
+     * @param int $index The index of the axis.
+     * @param bool $createifnotexists When true, create an instance of the axis if none exist at this index yet.
+     * @return chart_axis
+     */
     public function get_xaxis($index = 0, $createifnotexists = false) {
         return $this->get_axis('x', $index, $createifnotexists);
     }
 
+    /**
+     * Get the Y axes.
+     *
+     * @return chart_axis[]
+     */
     public function get_yaxes() {
         return $this->yaxes;
     }
 
+    /**
+     * Get a Y axis.
+     *
+     * @param int $index The index of the axis.
+     * @param bool $createifnotexists When true, create an instance of the axis if none exist at this index yet.
+     * @return chart_axis
+     */
     public function get_yaxis($index = 0, $createifnotexists = false) {
         return $this->get_axis('y', $index, $createifnotexists);
     }
 
+    /**
+     * Set the defaults for this chart type.
+     *
+     * Child classes can extend this to set default values on instantiation.
+     *
+     * In general the constructor could be used, but this method is here to
+     * emphasize and self-document the default values set by the chart type.
+     *
+     * @return void
+     */
     protected function set_defaults() {
-        // For the child classes to extend.
     }
 
+    /**
+     * Set the chart labels.
+     *
+     * @param string[] $labels The labels.
+     */
     public function set_labels(array $labels) {
         $this->labels = $labels;
     }
 
+    /**
+     * Set the title.
+     *
+     * @param string $title The title.
+     */
     public function set_title($title) {
         $this->title = $title;
     }
 
+    /**
+     * Set an X axis.
+     *
+     * Note that this will override any predefined axis without warning.
+     *
+     * @param chart_axis $axis The axis.
+     * @param int $index The index of the axis.
+     */
     public function set_xaxis(chart_axis $axis, $index = 0) {
         return $this->xaxes[$index] = $axis;
     }
 
+    /**
+     * Set an Y axis.
+     *
+     * Note that this will override any predefined axis without warning.
+     *
+     * @param chart_axis $axis The axis.
+     * @param int $index The index of the axis.
+     */
     public function set_yaxis(chart_axis $axis, $index = 0) {
         return $this->yaxes[$index] = $axis;
     }
index 2c5a93f..4ac93ef 100644 (file)
@@ -37,39 +37,81 @@ use JsonSerializable;
  */
 class chart_series implements JsonSerializable {
 
+    /** Default type for a series. */
     const TYPE_DEFAULT = null;
+    /** Series of type line. */
     const TYPE_LINE = 'line';
 
+    /** @var string Color of the series. */
     protected $color;
+    /** @var string Label for this series. */
     protected $label;
+    /** @var string Type of the series. */
     protected $type = self::TYPE_DEFAULT;
+    /** @var float[] Values of the series. */
     protected $values = [];
 
+    /**
+     * Constructor.
+     *
+     * @param string $label The label of the series.
+     * @param float[] $values The values of this series.
+     */
     public function __construct($label, $values) {
         $this->values = $values;
         $this->label = $label;
     }
 
+    /**
+     * Get the color.
+     *
+     * @return string
+     */
     public function get_color() {
         return $this->color;
     }
 
+    /**
+     * Get the number of values in this series.
+     *
+     * @return int
+     */
     public function get_count() {
         return count($this->values);
     }
 
+    /**
+     * Get the label of the series.
+     *
+     * @return string
+     */
     public function get_label() {
         return $this->label;
     }
 
+    /**
+     * Get the type of series.
+     *
+     * @return string
+     */
     public function get_type() {
         return $this->type;
     }
 
+    /**
+     * Get the values of the series.
+     *
+     * @return [type]
+     */
     public function get_values() {
         return $this->values;
     }
 
+    /**
+     * Serialize the object.
+     *
+     * @return array
+     */
     public function jsonSerialize() {
         $data = [
             'label' => $this->label,
@@ -80,10 +122,20 @@ class chart_series implements JsonSerializable {
         return $data;
     }
 
+    /**
+     * Set the color of the series.
+     *
+     * @param string $color CSS compatible color.
+     */
     public function set_color($color) {
         $this->color = $color;
     }
 
+    /**
+     * Set the type of the series.
+     *
+     * @param string $type Constant value from self::TYPE_*.
+     */
     public function set_type($type) {
         if (!in_array($type, [self::TYPE_DEFAULT, self::TYPE_LINE])) {
             throw new coding_exception('Invalid serie type.');