Skip to content

Commit

Permalink
New weight option for pie and doughnut charts (#5951)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Vincent-Ip authored and simonbrunel committed Feb 27, 2019
1 parent 79fc340 commit 93f4e6e
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 4 deletions.
2 changes: 2 additions & 0 deletions docs/charts/doughnut.md
Expand Up @@ -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

Expand All @@ -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.

Expand Down
40 changes: 36 additions & 4 deletions src/controllers/controller.doughnut.js
Expand Up @@ -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: {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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);
}
});
50 changes: 50 additions & 0 deletions test/fixtures/controller.doughnut/doughnut-weight.json
@@ -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
}
}
}
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
52 changes: 52 additions & 0 deletions test/fixtures/controller.doughnut/pie-weight.json
@@ -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
}
}
}
Binary file added test/fixtures/controller.doughnut/pie-weight.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 93f4e6e

Please sign in to comment.