]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Allow changing the aspect ratio (#8659)
authorEvert Timberg <evert.timberg+github@gmail.com>
Thu, 18 Mar 2021 21:07:32 +0000 (17:07 -0400)
committerGitHub <noreply@github.com>
Thu, 18 Mar 2021 21:07:32 +0000 (23:07 +0200)
* Allow changing the aspect ratio

* Add test and require `resize()` call

* Update to respect maintainAspectRatio

src/core/core.controller.js
test/specs/core.controller.tests.js

index ded583f079685071651d5361c02dee8a401b6cec..8a8e6984e4cf9042f1bfef023ccb2a91397fb33c 100644 (file)
@@ -7,7 +7,7 @@ import PluginService from './core.plugins';
 import registry from './core.registry';
 import Config, {determineAxis, getIndexAxis} from './core.config';
 import {retinaScale} from '../helpers/helpers.dom';
-import {each, callback as callCallback, uid, valueOrDefault, _elementsEqual} from '../helpers/helpers.core';
+import {each, callback as callCallback, uid, valueOrDefault, _elementsEqual, isNullOrUndef} from '../helpers/helpers.core';
 import {clearCanvas, clipArea, unclipArea, _isPointInArea} from '../helpers/helpers.canvas';
 // @ts-ignore
 import {version} from '../../package.json';
@@ -103,8 +103,11 @@ class Chart {
     this.canvas = canvas;
     this.width = width;
     this.height = height;
-    this.aspectRatio = height ? width / height : null;
     this._options = options;
+    // Store the previously used aspect ratio to determine if a resize
+    // is needed during updates. Do this after _options is set since
+    // aspectRatio uses a getter
+    this._aspectRatio = this.aspectRatio;
     this._layers = [];
     this._metasets = [];
     this._stacks = undefined;
@@ -147,6 +150,22 @@ class Chart {
     }
   }
 
+  get aspectRatio() {
+    const {options: {aspectRatio, maintainAspectRatio}, width, height, _aspectRatio} = this;
+    if (!isNullOrUndef(aspectRatio)) {
+      // If aspectRatio is defined in options, use that.
+      return aspectRatio;
+    }
+
+    if (maintainAspectRatio && _aspectRatio) {
+      // If maintainAspectRatio is truthly and we had previously determined _aspectRatio, use that
+      return _aspectRatio;
+    }
+
+    // Calculate
+    return height ? width / height : null;
+  }
+
   get data() {
     return this.config.data;
   }
@@ -238,6 +257,7 @@ class Chart {
 
     me.width = newSize.width;
     me.height = newSize.height;
+    me._aspectRatio = me.aspectRatio;
     retinaScale(me, newRatio, true);
 
     me.notifyPlugins('resize', {size: newSize});
index fc3a601ed6216f642750918e81ea62ab1e239656..21603c471412efbfe8bc9c0d57f539b3a0d25956 100644 (file)
@@ -1213,6 +1213,38 @@ describe('Chart', function() {
     });
   });
 
+  describe('config.options.aspectRatio', function() {
+    it('should resize the canvas when the aspectRatio option changes', function(done) {
+      var chart = acquireChart({
+        options: {
+          responsive: true,
+          aspectRatio: 1,
+        }
+      }, {
+        canvas: {
+          style: '',
+          width: 400,
+        },
+      });
+
+      expect(chart).toBeChartOfSize({
+        dw: 400, dh: 400,
+        rw: 400, rh: 400,
+      });
+
+      waitForResize(chart, function() {
+        expect(chart).toBeChartOfSize({
+          dw: 400, dh: 200,
+          rw: 400, rh: 200,
+        });
+
+        done();
+      });
+      chart.options.aspectRatio = 2;
+      chart.resize();
+    });
+  });
+
   describe('controller.reset', function() {
     it('should reset the chart elements', function() {
       var chart = acquireChart({