]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Add outerRadius option to doughnut/pie (#8487)
authorJukka Kurkela <jukka.kurkela@gmail.com>
Sun, 21 Feb 2021 22:30:37 +0000 (00:30 +0200)
committerGitHub <noreply@github.com>
Sun, 21 Feb 2021 22:30:37 +0000 (17:30 -0500)
docs/docs/charts/doughnut.mdx
src/controllers/controller.doughnut.js
src/controllers/controller.pie.js
src/helpers/helpers.core.js
test/fixtures/controller.doughnut/doughnut-outer-radius-percent.js [new file with mode: 0644]
test/fixtures/controller.doughnut/doughnut-outer-radius-percent.png [new file with mode: 0644]
test/fixtures/controller.doughnut/doughnut-outer-radius-pixels.js [new file with mode: 0644]
test/fixtures/controller.doughnut/doughnut-outer-radius-pixels.png [new file with mode: 0644]
types/index.esm.d.ts
types/tests/controllers/doughnut_outer_radius.ts [new file with mode: 0644]

index a9b929eb43560001e4beb5020a062998ff2f2c30..b2b69e30fd10b2b4b617d4e06787a68b8fbf9751 100644 (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.
index c283a266a656edaea7d1adeeeb04bbe87fd9040c..2f013c0cff87143383d5f737f7ca52b8108687e8 100644 (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',
index c88a3cbc3436b9e36760ca5e4bf683e6f443818c..f0162ef2d04269b7acc1b9f9ea47d4e8d3fbb07c 100644 (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%'
   }
 };
index 159c1335c4c9a76cc5d17f3d762ae2e42f908879..f670065c36f0152deda34fe789343187e5a7de38 100644 (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.
diff --git a/test/fixtures/controller.doughnut/doughnut-outer-radius-percent.js b/test/fixtures/controller.doughnut/doughnut-outer-radius-percent.js
new file mode 100644 (file)
index 0000000..28dd46d
--- /dev/null
@@ -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%',
+    }
+  }
+};
diff --git a/test/fixtures/controller.doughnut/doughnut-outer-radius-percent.png b/test/fixtures/controller.doughnut/doughnut-outer-radius-percent.png
new file mode 100644 (file)
index 0000000..f2f0dcd
Binary files /dev/null and b/test/fixtures/controller.doughnut/doughnut-outer-radius-percent.png differ
diff --git a/test/fixtures/controller.doughnut/doughnut-outer-radius-pixels.js b/test/fixtures/controller.doughnut/doughnut-outer-radius-pixels.js
new file mode 100644 (file)
index 0000000..a4a50df
--- /dev/null
@@ -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,
+    }
+  }
+};
diff --git a/test/fixtures/controller.doughnut/doughnut-outer-radius-pixels.png b/test/fixtures/controller.doughnut/doughnut-outer-radius-pixels.png
new file mode 100644 (file)
index 0000000..195218c
Binary files /dev/null and b/test/fixtures/controller.doughnut/doughnut-outer-radius-pixels.png differ
index cee5be46e7b6e3083b248d07960ca7f6573ea1b6..a2933237cb3e2077569521aea4b1877b19db6e44 100644 (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;
 }
 
diff --git a/types/tests/controllers/doughnut_outer_radius.ts b/types/tests/controllers/doughnut_outer_radius.ts
new file mode 100644 (file)
index 0000000..2c1dd73
--- /dev/null
@@ -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%',
+  }
+});