-
Notifications
You must be signed in to change notification settings - Fork 331
/
Copy pathevents.js
108 lines (93 loc) · 2.82 KB
/
events.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import {isFunction, callback} from 'chart.js/helpers';
import {getElements} from './interaction';
import {loadHooks} from './helpers';
const moveHooks = ['enter', 'leave'];
/**
* @typedef { import("chart.js").Chart } Chart
* @typedef { import('../../types/options').AnnotationPluginOptions } AnnotationPluginOptions
*/
export const eventHooks = moveHooks.concat('click');
/**
* @param {Chart} chart
* @param {Object} state
* @param {AnnotationPluginOptions} options
*/
export function updateListeners(chart, state, options) {
state.listened = loadHooks(options, eventHooks, state.listeners);
state.moveListened = false;
moveHooks.forEach(hook => {
if (isFunction(options[hook])) {
state.moveListened = true;
}
});
if (!state.listened || !state.moveListened) {
state.annotations.forEach(scope => {
if (!state.listened && isFunction(scope.click)) {
state.listened = true;
}
if (!state.moveListened) {
moveHooks.forEach(hook => {
if (isFunction(scope[hook])) {
state.listened = true;
state.moveListened = true;
}
});
}
});
}
}
/**
* @param {Object} state
* @param {ChartEvent} event
* @param {AnnotationPluginOptions} options
* @return {boolean|undefined}
*/
export function handleEvent(state, event, options) {
if (state.listened) {
switch (event.type) {
case 'mousemove':
case 'mouseout':
return handleMoveEvents(state, event, options);
case 'click':
return handleClickEvents(state, event, options);
default:
}
}
}
function handleMoveEvents(state, event, options) {
if (!state.moveListened) {
return;
}
let elements;
if (event.type === 'mousemove') {
elements = getElements(state.visibleElements, event, options.interaction);
} else {
elements = [];
}
const previous = state.hovered;
state.hovered = elements;
const context = {state, event};
let changed = dispatchMoveEvents(context, 'leave', previous, elements);
return dispatchMoveEvents(context, 'enter', elements, previous) || changed;
}
function dispatchMoveEvents({state, event}, hook, elements, checkElements) {
let changed;
for (const element of elements) {
if (checkElements.indexOf(element) < 0) {
changed = dispatchEvent(element.options[hook] || state.listeners[hook], element, event) || changed;
}
}
return changed;
}
function handleClickEvents(state, event, options) {
const listeners = state.listeners;
const elements = getElements(state.visibleElements, event, options.interaction);
let changed;
for (const element of elements) {
changed = dispatchEvent(element.options.click || listeners.click, element, event) || changed;
}
return changed;
}
function dispatchEvent(handler, element, event) {
return callback(handler, [element.$context, event]) === true;
}