-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
/
Copy pathhover.js
102 lines (77 loc) · 3.01 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
'use strict';
var Fx = require('../../components/fx');
var BADNUM = require('../../constants/numerical').BADNUM;
var getTraceColor = require('../scatter/get_trace_color');
var fillText = require('../../lib').fillText;
var attributes = require('./attributes');
module.exports = function hoverPoints(pointData, xval, yval) {
var cd = pointData.cd;
var trace = cd[0].trace;
var xa = pointData.xa;
var ya = pointData.ya;
var geo = pointData.subplot;
var isLonLatOverEdges = geo.projection.isLonLatOverEdges;
var project = geo.project;
function distFn(d) {
var _lonlat = d.lonlat;
if(!_lonlat || _lonlat[0] === BADNUM) return Infinity;
if(isLonLatOverEdges(_lonlat)) return Infinity;
var pt = project(_lonlat);
var px = project([xval, yval]);
var dx = Math.abs(pt[0] - px[0]);
var dy = Math.abs(pt[1] - px[1]);
var rad = Math.max(3, d.mrc || 0);
// N.B. d.mrc is the calculated marker radius
// which is only set for trace with 'markers' mode.
return Math.max(Math.sqrt(dx * dx + dy * dy) - rad, 1 - 3 / rad);
}
Fx.getClosest(cd, distFn, pointData);
// skip the rest (for this trace) if we didn't find a close point
if(pointData.index === false) return;
var di = cd[pointData.index];
var lonlat = di.lonlat;
var pos = [xa.c2p(lonlat), ya.c2p(lonlat)];
var rad = di.mrc || 1;
pointData.x0 = pos[0] - rad;
pointData.x1 = pos[0] + rad;
pointData.y0 = pos[1] - rad;
pointData.y1 = pos[1] + rad;
pointData.loc = di.loc;
pointData.lon = lonlat[0];
pointData.lat = lonlat[1];
var fullLayout = {};
fullLayout[trace.geo] = {_subplot: geo};
var labels = trace._module.formatLabels(di, trace, fullLayout);
pointData.lonLabel = labels.lonLabel;
pointData.latLabel = labels.latLabel;
pointData.color = getTraceColor(trace, di);
pointData.extraText = getExtraText(trace, di, pointData, cd[0].t.labels);
pointData.hovertemplate = trace.hovertemplate;
return [pointData];
};
function getExtraText(trace, pt, pointData, labels) {
if(trace.hovertemplate) return;
var hoverinfo = pt.hi || trace.hoverinfo;
var parts = hoverinfo === 'all' ?
attributes.hoverinfo.flags :
hoverinfo.split('+');
var hasLocation = parts.indexOf('location') !== -1 && Array.isArray(trace.locations);
var hasLon = (parts.indexOf('lon') !== -1);
var hasLat = (parts.indexOf('lat') !== -1);
var hasText = (parts.indexOf('text') !== -1);
var text = [];
function format(val) { return val + '\u00B0'; }
if(hasLocation) {
text.push(pt.loc);
} else if(hasLon && hasLat) {
text.push('(' + format(pointData.latLabel) + ', ' + format(pointData.lonLabel) + ')');
} else if(hasLon) {
text.push(labels.lon + format(pointData.lonLabel));
} else if(hasLat) {
text.push(labels.lat + format(pointData.latLabel));
}
if(hasText) {
fillText(pt, trace, text);
}
return text.join('<br>');
}