forked from plotly/plotly.js
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathclick.js
More file actions
128 lines (112 loc) · 4.03 KB
/
click.js
File metadata and controls
128 lines (112 loc) · 4.03 KB
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
'use strict';
var Lib = require('../../lib');
var Registry = require('../../registry');
var arrayEditor = require('../../plot_api/plot_template').arrayEditor;
module.exports = {
hasClickToShow: hasClickToShow,
onClick: onClick
};
/*
* hasClickToShow: does the given hoverData have ANY annotations which will
* turn ON if we click here? (used by hover events to set cursor)
*
* gd: graphDiv
* hoverData: a hoverData array, as included with the *plotly_hover* or
* *plotly_click* events in the `points` attribute
*
* returns: boolean
*/
function hasClickToShow(gd, hoverData) {
var sets = getToggleSets(gd, hoverData);
return sets.on.length > 0 || sets.explicitOff.length > 0;
}
/*
* onClick: perform the toggling (via Plotly.update) implied by clicking
* at this hoverData
*
* gd: graphDiv
* hoverData: a hoverData array, as included with the *plotly_hover* or
* *plotly_click* events in the `points` attribute
*
* returns: Promise that the update is complete
*/
function onClick(gd, hoverData) {
var toggleSets = getToggleSets(gd, hoverData);
var onSet = toggleSets.on;
var offSet = toggleSets.off.concat(toggleSets.explicitOff);
var update = {};
var annotationsOut = gd._fullLayout.annotations;
var i, editHelpers;
if(!(onSet.length || offSet.length)) return;
for(i = 0; i < onSet.length; i++) {
editHelpers = arrayEditor(gd.layout, 'annotations', annotationsOut[onSet[i]]);
editHelpers.modifyItem('visible', true);
Lib.extendFlat(update, editHelpers.getUpdateObj());
}
for(i = 0; i < offSet.length; i++) {
editHelpers = arrayEditor(gd.layout, 'annotations', annotationsOut[offSet[i]]);
editHelpers.modifyItem('visible', false);
Lib.extendFlat(update, editHelpers.getUpdateObj());
}
return Registry.call('update', gd, {}, update);
}
/*
* getToggleSets: find the annotations which will turn on or off at this
* hoverData
*
* gd: graphDiv
* hoverData: a hoverData array, as included with the *plotly_hover* or
* *plotly_click* events in the `points` attribute
*
* returns: {
* on: Array (indices of annotations to turn on),
* off: Array (indices to turn off because you're not hovering on them),
* explicitOff: Array (indices to turn off because you *are* hovering on them)
* }
*/
function getToggleSets(gd, hoverData) {
var annotations = gd._fullLayout.annotations;
var onSet = [];
var offSet = [];
var explicitOffSet = [];
var hoverLen = (hoverData || []).length;
var i, j, anni, showMode, pointj, xa, ya, toggleType;
for(i = 0; i < annotations.length; i++) {
anni = annotations[i];
showMode = anni.clicktoshow;
if(showMode) {
for(j = 0; j < hoverLen; j++) {
pointj = hoverData[j];
xa = pointj.xaxis;
ya = pointj.yaxis;
if(xa._id === anni.xref &&
ya._id === anni.yref &&
xa.d2r(pointj.x) === clickData2r(anni._xclick, xa) &&
ya.d2r(pointj.y) === clickData2r(anni._yclick, ya)
) {
// match! toggle this annotation
// regardless of its clicktoshow mode
// but if it's onout mode, off is implicit
if(anni.visible) {
if(showMode === 'onout') toggleType = offSet;
else toggleType = explicitOffSet;
} else {
toggleType = onSet;
}
toggleType.push(i);
break;
}
}
if(j === hoverLen) {
// no match - only turn this annotation OFF, and only if
// showmode is 'onout'
if(anni.visible && showMode === 'onout') offSet.push(i);
}
}
}
return {on: onSet, off: offSet, explicitOff: explicitOffSet};
}
// to handle log axes until v3
function clickData2r(d, ax) {
return ax.type === 'log' ? ax.l2r(d) : ax.d2r(d);
}