New weight option for pie and doughnut charts (#5951)

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.
This commit is contained in:
Vincent-Ip 2019-02-27 17:06:54 -05:00 committed by Simon Brunel
parent 79fc340514
commit 93f4e6e4e8
6 changed files with 140 additions and 4 deletions

View 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.

View 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);
}
});

View File

@ -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
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View File

@ -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 not shown.

After

Width:  |  Height:  |  Size: 28 KiB