]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Fix doughnut rotation on float edge cases (#9121)
authorJukka Kurkela <jukka.kurkela@gmail.com>
Tue, 18 May 2021 23:24:23 +0000 (02:24 +0300)
committerGitHub <noreply@github.com>
Tue, 18 May 2021 23:24:23 +0000 (19:24 -0400)
src/controllers/controller.doughnut.js
src/helpers/helpers.math.js
test/fixtures/controller.doughnut/doughnut-rotation-300.js [new file with mode: 0644]
test/fixtures/controller.doughnut/doughnut-rotation-300.png [new file with mode: 0644]

index 47e28b57bac11ebd211dd463b8317e656599cd81..d6c9c020b80307e937c7034b5bb7148981e748f2 100644 (file)
@@ -20,8 +20,8 @@ function getRatioAndOffset(rotation, circumference, cutout) {
     const startY = Math.sin(startAngle);
     const endX = Math.cos(endAngle);
     const endY = Math.sin(endAngle);
-    const calcMax = (angle, a, b) => _angleBetween(angle, startAngle, endAngle) ? 1 : Math.max(a, a * cutout, b, b * cutout);
-    const calcMin = (angle, a, b) => _angleBetween(angle, startAngle, endAngle) ? -1 : Math.min(a, a * cutout, b, b * cutout);
+    const calcMax = (angle, a, b) => _angleBetween(angle, startAngle, endAngle, true) ? 1 : Math.max(a, a * cutout, b, b * cutout);
+    const calcMin = (angle, a, b) => _angleBetween(angle, startAngle, endAngle, true) ? -1 : Math.min(a, a * cutout, b, b * cutout);
     const maxX = calcMax(0, startX, endX);
     const maxY = calcMax(HALF_PI, startY, endY);
     const minX = calcMin(PI, startX, endX);
index daf849818d40800b1defe258499707a099d488b6..d9e792c08fb3cd7a43fc5d6d6afc509f258a5a37 100644 (file)
@@ -148,7 +148,7 @@ export function _normalizeAngle(a) {
 /**
  * @private
  */
-export function _angleBetween(angle, start, end) {
+export function _angleBetween(angle, start, end, sameAngleIsFullCircle) {
   const a = _normalizeAngle(angle);
   const s = _normalizeAngle(start);
   const e = _normalizeAngle(end);
@@ -156,7 +156,8 @@ export function _angleBetween(angle, start, end) {
   const angleToEnd = _normalizeAngle(e - a);
   const startToAngle = _normalizeAngle(a - s);
   const endToAngle = _normalizeAngle(a - e);
-  return a === s || a === e || (angleToStart > angleToEnd && startToAngle < endToAngle);
+  return a === s || a === e || (sameAngleIsFullCircle && s === e)
+    || (angleToStart > angleToEnd && startToAngle < endToAngle);
 }
 
 /**
diff --git a/test/fixtures/controller.doughnut/doughnut-rotation-300.js b/test/fixtures/controller.doughnut/doughnut-rotation-300.js
new file mode 100644 (file)
index 0000000..f4fa424
--- /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: {
+      rotation: 300
+    }
+  }
+};
diff --git a/test/fixtures/controller.doughnut/doughnut-rotation-300.png b/test/fixtures/controller.doughnut/doughnut-rotation-300.png
new file mode 100644 (file)
index 0000000..9b8bc86
Binary files /dev/null and b/test/fixtures/controller.doughnut/doughnut-rotation-300.png differ