]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
New weight option for pie and doughnut charts (#5951)
authorVincent-Ip <40588938+Vincent-Ip@users.noreply.github.com>
Wed, 27 Feb 2019 22:06:54 +0000 (17:06 -0500)
committerSimon Brunel <simonbrunel@users.noreply.github.com>
Wed, 27 Feb 2019 22:06:54 +0000 (23:06 +0100)
Add functionality to give pie & doughnut datasets a weight attribute, which affects the relative thickness of the dataset when there are multiple datasets in pie & doughnut charts. The default weight of each dataset is 1, providing any other numerical value will allow the pie or doughnut dataset to be drawn with a thickness relative to its default size.

For example a weight of 2 will allow the dataset to be drawn double its typical dataset thickness. Note that the weight attribute will only affect a pie or doughnut chart if there is more than one visible dataset. Using weight on a pie or doughnut dataset when there is only one dataset on the chart will have no affect.

docs/charts/doughnut.md
src/controllers/controller.doughnut.js
test/fixtures/controller.doughnut/doughnut-weight.json [new file with mode: 0644]
test/fixtures/controller.doughnut/doughnut-weight.png [new file with mode: 0644]
test/fixtures/controller.doughnut/pie-weight.json [new file with mode: 0644]
test/fixtures/controller.doughnut/pie-weight.png [new file with mode: 0644]

index ad1af3106ef2a96eb325db585178f83a810e8e8d..65c8767fa9ff6229fd3f2c2a89da4d0ddbb4b29f 100644 (file)
@@ -63,6 +63,7 @@ The doughnut/pie chart allows a number of properties to be specified for each da
 | [`hoverBackgroundColor`](#interations) | [`Color`](../general/colors.md) | Yes | Yes | `undefined`
 | [`hoverBorderColor`](#interactions) | [`Color`](../general/colors.md) | Yes | Yes | `undefined`
 | [`hoverBorderWidth`](#interactions) | `number` | Yes | Yes | `undefined`
+| [`weight`](#styling) | `number` | - | - | `1`
 
 ### Styling
 
@@ -73,6 +74,7 @@ The style of each arc can be controlled with the following properties:
 | `backgroundColor` | arc background color.
 | `borderColor` | arc border color.
 | `borderWidth` | arc border width (in pixels).
+| `weight` | The relative thickness of the dataset. Providing a value for weight will cause the pie or doughnut dataset to be drawn with a thickness relative to the sum of all the dataset weight values.
 
 All these values, if `undefined`, fallback to the associated [`elements.arc.*`](../configuration/elements.md#arc-configuration) options.
 
index 21e23ebcae8f5195a0b936deed9d85f94b45c70b..a6d4a63775a9093ec5a03df6b8d0bc11d4a2edec 100644 (file)
@@ -6,6 +6,7 @@ var elements = require('../elements/index');
 var helpers = require('../helpers/index');
 
 var resolve = helpers.options.resolve;
+var valueOrDefault = helpers.valueOrDefault;
 
 defaults._set('doughnut', {
        animation: {
@@ -152,6 +153,7 @@ module.exports = DatasetController.extend({
                var arcs = meta.data;
                var cutoutPercentage = opts.cutoutPercentage;
                var circumference = opts.circumference;
+               var chartWeight = me._getRingWeight(me.index);
                var i, ilen;
 
                // If the chart's circumference isn't a full circle, calculate minSize as a ratio of the width/height of the arc
@@ -180,14 +182,14 @@ module.exports = DatasetController.extend({
                chart.borderWidth = me.getMaxBorderWidth();
                chart.outerRadius = Math.max((minSize - chart.borderWidth) / 2, 0);
                chart.innerRadius = Math.max(cutoutPercentage ? (chart.outerRadius / 100) * (cutoutPercentage) : 0, 0);
-               chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount();
+               chart.radiusLength = (chart.outerRadius - chart.innerRadius) / (me._getVisibleDatasetWeightTotal() || 1);
                chart.offsetX = offset.x * chart.outerRadius;
                chart.offsetY = offset.y * chart.outerRadius;
 
                meta.total = me.calculateTotal();
 
-               me.outerRadius = chart.outerRadius - (chart.radiusLength * me.getRingIndex(me.index));
-               me.innerRadius = Math.max(me.outerRadius - chart.radiusLength, 0);
+               me.outerRadius = chart.outerRadius - chart.radiusLength * me._getRingWeightOffset(me.index);
+               me.innerRadius = Math.max(me.outerRadius - chart.radiusLength * chartWeight, 0);
 
                for (i = 0, ilen = arcs.length; i < ilen; ++i) {
                        me.updateElement(arcs[i], i, reset);
@@ -322,7 +324,6 @@ module.exports = DatasetController.extend({
                var model = arc._model;
                var options = arc._options;
                var getHoverColor = helpers.getHoverColor;
-               var valueOrDefault = helpers.valueOrDefault;
 
                arc.$previousStyle = {
                        backgroundColor: model.backgroundColor,
@@ -375,5 +376,36 @@ module.exports = DatasetController.extend({
                }
 
                return values;
+       },
+
+       /**
+        * Get radius length offset of the dataset in relation to the visible datasets weights. This allows determining the inner and outer radius correctly
+        * @private
+        */
+       _getRingWeightOffset: function(datasetIndex) {
+               var ringWeightOffset = 0;
+
+               for (var i = 0; i < datasetIndex; ++i) {
+                       if (this.chart.isDatasetVisible(i)) {
+                               ringWeightOffset += this._getRingWeight(i);
+                       }
+               }
+
+               return ringWeightOffset;
+       },
+
+       /**
+        * @private
+        */
+       _getRingWeight: function(dataSetIndex) {
+               return Math.max(valueOrDefault(this.chart.data.datasets[dataSetIndex].weight, 1), 0);
+       },
+
+       /**
+        * Returns the sum of all visibile data set weights.  This value can be 0.
+        * @private
+        */
+       _getVisibleDatasetWeightTotal: function() {
+               return this._getRingWeightOffset(this.chart.data.datasets.length);
        }
 });
diff --git a/test/fixtures/controller.doughnut/doughnut-weight.json b/test/fixtures/controller.doughnut/doughnut-weight.json
new file mode 100644 (file)
index 0000000..769814b
--- /dev/null
@@ -0,0 +1,50 @@
+{
+    "config": {
+        "type": "doughnut",
+        "data": {
+            "datasets": [{
+                "data": [ 1, 1 ],
+                "backgroundColor": [
+                    "rgba(255, 99, 132, 0.8)",
+                    "rgba(54, 162, 235, 0.8)"
+                ],
+                "borderWidth": 0
+            },
+            {
+                "data": [ 2, 1 ],
+                "hidden": true,
+                "borderWidth": 0
+            },
+            {
+                "data": [ 3, 3 ],
+                "weight": 3,
+                "backgroundColor": [
+                    "rgba(255, 206, 86, 0.8)",
+                    "rgba(75, 192, 192, 0.8)"
+                ],
+                "borderWidth": 0
+            },
+            {
+                "data": [ 4, 0 ],
+                "weight": 0,
+                "borderWidth": 0
+            },
+            {
+                "data": [ 5, 0 ],
+                "weight": -2,
+                "borderWidth": 0
+            }],
+            "labels": [ "label0", "label1" ]
+        },
+        "options": {
+            "legend": false,
+            "title": false
+        }
+    },
+    "options": {
+        "canvas": {
+            "height": 500,
+            "width": 500
+        }
+    }
+}
\ No newline at end of file
diff --git a/test/fixtures/controller.doughnut/doughnut-weight.png b/test/fixtures/controller.doughnut/doughnut-weight.png
new file mode 100644 (file)
index 0000000..d6ab34c
Binary files /dev/null and b/test/fixtures/controller.doughnut/doughnut-weight.png differ
diff --git a/test/fixtures/controller.doughnut/pie-weight.json b/test/fixtures/controller.doughnut/pie-weight.json
new file mode 100644 (file)
index 0000000..91d6c11
--- /dev/null
@@ -0,0 +1,52 @@
+{
+    "config": {
+        "type": "pie",
+        "data": {
+            "datasets": [
+                {
+                    "data": [ 1, 1 ],
+                    "backgroundColor": [
+                        "rgba(255, 99, 132, 0.8)",
+                        "rgba(54, 162, 235, 0.8)"
+                    ],
+                    "borderWidth": 0
+                },
+                {
+                    "data": [ 2, 1 ],
+                    "hidden": true,
+                    "borderWidth": 0
+                },
+                {
+                    "data": [ 3, 3 ],
+                    "weight": 3,
+                    "backgroundColor": [
+                        "rgba(255, 206, 86, 0.8)",
+                        "rgba(75, 192, 192, 0.8)"
+                    ],
+                    "borderWidth": 0
+                },
+                {
+                    "data": [ 4, 0 ],
+                    "weight": 0,
+                    "borderWidth": 0
+                },
+                {
+                    "data": [ 5, 0 ],
+                    "weight": -2,
+                    "borderWidth": 0
+                }
+            ],
+            "labels": [ "label0", "label1" ]
+        },
+        "options": {
+            "legend": false,
+            "title": false
+        }
+    },
+    "options": {
+        "canvas": {
+            "height": 500,
+            "width": 500
+        }
+    }
+}
\ No newline at end of file
diff --git a/test/fixtures/controller.doughnut/pie-weight.png b/test/fixtures/controller.doughnut/pie-weight.png
new file mode 100644 (file)
index 0000000..606ae0e
Binary files /dev/null and b/test/fixtures/controller.doughnut/pie-weight.png differ