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, isNullOrUndef} from '../helpers/helpers.core';
+import {each, callback as callCallback, uid, valueOrDefault, _elementsEqual, isNullOrUndef, setsEqual} from '../helpers/helpers.core';
import {clearCanvas, clipArea, unclipArea, _isPointInArea} from '../helpers/helpers.canvas';
// @ts-ignore
import {version} from '../../package.json';
me.ensureScalesHaveIDs();
me.buildOrUpdateScales();
+ const existingEvents = new Set(Object.keys(me._listeners));
+ const newEvents = new Set(me.options.events);
+
+ if (!setsEqual(existingEvents, newEvents)) {
+ // The events array has changed. Rebind it
+ me.unbindEvents();
+ me.bindEvents();
+ }
+
// plugins options references might have change, let's invalidate the cache
// https://github.com/chartjs/Chart.js/issues/5111#issuecomment-355934167
me._plugins.invalidate();
return;
}
- delete me._listeners;
+ me._listeners = {};
each(listeners, (listener, type) => {
me.platform.removeEventListener(me, type, listener);
});
export const defined = (value) => typeof value !== 'undefined';
export const isFunction = (value) => typeof value === 'function';
+
+// Adapted from https://stackoverflow.com/questions/31128855/comparing-ecma6-sets-for-equality#31129384
+export const setsEqual = (a, b) => {
+ if (a.size !== b.size) {
+ return false;
+ }
+
+ for (const item of a) {
+ if (!b.has(item)) {
+ return false;
+ }
+ }
+
+ return true;
+};
expect(chart.getActiveElements()).toEqual([{datasetIndex: 0, index: 1, element: point}]);
});
+ it('should handle changing the events at runtime', async function() {
+ var chart = acquireChart({
+ type: 'line',
+ data: {
+ labels: ['A', 'B', 'C', 'D'],
+ datasets: [{
+ data: [10, 20, 30, 100]
+ }]
+ },
+ options: {
+ events: ['click']
+ }
+ });
+
+ var point1 = chart.getDatasetMeta(0).data[1];
+ var point2 = chart.getDatasetMeta(0).data[2];
+
+ await jasmine.triggerMouseEvent(chart, 'click', point1);
+ expect(chart.getActiveElements()).toEqual([{datasetIndex: 0, index: 1, element: point1}]);
+
+ chart.options.events = ['mousemove'];
+ chart.update();
+
+ await jasmine.triggerMouseEvent(chart, 'mousemove', point2);
+ expect(chart.getActiveElements()).toEqual([{datasetIndex: 0, index: 2, element: point2}]);
+ });
+
it('should activate element on hover when minPadding pixels outside chart area', async function() {
var chart = acquireChart({
type: 'line',
expect(() => helpers.resolveObjectKey({}, 1)).toThrow();
});
});
+
+ describe('setsEqual', function() {
+ it('should handle set comparison', function() {
+ var a = new Set([1]);
+ var b = new Set(['1']);
+ var c = new Set([1]);
+
+ expect(helpers.setsEqual(a, b)).toBeFalse();
+ expect(helpers.setsEqual(a, c)).toBeTrue();
+ });
+ });
});
export function mergeIf<T>(target: T, source: AnyObject[]): AnyObject;
export function resolveObjectKey(obj: AnyObject, key: string): AnyObject;
+
+export function setsEqual(a: Set<unknown>, b: Set<unknown>): boolean;