Add outerRadius option to doughnut/pie (#8487)

This commit is contained in:
Jukka Kurkela 2021-02-22 00:30:37 +02:00 committed by GitHub
parent b27a4608cc
commit 65bfacd9a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 101 additions and 12 deletions

View File

@ -164,6 +164,7 @@ These are the customisation options specific to Pie & Doughnut charts. These opt
| Name | Type | Default | Description
| ---- | ---- | ------- | -----------
| `cutoutPercentage` | `number` | `50` - for doughnut, `0` - for pie | The percentage of the chart that is cut out of the middle.
| `outerRadius` | `number`\|`string` | `100%` | The outer radius of the chart. If `string` and ending with '%', percentage of the maximum radius. `number` is considered to be pixels.
| `rotation` | `number` | 0 | Starting angle to draw arcs from.
| `circumference` | `number` | 360 | Sweep to allow arcs to cover.
| `animation.animateRotate` | `boolean` | `true` | If true, the chart will animate in with a rotation animation. This property is in the `options.animation` object.

View File

@ -1,6 +1,6 @@
import DatasetController from '../core/core.datasetController';
import {formatNumber} from '../core/core.intl';
import {isArray, valueOrDefault} from '../helpers/helpers.core';
import {isArray, numberOrPercentageOf, valueOrDefault} from '../helpers/helpers.core';
import {toRadians, PI, TAU, HALF_PI} from '../helpers/helpers.math';
/**
@ -138,7 +138,8 @@ export default class DoughnutController extends DatasetController {
const spacing = me.getMaxBorderWidth() + me.getMaxOffset(arcs);
const maxWidth = (chartArea.right - chartArea.left - spacing) / ratioX;
const maxHeight = (chartArea.bottom - chartArea.top - spacing) / ratioY;
const outerRadius = Math.max(Math.min(maxWidth, maxHeight) / 2, 0);
const maxRadius = Math.max(Math.min(maxWidth, maxHeight) / 2, 0);
const outerRadius = numberOrPercentageOf(me.options.outerRadius, maxRadius);
const innerRadius = Math.max(outerRadius * cutout, 0);
const radiusLength = (outerRadius - innerRadius) / me._getVisibleDatasetWeightTotal();
me.offsetX = offsetX * outerRadius;
@ -350,7 +351,10 @@ DoughnutController.defaults = {
rotation: 0,
// The total circumference of the chart.
circumference: 360
circumference: 360,
// The outr radius of the chart
outerRadius: '100%'
},
indexAxis: 'r',

View File

@ -13,12 +13,15 @@ PieController.id = 'pie';
PieController.defaults = {
datasets: {
// The percentage of the chart that we cut out of the middle.
cutoutPercentage: 0,
cutout: 0,
// The rotation of the chart, where the first data arc begins.
rotation: 0,
// The total circumference of the chart.
circumference: 360
circumference: 360,
// The outr radius of the chart
outerRadius: '100%'
}
};

View File

@ -85,6 +85,11 @@ export function valueOrDefault(value, defaultValue) {
return typeof value === 'undefined' ? defaultValue : value;
}
export const numberOrPercentageOf = (value, dimension) =>
typeof value === 'string' && value.endsWith('%') ?
parseFloat(value) / 100 * dimension
: +value;
/**
* Calls `fn` with the given `args` in the scope defined by `thisArg` and returns the
* value returned by `fn`. If `fn` is not a function, this method returns undefined.

View File

@ -0,0 +1,28 @@
module.exports = {
config: {
type: 'doughnut',
data: {
labels: ['A', 'B', 'C', 'D', 'E'],
datasets: [{
data: [1, 5, 10, 50, 100],
backgroundColor: [
'rgba(255, 99, 132, 0.8)',
'rgba(54, 162, 235, 0.8)',
'rgba(255, 206, 86, 0.8)',
'rgba(75, 192, 192, 0.8)',
'rgba(153, 102, 255, 0.8)'
],
borderColor: [
'rgb(255, 99, 132)',
'rgb(54, 162, 235)',
'rgb(255, 206, 86)',
'rgb(75, 192, 192)',
'rgb(153, 102, 255)'
]
}]
},
options: {
outerRadius: '30%',
}
}
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -0,0 +1,28 @@
module.exports = {
config: {
type: 'doughnut',
data: {
labels: ['A', 'B', 'C', 'D', 'E'],
datasets: [{
data: [1, 5, 10, 50, 100],
backgroundColor: [
'rgba(255, 99, 132, 0.8)',
'rgba(54, 162, 235, 0.8)',
'rgba(255, 206, 86, 0.8)',
'rgba(75, 192, 192, 0.8)',
'rgba(153, 102, 255, 0.8)'
],
borderColor: [
'rgb(255, 99, 132)',
'rgb(54, 162, 235)',
'rgb(255, 206, 86)',
'rgb(75, 192, 192)',
'rgb(153, 102, 255)'
]
}]
},
options: {
outerRadius: 150,
}
}
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

20
types/index.esm.d.ts vendored
View File

@ -279,10 +279,22 @@ export interface DoughnutAnimationOptions {
export interface DoughnutControllerChartOptions {
/**
* Sweep to allow arcs to cover.
* @default 360
*/
circumference: number;
/**
* The percentage of the chart that is cut out of the middle. (50 - for doughnut, 0 - for pie)
* @default 50
*/
cutoutPercentage: number;
cutoutPercentage: number;
/**
* The outer radius of the chart. String ending with '%' means percentage of maximum radius, number means pixels.
* @default '100%'
*/
outerRadius: Scriptable<number | string, ScriptableContext<number>>;
/**
* Starting angle to draw arcs from.
@ -290,12 +302,6 @@ export interface DoughnutControllerChartOptions {
*/
rotation: number;
/**
* Sweep to allow arcs to cover.
* @default 360
*/
circumference: number;
animation: DoughnutAnimationOptions;
}

View File

@ -0,0 +1,14 @@
import { Chart } from '../../index.esm';
const chart = new Chart('id', {
type: 'doughnut',
data: {
labels: [],
datasets: [{
data: [],
}]
},
options: {
outerRadius: () => Math.random() > 0.5 ? 50 : '50%',
}
});