MDL-85158 libraries: Configure responsive options for ChartJS
Currently, the attributes to configure the responsiveness of a chart are being set statically. With this change it will be possible to update these static attributes in order to change the aspectRatio and resizeDelay of the chart.
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
issueNumber: MDL-85158
|
||||
notes:
|
||||
core:
|
||||
- message: >-
|
||||
Added support for configurable `aspectRatio` in charts rendered using
|
||||
Chart.js. This enables developers to control chart sizing more precisely
|
||||
via the `chart_base` API and the frontend renderer.
|
||||
type: improved
|
||||
Vendored
+1
-1
@@ -5,6 +5,6 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @module core/chart_base
|
||||
*/
|
||||
define("core/chart_base",["core/chart_series","core/chart_axis"],(function(Series,Axis){function Base(){this._series=[],this._labels=[],this._xaxes=[],this._yaxes=[],this._setDefaults()}return Base.prototype._series=null,Base.prototype._labels=null,Base.prototype._legendOptions=null,Base.prototype._title=null,Base.prototype._xaxes=null,Base.prototype._yaxes=null,Base.prototype.COLORSET=["#f3c300","#875692","#f38400","#a1caf1","#be0032","#c2b280","#7f180d","#008856","#e68fac","#0067a5"],Base.prototype._configColorSet=null,Base.prototype.TYPE=null,Base.prototype.addSeries=function(series){if(this._validateSeries(series),this._series.push(series),null===series.getColor()){var configColorSet=this.getConfigColorSet()||Base.prototype.COLORSET;series.setColor(configColorSet[this._series.length%configColorSet.length])}},Base.prototype.create=function(Klass,data){var Chart=new Klass;return Chart.setConfigColorSet(data.config_colorset),Chart.setLabels(data.labels),Chart.setTitle(data.title),data.legend_options&&Chart.setLegendOptions(data.legend_options),data.series.forEach((function(seriesData){Chart.addSeries(Series.prototype.create(seriesData))})),data.axes.x.forEach((function(axisData,i){Chart.setXAxis(Axis.prototype.create(axisData),i)})),data.axes.y.forEach((function(axisData,i){Chart.setYAxis(Axis.prototype.create(axisData),i)})),Chart},Base.prototype.__getAxis=function(xy,index,createIfNotExists){var axis,axes="x"===xy?this._xaxes:this._yaxes,setAxis=("x"===xy?this.setXAxis:this.setYAxis).bind(this);if(createIfNotExists=void 0!==createIfNotExists&&createIfNotExists,void 0===(axis=axes[index=void 0===index?0:index])){if(!createIfNotExists)throw new Error("Unknown axis.");setAxis(axis=new Axis,index)}return axis},Base.prototype.getConfigColorSet=function(){return this._configColorSet},Base.prototype.getLabels=function(){return this._labels},Base.prototype.getLegendOptions=function(){return this._legendOptions},Base.prototype.getSeries=function(){return this._series},Base.prototype.getTitle=function(){return this._title},Base.prototype.getType=function(){if(!this.TYPE)throw new Error("The TYPE property has not been set.");return this.TYPE},Base.prototype.getXAxes=function(){return this._xaxes},Base.prototype.getXAxis=function(index,createIfNotExists){return this.__getAxis("x",index,createIfNotExists)},Base.prototype.getYAxes=function(){return this._yaxes},Base.prototype.getYAxis=function(index,createIfNotExists){return this.__getAxis("y",index,createIfNotExists)},Base.prototype.setConfigColorSet=function(colorset){this._configColorSet=colorset},Base.prototype._setDefaults=function(){},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.");this._labels=labels},Base.prototype.setLegendOptions=function(legendOptions){if("object"!=typeof legendOptions)throw new Error("Setting legend with non-object value:"+legendOptions);this._legendOptions=legendOptions},Base.prototype.setTitle=function(title){this._title=title},Base.prototype.setXAxis=function(axis,index){index=void 0===index?0:index,this._validateAxis("x",axis,index),this._xaxes[index]=axis},Base.prototype.setYAxis=function(axis,index){index=void 0===index?0:index,this._validateAxis("y",axis,index),this._yaxes[index]=axis},Base.prototype._validateAxis=function(xy,axis,index){if((index=void 0===index?0:index)>0&&void 0===("x"==xy?this._xaxes:this._yaxes)[index-1])throw new Error("Missing "+xy+" axis at index lower than "+index)},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.");if(this._labels.length&&this._labels.length!=series.getCount())throw new Error("Series must match label values.")},Base}));
|
||||
define("core/chart_base",["core/chart_series","core/chart_axis"],(function(Series,Axis){function Base(){this._series=[],this._labels=[],this._xaxes=[],this._yaxes=[],this._setDefaults()}return Base.prototype._series=null,Base.prototype._labels=null,Base.prototype._legendOptions=null,Base.prototype._title=null,Base.prototype._xaxes=null,Base.prototype._yaxes=null,Base.prototype.COLORSET=["#f3c300","#875692","#f38400","#a1caf1","#be0032","#c2b280","#7f180d","#008856","#e68fac","#0067a5"],Base.prototype._configColorSet=null,Base.prototype.TYPE=null,Base.prototype._responsiveOptions=null,Base.prototype.addSeries=function(series){if(this._validateSeries(series),this._series.push(series),null===series.getColor()){var configColorSet=this.getConfigColorSet()||Base.prototype.COLORSET;series.setColor(configColorSet[this._series.length%configColorSet.length])}},Base.prototype.create=function(Klass,data){var Chart=new Klass;return Chart.setConfigColorSet(data.config_colorset),Chart.setLabels(data.labels),Chart.setTitle(data.title),data.legend_options&&Chart.setLegendOptions(data.legend_options),data.responsive_options&&Chart.setResponsiveOptions(data.responsive_options),data.series.forEach((function(seriesData){Chart.addSeries(Series.prototype.create(seriesData))})),data.axes.x.forEach((function(axisData,i){Chart.setXAxis(Axis.prototype.create(axisData),i)})),data.axes.y.forEach((function(axisData,i){Chart.setYAxis(Axis.prototype.create(axisData),i)})),Chart},Base.prototype.__getAxis=function(xy,index,createIfNotExists){var axis,axes="x"===xy?this._xaxes:this._yaxes,setAxis=("x"===xy?this.setXAxis:this.setYAxis).bind(this);if(createIfNotExists=void 0!==createIfNotExists&&createIfNotExists,void 0===(axis=axes[index=void 0===index?0:index])){if(!createIfNotExists)throw new Error("Unknown axis.");setAxis(axis=new Axis,index)}return axis},Base.prototype.getConfigColorSet=function(){return this._configColorSet},Base.prototype.getLabels=function(){return this._labels},Base.prototype.getLegendOptions=function(){return this._legendOptions},Base.prototype.getSeries=function(){return this._series},Base.prototype.getTitle=function(){return this._title},Base.prototype.getType=function(){if(!this.TYPE)throw new Error("The TYPE property has not been set.");return this.TYPE},Base.prototype.getXAxes=function(){return this._xaxes},Base.prototype.getXAxis=function(index,createIfNotExists){return this.__getAxis("x",index,createIfNotExists)},Base.prototype.getYAxes=function(){return this._yaxes},Base.prototype.getYAxis=function(index,createIfNotExists){return this.__getAxis("y",index,createIfNotExists)},Base.prototype.getResponsiveOptions=function(){return this._responsiveOptions},Base.prototype.setConfigColorSet=function(colorset){this._configColorSet=colorset},Base.prototype._setDefaults=function(){},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.");this._labels=labels},Base.prototype.setLegendOptions=function(legendOptions){if("object"!=typeof legendOptions)throw new Error("Setting legend with non-object value:"+legendOptions);this._legendOptions=legendOptions},Base.prototype.setTitle=function(title){this._title=title},Base.prototype.setXAxis=function(axis,index){index=void 0===index?0:index,this._validateAxis("x",axis,index),this._xaxes[index]=axis},Base.prototype.setYAxis=function(axis,index){index=void 0===index?0:index,this._validateAxis("y",axis,index),this._yaxes[index]=axis},Base.prototype.setResponsiveOptions=function(responsiveOptions){if("object"!=typeof responsiveOptions)throw new Error("Setting responsive options with non-object value:"+responsiveOptions);this._responsiveOptions=responsiveOptions},Base.prototype._validateAxis=function(xy,axis,index){if((index=void 0===index?0:index)>0&&void 0===("x"==xy?this._xaxes:this._yaxes)[index-1])throw new Error("Missing "+xy+" axis at index lower than "+index)},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.");if(this._labels.length&&this._labels.length!=series.getCount())throw new Error("Series must match label values.")},Base}));
|
||||
|
||||
//# sourceMappingURL=chart_base.min.js.map
|
||||
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -114,6 +114,14 @@ define(['core/chart_series', 'core/chart_axis'], function(Series, Axis) {
|
||||
*/
|
||||
Base.prototype.TYPE = null;
|
||||
|
||||
/**
|
||||
* Options for chart responsiveness.
|
||||
*
|
||||
* @protected
|
||||
* @type {Object}
|
||||
*/
|
||||
Base.prototype._responsiveOptions = null;
|
||||
|
||||
/**
|
||||
* Add a series to the chart.
|
||||
*
|
||||
@@ -153,6 +161,9 @@ define(['core/chart_series', 'core/chart_axis'], function(Series, Axis) {
|
||||
if (data.legend_options) {
|
||||
Chart.setLegendOptions(data.legend_options);
|
||||
}
|
||||
if (data.responsive_options) {
|
||||
Chart.setResponsiveOptions(data.responsive_options);
|
||||
}
|
||||
data.series.forEach(function(seriesData) {
|
||||
Chart.addSeries(Series.prototype.create(seriesData));
|
||||
});
|
||||
@@ -292,6 +303,15 @@ define(['core/chart_series', 'core/chart_axis'], function(Series, Axis) {
|
||||
return this.__getAxis('y', index, createIfNotExists);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get responsive options for the chart.
|
||||
*
|
||||
* @return {Object}
|
||||
*/
|
||||
Base.prototype.getResponsiveOptions = function() {
|
||||
return this._responsiveOptions;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set colours defined by setting.
|
||||
*
|
||||
@@ -379,6 +399,18 @@ define(['core/chart_series', 'core/chart_axis'], function(Series, Axis) {
|
||||
this._yaxes[index] = axis;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set responsive options for chart.
|
||||
*
|
||||
* @param {Object} responsiveOptions
|
||||
*/
|
||||
Base.prototype.setResponsiveOptions = function(responsiveOptions) {
|
||||
if (typeof responsiveOptions !== 'object') {
|
||||
throw new Error('Setting responsive options with non-object value:' + responsiveOptions);
|
||||
}
|
||||
this._responsiveOptions = responsiveOptions;
|
||||
};
|
||||
|
||||
/**
|
||||
* Validate an axis.
|
||||
*
|
||||
|
||||
@@ -222,6 +222,17 @@ define([
|
||||
config.options.plugins.legend = legendOptions;
|
||||
}
|
||||
|
||||
var responsiveOptions = this._chart.getResponsiveOptions();
|
||||
if (responsiveOptions) {
|
||||
// Possible values to be changed in the properties related to the chart's responsiveness.
|
||||
const responsiveProperties = ['aspectRatio', 'maintainAspectRatio', 'responsive', 'resizeDelay'];
|
||||
for (const key of responsiveProperties) {
|
||||
const value = responsiveOptions[key];
|
||||
if (value !== null && value !== undefined) {
|
||||
config.options[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this._chart.getXAxes().forEach(function(axis, i) {
|
||||
var axisLabels = axis.getLabels();
|
||||
|
||||
@@ -50,6 +50,8 @@ class chart_base implements JsonSerializable, renderable {
|
||||
protected $yaxes = [];
|
||||
/** @var array Options for the chart legend. */
|
||||
protected $legendoptions = [];
|
||||
/** @var array Options for the chart responsiveness. */
|
||||
protected $responsiveoptions = [];
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
@@ -89,6 +91,7 @@ class chart_base implements JsonSerializable, renderable {
|
||||
'y' => $this->yaxes,
|
||||
],
|
||||
'legend_options' => !empty($this->legendoptions) ? $this->legendoptions : null,
|
||||
'responsive_options' => !empty($this->responsiveoptions) ? $this->responsiveoptions : null,
|
||||
'config_colorset' => !empty($CFG->chart_colorset) ? $CFG->chart_colorset : null
|
||||
];
|
||||
}
|
||||
@@ -211,6 +214,15 @@ class chart_base implements JsonSerializable, renderable {
|
||||
return $this->get_axis('y', $index, $createifnotexists);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of responsive options for the chart.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_responsive_options() {
|
||||
return $this->responsiveoptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the defaults for this chart type.
|
||||
*
|
||||
@@ -282,6 +294,16 @@ class chart_base implements JsonSerializable, renderable {
|
||||
return $this->yaxes[$index] = $axis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set responsive options for the chart.
|
||||
* See https://www.chartjs.org/docs/latest/configuration/responsive.html for options.
|
||||
*
|
||||
* @param array $responsiveoptions Whether or not to display the chart extra options.
|
||||
*/
|
||||
public function set_responsive_options(array $responsiveoptions) {
|
||||
$this->responsiveoptions = $responsiveoptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate an axis.
|
||||
*
|
||||
|
||||
@@ -54,6 +54,7 @@ $chart3->set_title('TENSIONED LINES CHART');
|
||||
$chart3->add_series($sales);
|
||||
$chart3->add_series($expenses);
|
||||
$chart3->set_labels($labels);
|
||||
$chart3->set_responsive_options(['aspectRatio' => 2, 'maintainAspectRatio' => true, 'resizeDelay' => 1]);
|
||||
|
||||
$chart4 = new \core\chart_line();
|
||||
$chart4->set_smooth(true);
|
||||
|
||||
Reference in New Issue
Block a user