From 357ec2d5845ad5716efb3b1221069f5a017e1962 Mon Sep 17 00:00:00 2001 From: Frederic Massart Date: Mon, 20 Jun 2016 19:12:43 +0800 Subject: [PATCH] MDL-54987 core: New charting API --- lib/amd/build/chart_bar.min.js | 1 + lib/amd/build/chart_base.min.js | 1 + lib/amd/build/chart_builder.min.js | 1 + lib/amd/build/chart_line.min.js | 1 + lib/amd/build/chart_output.min.js | 1 + lib/amd/build/chart_output_base.min.js | 1 + lib/amd/build/chart_output_chartjs.min.js | 1 + lib/amd/build/chart_pie.min.js | 1 + lib/amd/build/chart_series.min.js | 1 + lib/amd/src/chart_bar.js | 37 +++++++++ lib/amd/src/chart_base.js | 91 ++++++++++++++++++++++ lib/amd/src/chart_builder.js | 38 +++++++++ lib/amd/src/chart_line.js | 37 +++++++++ lib/amd/src/chart_output.js | 29 +++++++ lib/amd/src/chart_output_base.js | 44 +++++++++++ lib/amd/src/chart_output_chartjs.js | 77 +++++++++++++++++++ lib/amd/src/chart_pie.js | 44 +++++++++++ lib/amd/src/chart_series.js | 94 +++++++++++++++++++++++ lib/classes/chart_bar.php | 36 +++++++++ lib/classes/chart_base.php | 76 ++++++++++++++++++ lib/classes/chart_line.php | 36 +++++++++ lib/classes/chart_pie.php | 36 +++++++++ lib/classes/chart_series.php | 88 +++++++++++++++++++++ lib/outputrenderers.php | 50 ++++++++++++ 24 files changed, 822 insertions(+) create mode 100644 lib/amd/build/chart_bar.min.js create mode 100644 lib/amd/build/chart_base.min.js create mode 100644 lib/amd/build/chart_builder.min.js create mode 100644 lib/amd/build/chart_line.min.js create mode 100644 lib/amd/build/chart_output.min.js create mode 100644 lib/amd/build/chart_output_base.min.js create mode 100644 lib/amd/build/chart_output_chartjs.min.js create mode 100644 lib/amd/build/chart_pie.min.js create mode 100644 lib/amd/build/chart_series.min.js create mode 100644 lib/amd/src/chart_bar.js create mode 100644 lib/amd/src/chart_base.js create mode 100644 lib/amd/src/chart_builder.js create mode 100644 lib/amd/src/chart_line.js create mode 100644 lib/amd/src/chart_output.js create mode 100644 lib/amd/src/chart_output_base.js create mode 100644 lib/amd/src/chart_output_chartjs.js create mode 100644 lib/amd/src/chart_pie.js create mode 100644 lib/amd/src/chart_series.js create mode 100644 lib/classes/chart_bar.php create mode 100644 lib/classes/chart_base.php create mode 100644 lib/classes/chart_line.php create mode 100644 lib/classes/chart_pie.php create mode 100644 lib/classes/chart_series.php diff --git a/lib/amd/build/chart_bar.min.js b/lib/amd/build/chart_bar.min.js new file mode 100644 index 00000000000..6083d244bdb --- /dev/null +++ b/lib/amd/build/chart_bar.min.js @@ -0,0 +1 @@ +define(["core/chart_base"],function(a){function b(){a.prototype.constructor.apply(this,arguments)}return b.prototype=Object.create(a.prototype),b.prototype.TYPE="bar",b}); \ No newline at end of file diff --git a/lib/amd/build/chart_base.min.js b/lib/amd/build/chart_base.min.js new file mode 100644 index 00000000000..9da29808ea8 --- /dev/null +++ b/lib/amd/build/chart_base.min.js @@ -0,0 +1 @@ +define(["core/chart_series"],function(a){function b(){this._series=[],this._labels=[]}return b.prototype._series=null,b.prototype._labels=null,b.prototype.COLORSET=["red","green","blue","yellow","pink","orange"],b.prototype.TYPE=null,b.prototype.addSeries=function(a){this._validateSerie(a),this._series.push(a),null===a.getColor()&&a.setColor(b.prototype.COLORSET[this._series.length%b.prototype.COLORSET.length])},b.prototype.create=function(b,c){var d=new b;d.setLabels(c.labels);for(var e=0;e=1)throw new Error("Pie charts only support one serie.");return a.prototype._validateSerie.apply(this,arguments)},b}); \ No newline at end of file diff --git a/lib/amd/build/chart_series.min.js b/lib/amd/build/chart_series.min.js new file mode 100644 index 00000000000..5723224d57a --- /dev/null +++ b/lib/amd/build/chart_series.min.js @@ -0,0 +1 @@ +define([],function(){function a(a,b){if("string"!=typeof a)throw new Error("Invalid label for series.");if("object"!=typeof b)throw new Error("Values for a series must be an array.");if(b.length<1)throw new Error("Invalid values received for series.");this._label=a,this._values=b}return a.prototype.TYPE_DEFAULT=null,a.prototype.TYPE_LINE="line",a.prototype._color=null,a.prototype._label=null,a.prototype._type=a.prototype.TYPE_DEFAULT,a.prototype._values=null,a.prototype.create=function(b){var c=new a(b.label,b.values);return c.setColor(b.color),c.setType(b.type),c},a.prototype.getColor=function(){return this._color},a.prototype.getCount=function(){return this._values.length},a.prototype.getLabel=function(){return this._label},a.prototype.getType=function(){return this._type},a.prototype.getValues=function(){return this._values},a.prototype.setColor=function(a){this._color=a||null},a.prototype.setType=function(a){if(a!=this.TYPE_DEFAULT&&a!=this.TYPE_LINE)throw new Error("Invalid serie type.");this._type=a||null},a}); \ No newline at end of file diff --git a/lib/amd/src/chart_bar.js b/lib/amd/src/chart_bar.js new file mode 100644 index 00000000000..e1e118a2c87 --- /dev/null +++ b/lib/amd/src/chart_bar.js @@ -0,0 +1,37 @@ +// This file is part of Moodle - http://moodle.org/ +// +// Moodle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Moodle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Moodle. If not, see . + +/** + * Chart bar. + * + * @package core + * @copyright 2016 Frédéric Massart - FMCorz.net + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +define(['core/chart_base'], function(Base) { + + /** + * Bar chart. + */ + function Bar() { + Base.prototype.constructor.apply(this, arguments); + } + Bar.prototype = Object.create(Base.prototype); + + Bar.prototype.TYPE = 'bar'; + + return Bar; + +}); diff --git a/lib/amd/src/chart_base.js b/lib/amd/src/chart_base.js new file mode 100644 index 00000000000..bacf6bcbe4d --- /dev/null +++ b/lib/amd/src/chart_base.js @@ -0,0 +1,91 @@ +// This file is part of Moodle - http://moodle.org/ +// +// Moodle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Moodle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Moodle. If not, see . + +/** + * Chart base. + * + * @package core + * @copyright 2016 Frédéric Massart - FMCorz.net + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +define(['core/chart_series'], function(Series) { + + /** + * Chart base. + */ + function Base() { + this._series = []; + this._labels = []; + } + Base.prototype._series = null; + Base.prototype._labels = null; + Base.prototype.COLORSET = ['red', 'green', 'blue', 'yellow', 'pink', 'orange']; + Base.prototype.TYPE = null; + + Base.prototype.addSeries = function(serie) { + this._validateSerie(serie); + this._series.push(serie); + + // Give a default color from the set. + if (serie.getColor() === null) { + serie.setColor(Base.prototype.COLORSET[this._series.length % Base.prototype.COLORSET.length]); + } + }; + + 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(). + var Chart = new Klass(); + Chart.setLabels(data.labels); + for (var i = 0; i < data.series.length; i++) { + Chart.addSeries(Series.prototype.create(data.series[i])); + } + return Chart; + }; + + Base.prototype.getLabels = function() { + return this._labels; + }; + + Base.prototype.getSeries = function() { + return this._series; + }; + + Base.prototype.getType = function() { + if (!this.TYPE) { + throw new Error('The TYPE property has not been set.'); + } + return this.TYPE; + }; + + 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._validateSerie = function(serie) { + if (this._series.length && this._series[0].getCount() != serie.getCount()) { + throw new Error('Series do not have an equal number of values.'); + + } else if (this._labels.length && this._labels.length != serie.getCount()) { + throw new Error('Series must match label values.'); + } + }; + + return Base; + +}); diff --git a/lib/amd/src/chart_builder.js b/lib/amd/src/chart_builder.js new file mode 100644 index 00000000000..44553e25b39 --- /dev/null +++ b/lib/amd/src/chart_builder.js @@ -0,0 +1,38 @@ +// This file is part of Moodle - http://moodle.org/ +// +// Moodle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Moodle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Moodle. If not, see . + +/** + * 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 { + make: function(data) { + var deferred = $.Deferred(); + require(['core/chart_' + data.type], function(Klass) { + var instance = Klass.prototype.create(Klass, data); + deferred.resolve(instance); + }); + return deferred.promise(); + } + }; + +}); diff --git a/lib/amd/src/chart_line.js b/lib/amd/src/chart_line.js new file mode 100644 index 00000000000..a4351c91614 --- /dev/null +++ b/lib/amd/src/chart_line.js @@ -0,0 +1,37 @@ +// This file is part of Moodle - http://moodle.org/ +// +// Moodle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Moodle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Moodle. If not, see . + +/** + * Chart line. + * + * @package core + * @copyright 2016 Frédéric Massart - FMCorz.net + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +define(['core/chart_base'], function(Base) { + + /** + * Line chart. + */ + function Line() { + Base.prototype.constructor.apply(this, arguments); + } + Line.prototype = Object.create(Base.prototype); + + Line.prototype.TYPE = 'line'; + + return Line; + +}); diff --git a/lib/amd/src/chart_output.js b/lib/amd/src/chart_output.js new file mode 100644 index 00000000000..b7d947729f2 --- /dev/null +++ b/lib/amd/src/chart_output.js @@ -0,0 +1,29 @@ +// This file is part of Moodle - http://moodle.org/ +// +// Moodle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Moodle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Moodle. If not, see . + +/** + * Chart output. + * + * Proxy to the default output module. + * + * @package core + * @copyright 2016 Frédéric Massart - FMCorz.net + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +define(['core/chart_output_chartjs'], function(Output) { + + return Output; + +}); diff --git a/lib/amd/src/chart_output_base.js b/lib/amd/src/chart_output_base.js new file mode 100644 index 00000000000..91c6ae5c4cd --- /dev/null +++ b/lib/amd/src/chart_output_base.js @@ -0,0 +1,44 @@ +// This file is part of Moodle - http://moodle.org/ +// +// Moodle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Moodle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Moodle. If not, see . + +/** + * Chart output base. + * + * This takes a chart object and draws it. + * + * @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($) { + + /** + * Chart output base. + * + * @param {Node} node The node to output with/in. + * @param {Chart} chart A chart object. + */ + function Base(node, chart) { + this._node = $(node); + this._chart = chart; + } + + Base.prototype.update = function() { + throw new Error('Not supported.'); + }; + + return Base; + +}); diff --git a/lib/amd/src/chart_output_chartjs.js b/lib/amd/src/chart_output_chartjs.js new file mode 100644 index 00000000000..34fa32eb7b8 --- /dev/null +++ b/lib/amd/src/chart_output_chartjs.js @@ -0,0 +1,77 @@ +// This file is part of Moodle - http://moodle.org/ +// +// Moodle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Moodle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Moodle. If not, see . + +/** + * Chart output for chart.js. + * + * @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', 'core/chartjs', 'core/chart_output_base'], function($, Chartjs, Base) { + + /** + * Chart output for Chart.js. + */ + function Output() { + Base.prototype.constructor.apply(this, arguments); + this._build(); + } + + Output.prototype = Object.create(Base.prototype); + + Output.prototype._config = null; + Output.prototype._chartjs = 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; + }; + + Output.prototype._build = function() { + this._config = this._makeConfig(); + this._chartjs = new Chartjs(this._node[0], this._config); + }; + + Output.prototype._makeConfig = function() { + var config = { + type: this._chart.getType(), + data: { + labels: this._chart.getLabels(), + datasets: this.getDatasets() + }, + options: { + } + }; + return config; + }; + + Output.prototype.update = function() { + $.extend(true, this._config, this._makeConfig()); + this._chartjs.update(); + }; + + return Output; + +}); diff --git a/lib/amd/src/chart_pie.js b/lib/amd/src/chart_pie.js new file mode 100644 index 00000000000..8325520eafb --- /dev/null +++ b/lib/amd/src/chart_pie.js @@ -0,0 +1,44 @@ +// This file is part of Moodle - http://moodle.org/ +// +// Moodle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Moodle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Moodle. If not, see . + +/** + * Chart pie. + * + * @package core + * @copyright 2016 Frédéric Massart - FMCorz.net + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +define(['core/chart_base'], function(Base) { + + /** + * Pie chart. + */ + function Pie() { + Base.prototype.constructor.apply(this, arguments); + } + Pie.prototype = Object.create(Base.prototype); + + Pie.prototype.TYPE = 'pie'; + + Pie.prototype._validateSerie = function() { + if (this._series.length >= 1) { + throw new Error('Pie charts only support one serie.'); + } + return Base.prototype._validateSerie.apply(this, arguments); + }; + + return Pie; + +}); diff --git a/lib/amd/src/chart_series.js b/lib/amd/src/chart_series.js new file mode 100644 index 00000000000..9df3176db97 --- /dev/null +++ b/lib/amd/src/chart_series.js @@ -0,0 +1,94 @@ +// This file is part of Moodle - http://moodle.org/ +// +// Moodle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Moodle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Moodle. If not, see . + +/** + * Chart series. + * + * @package core + * @copyright 2016 Frédéric Massart - FMCorz.net + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +define([], function() { + + /** + * Chart data series. + * + * @param {String} label The series label. + * @param {Number[]} values The values. + */ + function Series(label, values) { + if (typeof label !== 'string') { + throw new Error('Invalid label for series.'); + + } else if (typeof values !== 'object') { + throw new Error('Values for a series must be an array.'); + + } else if (values.length < 1) { + throw new Error('Invalid values received for series.'); + } + + this._label = label; + this._values = values; + } + + Series.prototype.TYPE_DEFAULT = null; + Series.prototype.TYPE_LINE = 'line'; + + Series.prototype._color = null; + Series.prototype._label = null; + Series.prototype._type = Series.prototype.TYPE_DEFAULT; + Series.prototype._values = null; + + Series.prototype.create = function(obj) { + var s = new Series(obj.label, obj.values); + s.setColor(obj.color); + s.setType(obj.type); + return s; + }; + + Series.prototype.getColor = function() { + return this._color; + }; + + Series.prototype.getCount = function() { + return this._values.length; + }; + + Series.prototype.getLabel = function() { + return this._label; + }; + + Series.prototype.getType = function() { + return this._type; + }; + + Series.prototype.getValues = function() { + return this._values; + }; + + Series.prototype.setColor = function(color) { + this._color = color || null; + }; + + Series.prototype.setType = function(type) { + if (type != this.TYPE_DEFAULT && type != this.TYPE_LINE) { + throw new Error('Invalid serie type.'); + } + this._type = type || null; + }; + + return Series; + +}); diff --git a/lib/classes/chart_bar.php b/lib/classes/chart_bar.php new file mode 100644 index 00000000000..ddaa8560ecb --- /dev/null +++ b/lib/classes/chart_bar.php @@ -0,0 +1,36 @@ +. + +/** + * Chart bar. + * + * @package core + * @copyright 2016 Frédéric Massart - FMCorz.net + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace core; +defined('MOODLE_INTERNAL') || die(); + +/** + * Chart bar class. + * + * @package core + * @copyright 2016 Frédéric Massart - FMCorz.net + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class chart_bar extends chart_base { +} diff --git a/lib/classes/chart_base.php b/lib/classes/chart_base.php new file mode 100644 index 00000000000..38c3bf2a0bd --- /dev/null +++ b/lib/classes/chart_base.php @@ -0,0 +1,76 @@ +. + +/** + * Chart base. + * + * @package core + * @copyright 2016 Frédéric Massart - FMCorz.net + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace core; +defined('MOODLE_INTERNAL') || die(); + +use coding_exception; +use JsonSerializable; +use renderable; + +/** + * Chart base class. + * + * @package core + * @copyright 2016 Frédéric Massart - FMCorz.net + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class chart_base implements JsonSerializable, renderable { + + protected $series = []; + protected $labels = []; + + public function __construct() { + } + + public function add_series(chart_series $serie) { + $this->series[] = $serie; + } + + public function jsonSerialize() { + return [ + 'type' => $this->get_type(), + 'series' => $this->series, + 'labels' => $this->labels + ]; + } + + public function get_labels() { + return $this->labels; + } + + public function get_series() { + return $this->series; + } + + public function get_type() { + $classname = get_class($this); + return substr($classname, strpos($classname, '_') + 1); + } + + public function set_labels(array $labels) { + $this->labels = $labels; + } + +} diff --git a/lib/classes/chart_line.php b/lib/classes/chart_line.php new file mode 100644 index 00000000000..82f4f46b9da --- /dev/null +++ b/lib/classes/chart_line.php @@ -0,0 +1,36 @@ +. + +/** + * Chart line. + * + * @package core + * @copyright 2016 Frédéric Massart - FMCorz.net + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace core; +defined('MOODLE_INTERNAL') || die(); + +/** + * Chart line class. + * + * @package core + * @copyright 2016 Frédéric Massart - FMCorz.net + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class chart_line extends chart_base { +} diff --git a/lib/classes/chart_pie.php b/lib/classes/chart_pie.php new file mode 100644 index 00000000000..32745badba8 --- /dev/null +++ b/lib/classes/chart_pie.php @@ -0,0 +1,36 @@ +. + +/** + * Chart pie. + * + * @package core + * @copyright 2016 Frédéric Massart - FMCorz.net + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace core; +defined('MOODLE_INTERNAL') || die(); + +/** + * Chart pie class. + * + * @package core + * @copyright 2016 Frédéric Massart - FMCorz.net + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class chart_pie extends chart_base { +} diff --git a/lib/classes/chart_series.php b/lib/classes/chart_series.php new file mode 100644 index 00000000000..ccc383ab4f3 --- /dev/null +++ b/lib/classes/chart_series.php @@ -0,0 +1,88 @@ +. + +/** + * Chart series. + * + * @package core + * @copyright 2016 Frédéric Massart - FMCorz.net + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace core; +defined('MOODLE_INTERNAL') || die(); + +use coding_exception; +use JsonSerializable; + +/** + * Chart series class. + * + * @package core + * @copyright 2016 Frédéric Massart - FMCorz.net + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class chart_series implements JsonSerializable { + + const TYPE_DEFAULT = null; + const TYPE_LINE = 'line'; + + protected $label; + protected $type = self::TYPE_DEFAULT; + protected $values = []; + + public function __construct($label, $values) { + $this->values = $values; + $this->label = $label; + } + + public function get_count() { + return count($this->values); + } + + public function get_label() { + return $this->label; + } + + public function get_type() { + return $this->type; + } + + public function get_values() { + return $this->values; + } + + public function jsonSerialize() { + $data = [ + 'label' => $this->label, + 'type' => $this->type, + 'values' => $this->values + ]; + return $data; + } + + public function set_color($color) { + $this->color = $color; + } + + public function set_type($type) { + if (!in_array($type, [self::TYPE_DEFAULT, self::TYPE_LINE])) { + throw new coding_exception('Invalid serie type.'); + } + $this->type = $type; + } + +} diff --git a/lib/outputrenderers.php b/lib/outputrenderers.php index d0d5b2327db..65212d7c9dd 100644 --- a/lib/outputrenderers.php +++ b/lib/outputrenderers.php @@ -4280,6 +4280,56 @@ EOD; public function render_inplace_editable(\core\output\inplace_editable $element) { return $this->render_from_template('core/inplace_editable', $element->export_for_template($this)); } + + /** + * Renders a bar chart. + * + * @param \core\chart_bar $chart The chart. + * @return string. + */ + public function render_chart_bar(\core\chart_bar $chart) { + return $this->render_chart($chart); + } + + /** + * Renders a line chart. + * + * @param \core\chart_line $chart The chart. + * @return string. + */ + public function render_chart_line(\core\chart_line $chart) { + return $this->render_chart($chart); + } + + /** + * Renders a pie chart. + * + * @param \core\chart_pie $chart The chart. + * @return string. + */ + public function render_chart_pie(\core\chart_pie $chart) { + return $this->render_chart($chart); + } + + /** + * Renders a chart. + * + * @param \core\chart_base $chart The chart. + * @return string. + */ + public function render_chart(\core\chart_base $chart) { + $id = 'chart' . uniqid(); + // TODO Handle the canvas in the output module rather than here. + $canvas = html_writer::tag('canvas', '', ['id' => $id]); + $js = "require(['core/chart_builder', 'core/chart_output'], function(Builder, Output) { + Builder.make(" . json_encode($chart) . ").then(function(ChartInst) { + new Output('#" . $id . "', ChartInst); + }); + });"; + $this->page->requires->js_init_code($js, true); + return $canvas; + } + } /**