mirror of
https://github.com/chartjs/Chart.js.git
synced 2025-12-08 20:36:08 +00:00
Fix detecting changed events (#9050)
* Fix detecting changed events Because `this._listeners` may contain both event handlers from options and internal event handlers for responsive support, the `setsEqual` check would often fail, causing event handlers to be unnecessarily detached and reattached and fired. If I'm understanding correctly, this is the root cause of #9049. * Use a separate object for responsive listeners Correctly update events when responsive property changes as well as when requested events change. * Code review feedback
This commit is contained in:
parent
c955ffad64
commit
1df4883aff
@ -116,8 +116,9 @@ class Chart {
|
|||||||
this.chartArea = undefined;
|
this.chartArea = undefined;
|
||||||
this._active = [];
|
this._active = [];
|
||||||
this._lastEvent = undefined;
|
this._lastEvent = undefined;
|
||||||
/** @type {{attach?: function, detach?: function, resize?: function}} */
|
|
||||||
this._listeners = {};
|
this._listeners = {};
|
||||||
|
/** @type {?{attach?: function, detach?: function, resize?: function}} */
|
||||||
|
this._responsiveListeners = undefined;
|
||||||
this._sortedMetasets = [];
|
this._sortedMetasets = [];
|
||||||
this.scales = {};
|
this.scales = {};
|
||||||
this.scale = undefined;
|
this.scale = undefined;
|
||||||
@ -478,8 +479,8 @@ class Chart {
|
|||||||
const existingEvents = new Set(Object.keys(me._listeners));
|
const existingEvents = new Set(Object.keys(me._listeners));
|
||||||
const newEvents = new Set(me.options.events);
|
const newEvents = new Set(me.options.events);
|
||||||
|
|
||||||
if (!setsEqual(existingEvents, newEvents)) {
|
if (!setsEqual(existingEvents, newEvents) || !!this._responsiveListeners !== me.options.responsive) {
|
||||||
// The events array has changed. Rebind it
|
// The configured events have changed. Rebind.
|
||||||
me.unbindEvents();
|
me.unbindEvents();
|
||||||
me.bindEvents();
|
me.bindEvents();
|
||||||
}
|
}
|
||||||
@ -889,10 +890,47 @@ class Chart {
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
bindEvents() {
|
bindEvents() {
|
||||||
|
this.bindUserEvents();
|
||||||
|
if (this.options.responsive) {
|
||||||
|
this.bindResponsiveEvents();
|
||||||
|
} else {
|
||||||
|
this.attached = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
bindUserEvents() {
|
||||||
const me = this;
|
const me = this;
|
||||||
const listeners = me._listeners;
|
const listeners = me._listeners;
|
||||||
const platform = me.platform;
|
const platform = me.platform;
|
||||||
|
|
||||||
|
const _add = (type, listener) => {
|
||||||
|
platform.addEventListener(me, type, listener);
|
||||||
|
listeners[type] = listener;
|
||||||
|
};
|
||||||
|
|
||||||
|
const listener = function(e, x, y) {
|
||||||
|
e.offsetX = x;
|
||||||
|
e.offsetY = y;
|
||||||
|
me._eventHandler(e);
|
||||||
|
};
|
||||||
|
|
||||||
|
each(me.options.events, (type) => _add(type, listener));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
bindResponsiveEvents() {
|
||||||
|
const me = this;
|
||||||
|
if (!me._responsiveListeners) {
|
||||||
|
me._responsiveListeners = {};
|
||||||
|
}
|
||||||
|
const listeners = me._responsiveListeners;
|
||||||
|
const platform = me.platform;
|
||||||
|
|
||||||
const _add = (type, listener) => {
|
const _add = (type, listener) => {
|
||||||
platform.addEventListener(me, type, listener);
|
platform.addEventListener(me, type, listener);
|
||||||
listeners[type] = listener;
|
listeners[type] = listener;
|
||||||
@ -904,16 +942,7 @@ class Chart {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let listener = function(e, x, y) {
|
const listener = (width, height) => {
|
||||||
e.offsetX = x;
|
|
||||||
e.offsetY = y;
|
|
||||||
me._eventHandler(e);
|
|
||||||
};
|
|
||||||
|
|
||||||
each(me.options.events, (type) => _add(type, listener));
|
|
||||||
|
|
||||||
if (me.options.responsive) {
|
|
||||||
listener = (width, height) => {
|
|
||||||
if (me.canvas) {
|
if (me.canvas) {
|
||||||
me.resize(width, height);
|
me.resize(width, height);
|
||||||
}
|
}
|
||||||
@ -942,9 +971,6 @@ class Chart {
|
|||||||
} else {
|
} else {
|
||||||
detached();
|
detached();
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
me.attached = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -952,15 +978,16 @@ class Chart {
|
|||||||
*/
|
*/
|
||||||
unbindEvents() {
|
unbindEvents() {
|
||||||
const me = this;
|
const me = this;
|
||||||
const listeners = me._listeners;
|
|
||||||
if (!listeners) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
me._listeners = {};
|
each(me._listeners, (listener, type) => {
|
||||||
each(listeners, (listener, type) => {
|
|
||||||
me.platform.removeEventListener(me, type, listener);
|
me.platform.removeEventListener(me, type, listener);
|
||||||
});
|
});
|
||||||
|
me._listeners = {};
|
||||||
|
|
||||||
|
each(me._responsiveListeners, (listener, type) => {
|
||||||
|
me.platform.removeEventListener(me, type, listener);
|
||||||
|
});
|
||||||
|
me._responsiveListeners = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateHoverStyle(items, mode, enabled) {
|
updateHoverStyle(items, mode, enabled) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user