-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
/
Copy pathhover.js
124 lines (105 loc) · 4.2 KB
/
hover.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
/**
* Copyright 2012-2016, 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 Lib = require('../../lib');
var Fx = require('../../plots/cartesian/graph_interact');
var constants = require('../../plots/cartesian/constants');
var ErrorBars = require('../../components/errorbars');
var getTraceColor = require('./get_trace_color');
var Color = require('../../components/color');
module.exports = function hoverPoints(pointData, xval, yval, hovermode) {
var cd = pointData.cd,
trace = cd[0].trace,
xa = pointData.xa,
ya = pointData.ya,
xpx = xa.c2p(xval),
ypx = ya.c2p(yval),
pt = [xpx, ypx];
// even if hoveron is 'fills', only use it if we have polygons too
if(trace.hoveron === 'fills' && trace._polygons) {
var polygons = trace._polygons,
inside = false,
x0 = Infinity,
x1 = -Infinity,
y0 = Infinity,
y1 = -Infinity;
for(var i = 0; i < polygons.length; i++) {
var polygon = polygons[i];
// TODO: this is not going to work right for curved edges, it will
// act as though they're straight. That's probably going to need
// the elements themselves to capture the events. Worth it?
if(polygon.contains(pt)) {
inside = !inside;
// TODO: need better than just the overall bounding box
x0 = Math.min(x0, polygon.xmin);
x1 = Math.max(x1, polygon.xmax);
y0 = Math.min(y0, polygon.ymin);
y1 = Math.max(y1, polygon.ymax);
}
}
if(inside) {
// get only fill or line color for the hover color
var color = Color.defaultLine;
if(Color.opacity(trace.fillcolor)) color = trace.fillcolor;
else if(Color.opacity((trace.line || {}).color)) {
color = trace.line.color;
}
Lib.extendFlat(pointData, {
// never let a 2D override 1D type as closest point
distance: constants.MAXDIST + 10,
x0: x0,
x1: x1,
y0: y0,
y1: y1,
color: color
});
delete pointData.index;
return [pointData];
}
}
else {
var dx = function(di) {
// scatter points: d.mrc is the calculated marker radius
// adjust the distance so if you're inside the marker it
// always will show up regardless of point size, but
// prioritize smaller points
var rad = Math.max(3, di.mrc || 0);
return Math.max(Math.abs(xa.c2p(di.x) - xa.c2p(xval)) - rad, 1 - 3 / rad);
},
dy = function(di) {
var rad = Math.max(3, di.mrc || 0);
return Math.max(Math.abs(ya.c2p(di.y) - ya.c2p(yval)) - rad, 1 - 3 / rad);
},
dxy = function(di) {
var rad = Math.max(3, di.mrc || 0),
dx = Math.abs(xa.c2p(di.x) - xa.c2p(xval)),
dy = Math.abs(ya.c2p(di.y) - ya.c2p(yval));
return Math.max(Math.sqrt(dx * dx + dy * dy) - rad, 1 - 3 / rad);
},
distfn = Fx.getDistanceFunction(hovermode, dx, dy, dxy);
Fx.getClosest(cd, distfn, pointData);
// skip the rest (for this trace) if we didn't find a close point
if(pointData.index === false) return;
// the closest data point
var di = cd[pointData.index],
xc = xa.c2p(di.x, true),
yc = ya.c2p(di.y, true),
rad = di.mrc || 1;
pointData.color = getTraceColor(trace, di);
pointData.x0 = xc - rad;
pointData.x1 = xc + rad;
pointData.xLabelVal = di.x;
pointData.y0 = yc - rad;
pointData.y1 = yc + rad;
pointData.yLabelVal = di.y;
if(di.tx) pointData.text = di.tx;
else if(trace.text) pointData.text = trace.text;
ErrorBars.hoverInfo(di, trace, pointData);
return [pointData];
}
};