mirror of
https://github.com/chartjs/Chart.js.git
synced 2026-03-03 15:04:03 +01:00
Use ResizeObserver and MutationObserver to detect detach/attach/resize (#7104)
* Use Resize/MutationObserver to detect detach/attach/resize * Cleanup * Review update * Restore infinite resize detection (#6011)
This commit is contained in:
@@ -7,6 +7,7 @@ import layouts from './core.layouts';
|
||||
import {BasicPlatform, DomPlatform} from '../platform/platforms';
|
||||
import plugins from './core.plugins';
|
||||
import scaleService from '../core/core.scaleService';
|
||||
import {getMaximumWidth, getMaximumHeight} from '../helpers/helpers.dom';
|
||||
|
||||
/**
|
||||
* @typedef { import("../platform/platform.base").IEvent } IEvent
|
||||
@@ -207,6 +208,7 @@ class Chart {
|
||||
this.scales = {};
|
||||
this.scale = undefined;
|
||||
this.$plugins = undefined;
|
||||
this.$proxies = {};
|
||||
|
||||
// Add the chart instance to the global namespace
|
||||
Chart.instances[me.id] = me;
|
||||
@@ -246,15 +248,15 @@ class Chart {
|
||||
// Before init plugin notification
|
||||
plugins.notify(me, 'beforeInit');
|
||||
|
||||
helpers.dom.retinaScale(me, me.options.devicePixelRatio);
|
||||
|
||||
me.bindEvents();
|
||||
|
||||
if (me.options.responsive) {
|
||||
// Initial resize before chart draws (must be silent to preserve initial animations).
|
||||
me.resize(true);
|
||||
} else {
|
||||
helpers.dom.retinaScale(me, me.options.devicePixelRatio);
|
||||
}
|
||||
|
||||
me.bindEvents();
|
||||
|
||||
// After init plugin notification
|
||||
plugins.notify(me, 'afterInit');
|
||||
|
||||
@@ -285,19 +287,25 @@ class Chart {
|
||||
return this;
|
||||
}
|
||||
|
||||
resize(silent) {
|
||||
resize(silent, width, height) {
|
||||
const me = this;
|
||||
const options = me.options;
|
||||
const canvas = me.canvas;
|
||||
const aspectRatio = (options.maintainAspectRatio && me.aspectRatio) || null;
|
||||
const oldRatio = me.currentDevicePixelRatio;
|
||||
const aspectRatio = options.maintainAspectRatio && me.aspectRatio;
|
||||
|
||||
if (width === undefined || height === undefined) {
|
||||
width = getMaximumWidth(canvas);
|
||||
height = getMaximumHeight(canvas);
|
||||
}
|
||||
// the canvas render width and height will be casted to integers so make sure that
|
||||
// the canvas display style uses the same integer values to avoid blurring effect.
|
||||
|
||||
// Set to 0 instead of canvas.size because the size defaults to 300x150 if the element is collapsed
|
||||
const newWidth = Math.max(0, Math.floor(helpers.dom.getMaximumWidth(canvas)));
|
||||
const newHeight = Math.max(0, Math.floor(aspectRatio ? newWidth / aspectRatio : helpers.dom.getMaximumHeight(canvas)));
|
||||
const newWidth = Math.max(0, Math.floor(width));
|
||||
const newHeight = Math.max(0, Math.floor(aspectRatio ? newWidth / aspectRatio : height));
|
||||
|
||||
// detect devicePixelRation changes
|
||||
const oldRatio = me.currentDevicePixelRatio;
|
||||
const newRatio = options.devicePixelRatio || me.platform.getDevicePixelRatio();
|
||||
|
||||
if (me.width === newWidth && me.height === newHeight && oldRatio === newRatio) {
|
||||
@@ -932,11 +940,11 @@ class Chart {
|
||||
listeners[type] = listener;
|
||||
});
|
||||
|
||||
// Elements used to detect size change should not be injected for non responsive charts.
|
||||
// See https://github.com/chartjs/Chart.js/issues/2210
|
||||
if (me.options.responsive) {
|
||||
listener = function() {
|
||||
me.resize();
|
||||
listener = function(width, height) {
|
||||
if (me.canvas) {
|
||||
me.resize(false, width, height);
|
||||
}
|
||||
};
|
||||
|
||||
me.platform.addEventListener(me, 'resize', listener);
|
||||
|
||||
Reference in New Issue
Block a user