diff --git a/docs/charts/doughnut.md b/docs/charts/doughnut.md index ad1af3106ef..65c8767fa9f 100644 --- a/docs/charts/doughnut.md +++ b/docs/charts/doughnut.md @@ -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. diff --git a/src/controllers/controller.doughnut.js b/src/controllers/controller.doughnut.js index 21e23ebcae8..a6d4a63775a 100644 --- a/src/controllers/controller.doughnut.js +++ b/src/controllers/controller.doughnut.js @@ -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 index 00000000000..769814b0ccb --- /dev/null +++ b/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 + } + } +} \ 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 index 00000000000..d6ab34c8a9a 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 index 00000000000..91d6c110ba9 --- /dev/null +++ b/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 + } + } +} \ 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 index 00000000000..606ae0ebc59 Binary files /dev/null and b/test/fixtures/controller.doughnut/pie-weight.png differ