-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
/
Copy pathgraph_interact.js
155 lines (131 loc) · 6.28 KB
/
graph_interact.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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/**
* Copyright 2012-2018, Plotly, Inc.
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
var d3 = require('d3');
var Fx = require('../../components/fx');
var dragElement = require('../../components/dragelement');
var constants = require('./constants');
var makeDragBox = require('./dragbox').makeDragBox;
module.exports = function initInteractions(gd) {
var fullLayout = gd._fullLayout;
if(gd._context.staticPlot) {
// this sweeps up more than just cartesian drag elements...
d3.select(gd).selectAll('.drag').remove();
return;
}
if(!fullLayout._has('cartesian') && !fullLayout._has('gl2d') && !fullLayout._has('splom')) return;
var subplots = Object.keys(fullLayout._plots || {}).sort(function(a, b) {
// sort overlays last, then by x axis number, then y axis number
if((fullLayout._plots[a].mainplot && true) ===
(fullLayout._plots[b].mainplot && true)) {
var aParts = a.split('y'),
bParts = b.split('y');
return (aParts[0] === bParts[0]) ?
(Number(aParts[1] || 1) - Number(bParts[1] || 1)) :
(Number(aParts[0] || 1) - Number(bParts[0] || 1));
}
return fullLayout._plots[a].mainplot ? 1 : -1;
});
subplots.forEach(function(subplot) {
var plotinfo = fullLayout._plots[subplot];
var xa = plotinfo.xaxis;
var ya = plotinfo.yaxis;
var DRAGGERSIZE = constants.DRAGGERSIZE;
// main and corner draggers need not be repeated for
// overlaid subplots - these draggers drag them all
if(!plotinfo.mainplot) {
// main dragger goes over the grids and data, so we use its
// mousemove events for all data hover effects
var maindrag = makeDragBox(gd, plotinfo, xa._offset, ya._offset,
xa._length, ya._length, 'ns', 'ew');
maindrag.onmousemove = function(evt) {
// This is on `gd._fullLayout`, *not* fullLayout because the reference
// changes by the time this is called again.
gd._fullLayout._rehover = function() {
if(gd._fullLayout._hoversubplot === subplot) {
Fx.hover(gd, evt, subplot);
}
};
Fx.hover(gd, evt, subplot);
// Note that we have *not* used the cached fullLayout variable here
// since that may be outdated when this is called as a callback later on
gd._fullLayout._lasthover = maindrag;
gd._fullLayout._hoversubplot = subplot;
};
/*
* IMPORTANT:
* We must check for the presence of the drag cover here.
* If we don't, a 'mouseout' event is triggered on the
* maindrag before each 'click' event, which has the effect
* of clearing the hoverdata; thus, cancelling the click event.
*/
maindrag.onmouseout = function(evt) {
if(gd._dragging) return;
// When the mouse leaves this maindrag, unset the hovered subplot.
// This may cause problems if it leaves the subplot directly *onto*
// another subplot, but that's a tiny corner case at the moment.
gd._fullLayout._hoversubplot = null;
dragElement.unhover(gd, evt);
};
// corner draggers
if(gd._context.showAxisDragHandles) {
makeDragBox(gd, plotinfo, xa._offset - DRAGGERSIZE, ya._offset - DRAGGERSIZE,
DRAGGERSIZE, DRAGGERSIZE, 'n', 'w');
makeDragBox(gd, plotinfo, xa._offset + xa._length, ya._offset - DRAGGERSIZE,
DRAGGERSIZE, DRAGGERSIZE, 'n', 'e');
makeDragBox(gd, plotinfo, xa._offset - DRAGGERSIZE, ya._offset + ya._length,
DRAGGERSIZE, DRAGGERSIZE, 's', 'w');
makeDragBox(gd, plotinfo, xa._offset + xa._length, ya._offset + ya._length,
DRAGGERSIZE, DRAGGERSIZE, 's', 'e');
}
}
if(gd._context.showAxisDragHandles) {
// x axis draggers - if you have overlaid plots,
// these drag each axis separately
if(subplot === xa._mainSubplot) {
// the y position of the main x axis line
var y0 = xa._mainLinePosition;
if(xa.side === 'top') y0 -= DRAGGERSIZE;
makeDragBox(gd, plotinfo, xa._offset + xa._length * 0.1, y0,
xa._length * 0.8, DRAGGERSIZE, '', 'ew');
makeDragBox(gd, plotinfo, xa._offset, y0,
xa._length * 0.1, DRAGGERSIZE, '', 'w');
makeDragBox(gd, plotinfo, xa._offset + xa._length * 0.9, y0,
xa._length * 0.1, DRAGGERSIZE, '', 'e');
}
// y axis draggers
if(subplot === ya._mainSubplot) {
// the x position of the main y axis line
var x0 = ya._mainLinePosition;
if(ya.side !== 'right') x0 -= DRAGGERSIZE;
makeDragBox(gd, plotinfo, x0, ya._offset + ya._length * 0.1,
DRAGGERSIZE, ya._length * 0.8, 'ns', '');
makeDragBox(gd, plotinfo, x0, ya._offset + ya._length * 0.9,
DRAGGERSIZE, ya._length * 0.1, 's', '');
makeDragBox(gd, plotinfo, x0, ya._offset,
DRAGGERSIZE, ya._length * 0.1, 'n', '');
}
}
});
// In case you mousemove over some hovertext, send it to Fx.hover too
// we do this so that we can put the hover text in front of everything,
// but still be able to interact with everything as if it isn't there
var hoverLayer = fullLayout._hoverlayer.node();
hoverLayer.onmousemove = function(evt) {
evt.target = fullLayout._lasthover;
Fx.hover(gd, evt, fullLayout._hoversubplot);
};
hoverLayer.onclick = function(evt) {
evt.target = fullLayout._lasthover;
Fx.click(gd, evt);
};
// also delegate mousedowns... TODO: does this actually work?
hoverLayer.onmousedown = function(evt) {
fullLayout._lasthover.onmousedown(evt);
};
};