Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit c53ae17

Browse filesBrowse files
authored
Merge pull request plotly#1582 from plotly/hoverlabel-custom
Custom trace hover labels
2 parents 9d149c3 + 3f52a89 commit c53ae17
Copy full SHA for c53ae17

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Dismiss banner

58 files changed

+2674
-1590
lines changed

‎src/components/annotations/annotation_defaults.js

Copy file name to clipboardExpand all lines: src/components/annotations/annotation_defaults.js
+13-7Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
var Lib = require('../../lib');
1313
var Color = require('../color');
1414
var Axes = require('../../plots/cartesian/axes');
15-
var constants = require('../../plots/cartesian/constants');
1615

1716
var attributes = require('./attributes');
1817

@@ -113,14 +112,21 @@ module.exports = function handleAnnotationDefaults(annIn, annOut, fullLayout, op
113112
}
114113

115114
var hoverText = coerce('hovertext');
115+
var globalHoverLabel = fullLayout.hoverlabel || {};
116+
116117
if(hoverText) {
117-
var hoverBG = coerce('hoverlabel.bgcolor',
118-
Color.opacity(bgColor) ? Color.rgb(bgColor) : Color.defaultLine);
119-
var hoverBorder = coerce('hoverlabel.bordercolor', Color.contrast(hoverBG));
118+
var hoverBG = coerce('hoverlabel.bgcolor', globalHoverLabel.bgcolor ||
119+
(Color.opacity(bgColor) ? Color.rgb(bgColor) : Color.defaultLine)
120+
);
121+
122+
var hoverBorder = coerce('hoverlabel.bordercolor', globalHoverLabel.bordercolor ||
123+
Color.contrast(hoverBG)
124+
);
125+
120126
Lib.coerceFont(coerce, 'hoverlabel.font', {
121-
family: constants.HOVERFONT,
122-
size: constants.HOVERFONTSIZE,
123-
color: hoverBorder
127+
family: globalHoverLabel.font.family,
128+
size: globalHoverLabel.font.size,
129+
color: globalHoverLabel.font.color || hoverBorder
124130
});
125131
}
126132
coerce('captureevents', !!hoverText);

‎src/components/annotations/draw.js

Copy file name to clipboardExpand all lines: src/components/annotations/draw.js
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ var Plotly = require('../../plotly');
1515
var Plots = require('../../plots/plots');
1616
var Lib = require('../../lib');
1717
var Axes = require('../../plots/cartesian/axes');
18-
var Fx = require('../../plots/cartesian/graph_interact');
1918
var Color = require('../color');
2019
var Drawing = require('../drawing');
20+
var Fx = require('../fx');
2121
var svgTextUtils = require('../../lib/svg_text_utils');
2222
var setCursor = require('../../lib/setcursor');
2323
var dragElement = require('../dragelement');

‎src/components/fx/attributes.js

Copy file name to clipboard
+38Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* Copyright 2012-2017, Plotly, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
'use strict';
10+
11+
var extendFlat = require('../../lib/extend').extendFlat;
12+
var fontAttrs = require('../../plots/font_attributes');
13+
14+
module.exports = {
15+
hoverlabel: {
16+
bgcolor: {
17+
valType: 'color',
18+
role: 'style',
19+
arrayOk: true,
20+
description: [
21+
'Sets the background color of the hover labels for this trace'
22+
].join(' ')
23+
},
24+
bordercolor: {
25+
valType: 'color',
26+
role: 'style',
27+
arrayOk: true,
28+
description: [
29+
'Sets the border color of the hover labels for this trace.'
30+
].join(' ')
31+
},
32+
font: {
33+
family: extendFlat({}, fontAttrs.family, { arrayOk: true }),
34+
size: extendFlat({}, fontAttrs.size, { arrayOk: true }),
35+
color: extendFlat({}, fontAttrs.color, { arrayOk: true })
36+
}
37+
}
38+
};

‎src/components/fx/calc.js

Copy file name to clipboard
+37Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* Copyright 2012-2017, Plotly, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
'use strict';
10+
11+
var Lib = require('../../lib');
12+
var Registry = require('../../registry');
13+
14+
module.exports = function calc(gd) {
15+
var calcdata = gd.calcdata;
16+
17+
for(var i = 0; i < calcdata.length; i++) {
18+
var cd = calcdata[i];
19+
var trace = cd[0].trace;
20+
21+
if(!trace.hoverlabel) continue;
22+
23+
var mergeFn = Registry.traceIs(trace, '2dMap') ? paste : Lib.mergeArray;
24+
25+
mergeFn(trace.hoverlabel.bgcolor, cd, 'hbg');
26+
mergeFn(trace.hoverlabel.bordercolor, cd, 'hbc');
27+
mergeFn(trace.hoverlabel.font.size, cd, 'hts');
28+
mergeFn(trace.hoverlabel.font.color, cd, 'htc');
29+
mergeFn(trace.hoverlabel.font.family, cd, 'htf');
30+
}
31+
};
32+
33+
function paste(traceAttr, cd, cdAttr) {
34+
if(Array.isArray(traceAttr)) {
35+
cd[0][cdAttr] = traceAttr;
36+
}
37+
}

‎src/components/fx/click.js

Copy file name to clipboard
+27Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/**
2+
* Copyright 2012-2017, Plotly, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
'use strict';
10+
11+
var Registry = require('../../registry');
12+
13+
module.exports = function click(gd, evt) {
14+
var annotationsDone = Registry.getComponentMethod('annotations', 'onClick')(gd, gd._hoverdata);
15+
16+
function emitClick() { gd.emit('plotly_click', {points: gd._hoverdata, event: evt}); }
17+
18+
if(gd._hoverdata && evt && evt.target) {
19+
if(annotationsDone && annotationsDone.then) {
20+
annotationsDone.then(emitClick);
21+
}
22+
else emitClick();
23+
24+
// why do we get a double event without this???
25+
if(evt.stopImmediatePropagation) evt.stopImmediatePropagation();
26+
}
27+
};

‎src/components/fx/constants.js

Copy file name to clipboard
+30Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* Copyright 2012-2017, Plotly, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
'use strict';
10+
11+
module.exports = {
12+
// max pixels away from mouse to allow a point to highlight
13+
MAXDIST: 20,
14+
15+
// hover labels for multiple horizontal bars get tilted by this angle
16+
YANGLE: 60,
17+
18+
// size and display constants for hover text
19+
20+
// pixel size of hover arrows
21+
HOVERARROWSIZE: 6,
22+
// pixels padding around text
23+
HOVERTEXTPAD: 3,
24+
// hover font
25+
HOVERFONTSIZE: 13,
26+
HOVERFONT: 'Arial, sans-serif',
27+
28+
// minimum time (msec) between hover calls
29+
HOVERMINTIME: 50
30+
};

‎src/components/fx/defaults.js

Copy file name to clipboard
+21Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* Copyright 2012-2017, Plotly, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
'use strict';
10+
11+
var Lib = require('../../lib');
12+
var attributes = require('./attributes');
13+
var handleHoverLabelDefaults = require('./hoverlabel_defaults');
14+
15+
module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {
16+
function coerce(attr, dflt) {
17+
return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);
18+
}
19+
20+
handleHoverLabelDefaults(traceIn, traceOut, coerce, layout.hoverlabel);
21+
};

‎src/components/fx/helpers.js

Copy file name to clipboard
+85Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/**
2+
* Copyright 2012-2017, Plotly, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
'use strict';
10+
11+
var constants = require('./constants');
12+
13+
// look for either subplot or xaxis and yaxis attributes
14+
exports.getSubplot = function getSubplot(trace) {
15+
return trace.subplot || (trace.xaxis + trace.yaxis) || trace.geo;
16+
};
17+
18+
// convenience functions for mapping all relevant axes
19+
exports.flat = function flat(subplots, v) {
20+
var out = new Array(subplots.length);
21+
for(var i = 0; i < subplots.length; i++) {
22+
out[i] = v;
23+
}
24+
return out;
25+
};
26+
27+
exports.p2c = function p2c(axArray, v) {
28+
var out = new Array(axArray.length);
29+
for(var i = 0; i < axArray.length; i++) {
30+
out[i] = axArray[i].p2c(v);
31+
}
32+
return out;
33+
};
34+
35+
exports.getDistanceFunction = function getDistanceFunction(mode, dx, dy, dxy) {
36+
if(mode === 'closest') return dxy || quadrature(dx, dy);
37+
return mode === 'x' ? dx : dy;
38+
};
39+
40+
exports.getClosest = function getClosest(cd, distfn, pointData) {
41+
// do we already have a point number? (array mode only)
42+
if(pointData.index !== false) {
43+
if(pointData.index >= 0 && pointData.index < cd.length) {
44+
pointData.distance = 0;
45+
}
46+
else pointData.index = false;
47+
}
48+
else {
49+
// apply the distance function to each data point
50+
// this is the longest loop... if this bogs down, we may need
51+
// to create pre-sorted data (by x or y), not sure how to
52+
// do this for 'closest'
53+
for(var i = 0; i < cd.length; i++) {
54+
var newDistance = distfn(cd[i]);
55+
if(newDistance <= pointData.distance) {
56+
pointData.index = i;
57+
pointData.distance = newDistance;
58+
}
59+
}
60+
}
61+
return pointData;
62+
};
63+
64+
// for bar charts and others with finite-size objects: you must be inside
65+
// it to see its hover info, so distance is infinite outside.
66+
// But make distance inside be at least 1/4 MAXDIST, and a little bigger
67+
// for bigger bars, to prioritize scatter and smaller bars over big bars
68+
//
69+
// note that for closest mode, two inbox's will get added in quadrature
70+
// args are (signed) difference from the two opposite edges
71+
// count one edge as in, so that over continuous ranges you never get a gap
72+
exports.inbox = function inbox(v0, v1) {
73+
if(v0 * v1 < 0 || v0 === 0) {
74+
return constants.MAXDIST * (0.6 - 0.3 / Math.max(3, Math.abs(v0 - v1)));
75+
}
76+
return Infinity;
77+
};
78+
79+
function quadrature(dx, dy) {
80+
return function(di) {
81+
var x = dx(di),
82+
y = dy(di);
83+
return Math.sqrt(x * x + y * y);
84+
};
85+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.