Part of MDL-54987 epic.
* @param {module:core/chart_series} series The series to add.
*/
Base.prototype.addSeries = function(series) {
- this._validateSerie(series);
+ this._validateSeries(series);
this._series.push(series);
// Give a default color from the set.
*/
Base.prototype.setXAxis = function(axis, index) {
index = typeof index === 'undefined' ? 0 : index;
+ this._validateAxis('x', axis, index);
this._xaxes[index] = axis;
};
*/
Base.prototype.setYAxis = function(axis, index) {
index = typeof index === 'undefined' ? 0 : index;
+ this._validateAxis('y', axis, index);
this._yaxes[index] = axis;
};
+ /**
+ * Validate an axis.
+ *
+ * @protected
+ * @param {String} xy X or Y axis.
+ * @param {module:core/chart_axis} axis The axis to validate.
+ * @param {Number} [index=0] The index of the axis.
+ */
+ Base.prototype._validateAxis = function(xy, axis, index) {
+ index = typeof index === 'undefined' ? 0 : index;
+ if (index > 0) {
+ var axes = xy == 'x' ? this._xaxes : this._yaxes;
+ if (typeof axes[index - 1] === 'undefined') {
+ throw new Error('Missing ' + xy + ' axis at index lower than ' + index);
+ }
+ }
+ };
+
/**
* Validate a series.
*
* @protected
* @param {module:core/chart_series} series The series to validate.
*/
- Base.prototype._validateSerie = function(series) {
+ Base.prototype._validateSeries = function(series) {
if (this._series.length && this._series[0].getCount() != series.getCount()) {
throw new Error('Series do not have an equal number of values.');
'core/chart_pie',
], function($, Chartjs, Axis, Base, Pie) {
+ /**
+ * Makes an axis ID.
+ *
+ * @param {String} xy Accepts 'x' and 'y'.
+ * @param {Number} index The axis index.
+ * @return {String}
+ */
+ var makeAxisId = function(xy, index) {
+ return 'axis-' + xy + '-' + index;
+ };
+
/**
* Chart output for Chart.js.
*
*
* @protected
* @param {module:core/chart_axis} axis The axis.
+ * @param {String} xy Accepts 'x' or 'y'.
+ * @param {Number} index The axis index.
* @return {Object} The axis config.
*/
- Output.prototype._makeAxisConfig = function(axis) {
- var scaleData = {};
+ Output.prototype._makeAxisConfig = function(axis, xy, index) {
+ var scaleData = {
+ id: makeAxisId(xy, index)
+ };
if (axis.getPosition() !== Axis.prototype.POS_DEFAULT) {
scaleData.position = axis.getPosition();
this._chart.getXAxes().forEach(function(axis, i) {
config.options.scales = config.options.scales || {};
config.options.scales.xAxes = config.options.scales.xAxes || [];
- config.options.scales.xAxes[i] = this._makeAxisConfig(axis);
+ config.options.scales.xAxes[i] = this._makeAxisConfig(axis, 'x', i);
}.bind(this));
this._chart.getYAxes().forEach(function(axis, i) {
config.options.scales = config.options.scales || {};
config.options.scales.yAxes = config.options.scales.yAxes || [];
- config.options.scales.yAxes[i] = this._makeAxisConfig(axis);
+ config.options.scales.yAxes[i] = this._makeAxisConfig(axis, 'y', i);
if (axisLabels !== null) {
config.options.scales.yAxes[i].ticks.callback = function(value) {
Output.prototype._makeDatasetsConfig = function() {
var sets = this._chart.getSeries().map(function(series) {
var colors = series.hasColoredValues() ? series.getColors() : series.getColor();
- return {
+ var dataset = {
label: series.getLabel(),
data: series.getValues(),
type: series.getType(),
fill: false,
backgroundColor: colors,
// Pie charts look better without borders.
- borderColor: this._chart.getType() == Pie.prototype.TYPE ? null : colors
+ borderColor: this._chart.getType() == Pie.prototype.TYPE ? null : colors,
};
+
+ if (series.getXAxis() !== null) {
+ dataset.xAxisID = makeAxisId('x', series.getXAxis());
+ }
+ if (series.getYAxis() !== null) {
+ dataset.yAxisID = makeAxisId('y', series.getYAxis());
+ }
+
+ return dataset;
}.bind(this));
return sets;
};
*
* @override
*/
- Pie.prototype._validateSerie = function() {
+ Pie.prototype._validateSeries = function() {
if (this._series.length >= 1) {
throw new Error('Pie charts only support one serie.');
}
- return Base.prototype._validateSerie.apply(this, arguments);
+ return Base.prototype._validateSeries.apply(this, arguments);
};
return Pie;
*/
Series.prototype._values = null;
+ /**
+ * The index of the X axis.
+ *
+ * @type {Number[]}
+ * @protected
+ */
+ Series.prototype._xaxis = null;
+
+ /**
+ * The index of the Y axis.
+ *
+ * @type {Number[]}
+ * @protected
+ */
+ Series.prototype._yaxis = null;
+
/**
* Create a new instance of a series from serialised data.
*
Series.prototype.create = function(obj) {
var s = new Series(obj.label, obj.values);
s.setType(obj.type);
+ s.setXAxis(obj.axes.x);
+ s.setYAxis(obj.axes.y);
// Colors are exported as an array with 1, or n values.
if (obj.colors && obj.colors.length > 1) {
return this._values;
};
+ /**
+ * Get the index of the X axis.
+ *
+ * @return {Number}
+ */
+ Series.prototype.getXAxis = function() {
+ return this._xaxis;
+ };
+
+ /**
+ * Get the index of the Y axis.
+ *
+ * @return {Number}
+ */
+ Series.prototype.getYAxis = function() {
+ return this._yaxis;
+ };
+
/**
* Whether there is a color per value.
*
this._type = type || null;
};
+ /**
+ * Set the index of the X axis.
+ *
+ * @param {Number} index The index.
+ */
+ Series.prototype.setXAxis = function(index) {
+ this._xaxis = index || null;
+ };
+
+
+ /**
+ * Set the index of the Y axis.
+ *
+ * @param {Number} index The index.
+ */
+ Series.prototype.setYAxis = function(index) {
+ this._yaxis = index || null;
+ };
+
return Series;
});
* @param int $index The index of the axis.
*/
public function set_xaxis(chart_axis $axis, $index = 0) {
+ $this->validateAxis('x', $axis, $index);
return $this->xaxes[$index] = $axis;
}
* @param int $index The index of the axis.
*/
public function set_yaxis(chart_axis $axis, $index = 0) {
+ $this->validateAxis('y', $axis, $index);
return $this->yaxes[$index] = $axis;
}
+ /**
+ * Validate an axis.
+ *
+ * We validate this from PHP because not doing it here could result in errors being
+ * hard to trace down. For instance, if we were to add axis at keys without another
+ * axis preceding, we would effectively contain the axes in an associative array
+ * rather than a simple array, and that would have consequences on serialisation.
+ *
+ * @param string} $xy Accepts x or y.
+ * @param chart_axis $axis The axis to validate.
+ * @param index $index The index of the axis.
+ */
+ protected function validateAxis($xy, chart_axis $axis, $index = 0) {
+ if ($index > 0) {
+ $axes = $xy == 'x' ? $this->xaxes : $this->yaxes;
+ if (!isset($axes[$index - 1])) {
+ throw new coding_exception('Missing ' . $xy . ' axis at index lower than ' . $index);
+ }
+ }
+ }
+
}
protected $type = self::TYPE_DEFAULT;
/** @var float[] Values of the series. */
protected $values = [];
+ /** @var int Index of the X axis. */
+ protected $xaxis = null;
+ /** @var int Index of the Y axis. */
+ protected $yaxis = null;
/**
* Constructor.
return $this->values;
}
+ /**
+ * Get the index of the X axis.
+ *
+ * @return int
+ */
+ public function get_xaxis() {
+ return $this->xaxis;
+ }
+
+ /**
+ * Get the index of the Y axis.
+ *
+ * @return int
+ */
+ public function get_yaxis() {
+ return $this->yaxis;
+ }
+
/**
* Whether there is a color per value.
*
'type' => $this->type,
'values' => $this->values,
'colors' => $this->colors,
+ 'axes' => [
+ 'x' => $this->xaxis,
+ 'y' => $this->yaxis,
+ ]
];
return $data;
}
$this->type = $type;
}
+ /**
+ * Set the index of the X axis.
+ *
+ * @param int $index The index.
+ */
+ public function set_xaxis($index) {
+ $this->xaxis = $index;
+ }
+
+ /**
+ * Set the index of the Y axis.
+ *
+ * @param int $index The index.
+ */
+ public function set_yaxis($index) {
+ $this->yaxis = $index;
+ }
+
}