From 4153fb1d5b59ddd2b9e4ddada9566c012e00414c Mon Sep 17 00:00:00 2001 From: Jukka Kurkela Date: Tue, 23 Feb 2021 22:27:18 +0200 Subject: [PATCH 1/2] Add resizeDelay option --- docs/docs/configuration/responsive.md | 1 + src/core/core.controller.js | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/docs/configuration/responsive.md b/docs/docs/configuration/responsive.md index d8b87f5dd91..37dcb67125f 100644 --- a/docs/docs/configuration/responsive.md +++ b/docs/docs/configuration/responsive.md @@ -21,6 +21,7 @@ Namespace: `options` | `maintainAspectRatio` | `boolean` | `true` | Maintain the original canvas aspect ratio `(width / height)` when resizing. | `aspectRatio` | `number` | `2` | Canvas aspect ratio (i.e. `width / height`, a value of 1 representing a square canvas). Note that this option is ignored if the height is explicitly defined either as attribute or via the style. | `onResize` | `function` | `null` | Called when a resize occurs. Gets passed two arguments: the chart instance and the new size. +| `resizeDelay` | `number` | `0` | Delay the resize update by give amount of milliseconds. This can ease the resize process by debouncing update of the elements. ## Important Note diff --git a/src/core/core.controller.js b/src/core/core.controller.js index 3e9151a0ff6..b230ee5ea06 100644 --- a/src/core/core.controller.js +++ b/src/core/core.controller.js @@ -122,6 +122,7 @@ class Chart { this.attached = false; this._animationsDisabled = undefined; this.$context = undefined; + this._resizeTimer = undefined; // Add the chart instance to the global namespace instances[me.id] = me; @@ -242,7 +243,15 @@ class Chart { callCallback(options.onResize, [newSize], me); if (me.attached) { - me.update('resize'); + const delay = options.resizeDelay || 0; + const resizeUpdate = () => me.update('resize'); + if (delay) { + clearTimeout(me._resizeTimer); + me._resizeTimer = setTimeout(resizeUpdate, delay); + me.render(); + } else { + resizeUpdate(); + } } } From 53f7716a3f9fffd142ba762a515c77fe7f17db9e Mon Sep 17 00:00:00 2001 From: Jukka Kurkela Date: Tue, 23 Feb 2021 22:50:36 +0200 Subject: [PATCH 2/2] Extract helper --- src/core/core.controller.js | 12 ++++-------- src/helpers/helpers.extras.js | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/core/core.controller.js b/src/core/core.controller.js index b230ee5ea06..7450587dfb9 100644 --- a/src/core/core.controller.js +++ b/src/core/core.controller.js @@ -11,6 +11,7 @@ import {each, callback as callCallback, uid, valueOrDefault, _elementsEqual} fro import {clearCanvas, clipArea, unclipArea, _isPointInArea} from '../helpers/helpers.canvas'; // @ts-ignore import {version} from '../../package.json'; +import {debounce} from '../helpers/helpers.extras'; /** * @typedef { import("../platform/platform.base").ChartEvent } ChartEvent @@ -122,7 +123,7 @@ class Chart { this.attached = false; this._animationsDisabled = undefined; this.$context = undefined; - this._resizeTimer = undefined; + this._doResize = debounce(() => this.update('resize'), options.resizeDelay || 0); // Add the chart instance to the global namespace instances[me.id] = me; @@ -243,14 +244,9 @@ class Chart { callCallback(options.onResize, [newSize], me); if (me.attached) { - const delay = options.resizeDelay || 0; - const resizeUpdate = () => me.update('resize'); - if (delay) { - clearTimeout(me._resizeTimer); - me._resizeTimer = setTimeout(resizeUpdate, delay); + if (me._doResize()) { + // The resize update is delayed, only draw without updating. me.render(); - } else { - resizeUpdate(); } } } diff --git a/src/helpers/helpers.extras.js b/src/helpers/helpers.extras.js index 21857a6e993..703fbf208d4 100644 --- a/src/helpers/helpers.extras.js +++ b/src/helpers/helpers.extras.js @@ -40,6 +40,25 @@ export function throttled(fn, thisArg, updateFn) { }; } +/** + * Debounces calling `fn` for `delay` ms + * @param {function} fn - Function to call. No arguments are passed. + * @param {number} delay - Delay in ms. 0 = immediate invocation. + * @returns {function} + */ +export function debounce(fn, delay) { + let timeout; + return function() { + if (delay) { + clearTimeout(timeout); + timeout = setTimeout(fn, delay); + } else { + fn(); + } + return delay; + }; +} + /** * Converts 'start' to 'left', 'end' to 'right' and others to 'center'