Skip to content

Commit 59f664c

Browse files
authored
Merge pull request #5854 from Domino987/patch-2
Skip hoverinfo none trace display for hover modes
2 parents edb4196 + 0d9a1be commit 59f664c

File tree

3 files changed

+50
-12
lines changed

3 files changed

+50
-12
lines changed

Diff for: draftlogs/5854_fix.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Skip `"hoverinfo": "none"` trace display for hover modes [[#5854](https://github.com/plotly/plotly.js/pull/5854)], with thanks to @Domino987 for the contribution!

Diff for: src/components/fx/hover.js

+17-12
Original file line numberDiff line numberDiff line change
@@ -879,6 +879,8 @@ function createHoverText(hoverData, opts) {
879879
var container = opts.container;
880880
var outerContainer = opts.outerContainer;
881881
var commonLabelOpts = opts.commonLabelOpts || {};
882+
// Early exit if no labels are drawn
883+
if(hoverData.length === 0) return [[]];
882884

883885
// opts.fontFamily/Size are used for the common label
884886
// and as defaults for each hover label, though the individual labels
@@ -1085,9 +1087,9 @@ function createHoverText(hoverData, opts) {
10851087
if(helpers.isUnifiedHover(hovermode)) {
10861088
// Delete leftover hover labels from other hovermodes
10871089
container.selectAll('g.hovertext').remove();
1088-
1090+
var groupedHoverData = hoverData.filter(function(data) {return data.hoverinfo !== 'none';});
10891091
// Return early if nothing is hovered on
1090-
if(hoverData.length === 0) return;
1092+
if(groupedHoverData.length === 0) return;
10911093

10921094
// mock legend
10931095
var hoverlabel = fullLayout.hoverlabel;
@@ -1111,11 +1113,14 @@ function createHoverText(hoverData, opts) {
11111113

11121114
// prepare items for the legend
11131115
mockLegend.entries = [];
1114-
for(var j = 0; j < hoverData.length; j++) {
1115-
var texts = getHoverLabelText(hoverData[j], true, hovermode, fullLayout, t0);
1116+
for(var j = 0; j < groupedHoverData.length; j++) {
1117+
var pt = groupedHoverData[j];
1118+
if(pt.hoverinfo === 'none') continue;
1119+
1120+
var texts = getHoverLabelText(pt, true, hovermode, fullLayout, t0);
11161121
var text = texts[0];
11171122
var name = texts[1];
1118-
var pt = hoverData[j];
1123+
11191124
pt.name = name;
11201125
if(name !== '') {
11211126
pt.text = name + ' : ' + text;
@@ -1151,7 +1156,7 @@ function createHoverText(hoverData, opts) {
11511156
var tbb = getBoundingClientRect(gd, legendContainer.node());
11521157
var tWidth = tbb.width + 2 * HOVERTEXTPAD;
11531158
var tHeight = tbb.height + 2 * HOVERTEXTPAD;
1154-
var winningPoint = hoverData[0];
1159+
var winningPoint = groupedHoverData[0];
11551160
var avgX = (winningPoint.x0 + winningPoint.x1) / 2;
11561161
var avgY = (winningPoint.y0 + winningPoint.y1) / 2;
11571162
// When a scatter (or e.g. heatmap) point wins, it's OK for the hovelabel to occlude the bar and other points.
@@ -1166,11 +1171,11 @@ function createHoverText(hoverData, opts) {
11661171
lyTop = avgY - HOVERTEXTPAD;
11671172
lyBottom = avgY + HOVERTEXTPAD;
11681173
} else {
1169-
lyTop = Math.min.apply(null, hoverData.map(function(c) { return Math.min(c.y0, c.y1); }));
1170-
lyBottom = Math.max.apply(null, hoverData.map(function(c) { return Math.max(c.y0, c.y1); }));
1174+
lyTop = Math.min.apply(null, groupedHoverData.map(function(c) { return Math.min(c.y0, c.y1); }));
1175+
lyBottom = Math.max.apply(null, groupedHoverData.map(function(c) { return Math.max(c.y0, c.y1); }));
11711176
}
11721177
} else {
1173-
lyTop = lyBottom = Lib.mean(hoverData.map(function(c) { return (c.y0 + c.y1) / 2; })) - tHeight / 2;
1178+
lyTop = lyBottom = Lib.mean(groupedHoverData.map(function(c) { return (c.y0 + c.y1) / 2; })) - tHeight / 2;
11741179
}
11751180

11761181
var lxRight, lxLeft;
@@ -1179,11 +1184,11 @@ function createHoverText(hoverData, opts) {
11791184
lxRight = avgX + HOVERTEXTPAD;
11801185
lxLeft = avgX - HOVERTEXTPAD;
11811186
} else {
1182-
lxRight = Math.max.apply(null, hoverData.map(function(c) { return Math.max(c.x0, c.x1); }));
1183-
lxLeft = Math.min.apply(null, hoverData.map(function(c) { return Math.min(c.x0, c.x1); }));
1187+
lxRight = Math.max.apply(null, groupedHoverData.map(function(c) { return Math.max(c.x0, c.x1); }));
1188+
lxLeft = Math.min.apply(null, groupedHoverData.map(function(c) { return Math.min(c.x0, c.x1); }));
11841189
}
11851190
} else {
1186-
lxRight = lxLeft = Lib.mean(hoverData.map(function(c) { return (c.x0 + c.x1) / 2; })) - tWidth / 2;
1191+
lxRight = lxLeft = Lib.mean(groupedHoverData.map(function(c) { return (c.x0 + c.x1) / 2; })) - tWidth / 2;
11871192
}
11881193

11891194
var xOffset = xa._offset;

Diff for: test/jasmine/tests/hover_label_test.js

+32
Original file line numberDiff line numberDiff line change
@@ -4592,6 +4592,38 @@ describe('hovermode: (x|y)unified', function() {
45924592
.then(done, done.fail);
45934593
});
45944594

4595+
it('should not display hover for display: none', function(done) {
4596+
Plotly.newPlot(gd, {
4597+
data: [{
4598+
name: 'A',
4599+
y: [1]
4600+
}, {
4601+
name: 'B',
4602+
y: [2],
4603+
hoverinfo: 'none'
4604+
}],
4605+
layout: {
4606+
hovermode: 'x unified',
4607+
showlegend: false,
4608+
width: 500,
4609+
height: 500,
4610+
margin: {
4611+
t: 50,
4612+
b: 50,
4613+
l: 50,
4614+
r: 50
4615+
}
4616+
}
4617+
})
4618+
.then(function() {
4619+
_hover(gd, { xpx: 200, ypx: 200 });
4620+
assertLabel({title: '0', items: [
4621+
'A : 1'
4622+
]});
4623+
})
4624+
.then(done, done.fail);
4625+
});
4626+
45954627
it('y unified should work for x/y cartesian traces', function(done) {
45964628
var mockCopy = Lib.extendDeep({}, mock);
45974629
mockCopy.layout.hovermode = 'y unified';

0 commit comments

Comments
 (0)