MDL-55038 core: Support multiple colours in the same series
authorFrederic Massart <fred@moodle.com>
Tue, 5 Jul 2016 10:29:18 +0000 (18:29 +0800)
committerDan Poltawski <dan@moodle.com>
Mon, 25 Jul 2016 09:43:06 +0000 (10:43 +0100)
Part of MDL-54987 epic.

lib/amd/build/chart_output_chartjs.min.js
lib/amd/build/chart_pie.min.js
lib/amd/build/chart_series.min.js
lib/amd/src/chart_output_chartjs.js
lib/amd/src/chart_pie.js
lib/amd/src/chart_series.js
lib/classes/chart_series.php

index 0acc1c9..a9dfb53 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 ea900bd..ff55da7 100644 (file)
Binary files a/lib/amd/build/chart_pie.min.js and b/lib/amd/build/chart_pie.min.js differ
index 5723224..b74b9d9 100644 (file)
Binary files a/lib/amd/build/chart_series.min.js and b/lib/amd/build/chart_series.min.js differ
index 775589a..faa9b3e 100644 (file)
@@ -26,7 +26,8 @@ define([
     'core/chartjs',
     'core/chart_axis',
     'core/chart_output_base',
-], function($, Chartjs, Axis, Base) {
+    'core/chart_pie',
+], function($, Chartjs, Axis, Base, Pie) {
 
     /**
      * Chart output for Chart.js.
@@ -175,15 +176,17 @@ define([
      */
     Output.prototype._makeDatasetsConfig = function() {
         var sets = this._chart.getSeries().map(function(series) {
+            var colors = series.hasColoredValues() ? series.getColors() : series.getColor();
             return {
                 label: series.getLabel(),
                 data: series.getValues(),
                 type: series.getType(),
                 fill: false,
-                borderColor: series.getColor(),
-                backgroundColor: series.getColor()
+                backgroundColor: colors,
+                // Pie charts look better without borders.
+                borderColor: this._chart.getType() == Pie.prototype.TYPE ? null : colors
             };
-        });
+        }.bind(this));
         return sets;
     };
 
index 57756df..7e73905 100644 (file)
@@ -38,6 +38,22 @@ define(['core/chart_base'], function(Base) {
     /** @override */
     Pie.prototype.TYPE = 'pie';
 
+    /**
+     * Overridden to add appropriate colors to the series.
+     *
+     * @override
+     */
+    Pie.prototype.addSeries = function(series) {
+        if (series.getColor() === null) {
+            var colors = [];
+            for (var i = 0; i < series.getCount(); i++) {
+                colors.push(this.COLORSET[i % Base.prototype.COLORSET.length]);
+            }
+            series.setColors(colors);
+        }
+        return Base.prototype.addSeries.apply(this, arguments);
+    };
+
     /**
      * Validate a series.
      *
index 73f827a..e6b3e24 100644 (file)
@@ -42,6 +42,7 @@ define([], function() {
             throw new Error('Invalid values received for series.');
         }
 
+        this._colors = [];
         this._label = label;
         this._values = values;
     }
@@ -63,12 +64,12 @@ define([], function() {
     Series.prototype.TYPE_LINE = 'line';
 
     /**
-     * The color of the series.
+     * The colors of the series.
      *
-     * @type {String}
+     * @type {String[]}
      * @protected
      */
-    Series.prototype._color = null;
+    Series.prototype._colors = null;
 
     /**
      * The label of the series.
@@ -104,8 +105,15 @@ define([], function() {
      */
     Series.prototype.create = function(obj) {
         var s = new Series(obj.label, obj.values);
-        s.setColor(obj.color);
         s.setType(obj.type);
+
+        // Colors are exported as an array with 1, or n values.
+        if (obj.colors && obj.colors.length > 1) {
+            s.setColors(obj.colors);
+        } else {
+            s.setColor(obj.colors[0]);
+        }
+
         return s;
     };
 
@@ -115,7 +123,16 @@ define([], function() {
      * @return {String}
      */
     Series.prototype.getColor = function() {
-        return this._color;
+        return this._colors[0] || null;
+    };
+
+    /**
+     * Get the colors for each value in the series.
+     *
+     * @return {String[]}
+     */
+    Series.prototype.getColors = function() {
+        return this._colors;
     };
 
     /**
@@ -154,13 +171,34 @@ define([], function() {
         return this._values;
     };
 
+    /**
+     * Whether there is a color per value.
+     *
+     * @return {Bool}
+     */
+    Series.prototype.hasColoredValues = function() {
+        return this._colors.length == this.getCount();
+    };
+
     /**
      * Set the series color.
      *
      * @param {String} color A CSS-compatible color.
      */
     Series.prototype.setColor = function(color) {
-        this._color = color || null;
+        this._colors = [color];
+    };
+
+    /**
+     * Set a color for each value in the series.
+     *
+     * @param {String[]} colors CSS-compatible colors.
+     */
+    Series.prototype.setColors = function(colors) {
+        if (colors && colors.length != this.getCount()) {
+            throw new Error('When setting multiple colors there must be one per value.');
+        }
+        this._colors = colors || [];
     };
 
     /**
index 4ac93ef..ae73b72 100644 (file)
@@ -42,8 +42,8 @@ class chart_series implements JsonSerializable {
     /** Series of type line. */
     const TYPE_LINE = 'line';
 
-    /** @var string Color of the series. */
-    protected $color;
+    /** @var string[] Colors of the series. */
+    protected $colors = [];
     /** @var string Label for this series. */
     protected $label;
     /** @var string Type of the series. */
@@ -65,10 +65,19 @@ class chart_series implements JsonSerializable {
     /**
      * Get the color.
      *
-     * @return string
+     * @return string|null
      */
     public function get_color() {
-        return $this->color;
+        return isset($this->color[0]) ? $this->color[0] : null;
+    }
+
+    /**
+     * Get the colors for each value in the series.
+     *
+     * @return string[]
+     */
+    public function get_colors() {
+        return $this->colors;
     }
 
     /**
@@ -101,12 +110,21 @@ class chart_series implements JsonSerializable {
     /**
      * Get the values of the series.
      *
-     * @return [type]
+     * @return string[]
      */
     public function get_values() {
         return $this->values;
     }
 
+    /**
+     * Whether there is a color per value.
+     *
+     * @return bool
+     */
+    public function has_colored_values() {
+        return count($this->colors) == $this->get_count();
+    }
+
     /**
      * Serialize the object.
      *
@@ -117,7 +135,7 @@ class chart_series implements JsonSerializable {
             'label' => $this->label,
             'type' => $this->type,
             'values' => $this->values,
-            'color' => $this->color,
+            'colors' => $this->colors,
         ];
         return $data;
     }
@@ -128,7 +146,16 @@ class chart_series implements JsonSerializable {
      * @param string $color CSS compatible color.
      */
     public function set_color($color) {
-        $this->color = $color;
+        $this->colors = [$color];
+    }
+
+    /**
+     * Set a color for each value in the series.
+     *
+     * @param string[] $colors CSS compatible colors.
+     */
+    public function set_colors(array $colors) {
+        $this->colors = $colors;
     }
 
     /**