Skip to content

Commit eb98c91

Browse files
committed
fix #2370
1 parent ad38f8d commit eb98c91

File tree

2 files changed

+47
-19
lines changed

2 files changed

+47
-19
lines changed

src/components/fx/hover.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -1190,7 +1190,9 @@ function cleanPoint(d, hovermode) {
11901190
fill('fontColor', 'htc', 'hoverlabel.font.color');
11911191
fill('nameLength', 'hnl', 'hoverlabel.namelength');
11921192

1193-
d.posref = hovermode === 'y' ? (d.x0 + d.x1) / 2 : (d.y0 + d.y1) / 2;
1193+
d.posref = hovermode === 'y' ?
1194+
(d.xa._offset + (d.x0 + d.x1) / 2) :
1195+
(d.ya._offset + (d.y0 + d.y1) / 2);
11941196

11951197
// then constrain all the positions to be on the plot
11961198
d.x0 = Lib.constrain(d.x0, 0, d.xa._length);

test/jasmine/tests/hover_label_test.js

+44-18
Original file line numberDiff line numberDiff line change
@@ -1082,42 +1082,68 @@ describe('hover info on stacked subplots', function() {
10821082
afterEach(destroyGraphDiv);
10831083

10841084
describe('hover info on stacked subplots with shared x-axis', function() {
1085-
var mock = require('@mocks/stacked_coupled_subplots.json');
1085+
var mock = Lib.extendDeep({},
1086+
require('@mocks/stacked_coupled_subplots.json'),
1087+
{data: [
1088+
// Tweak the mock so the higher subplot sometimes has points
1089+
// higher *within the subplot*, sometimes lower.
1090+
// This was the problem in #2370
1091+
{}, {y: [100, 120, 100]}
1092+
]});
1093+
1094+
var gd;
10861095

10871096
beforeEach(function(done) {
1088-
Plotly.plot(createGraphDiv(), mock.data, mock.layout).then(done);
1097+
gd = createGraphDiv();
1098+
Plotly.plot(gd, mock.data, mock.layout).then(done);
10891099
});
10901100

1091-
it('responds to hover', function() {
1092-
var gd = document.getElementById('graph');
1093-
Plotly.Fx.hover(gd, {xval: 3}, ['xy', 'xy2', 'xy3']);
1101+
function _check(xval, ptSpec1, ptSpec2) {
1102+
Lib.clearThrottle();
1103+
Plotly.Fx.hover(gd, {xval: xval}, ['xy', 'xy2', 'xy3']);
10941104

1095-
expect(gd._hoverdata.length).toEqual(2);
1105+
expect(gd._hoverdata.length).toBe(2);
10961106

10971107
expect(gd._hoverdata[0]).toEqual(jasmine.objectContaining(
10981108
{
1099-
curveNumber: 1,
1100-
pointNumber: 1,
1101-
x: 3,
1102-
y: 110
1109+
curveNumber: ptSpec1[0],
1110+
pointNumber: ptSpec1[1],
1111+
x: xval,
1112+
y: ptSpec1[2]
11031113
}));
11041114

11051115
expect(gd._hoverdata[1]).toEqual(jasmine.objectContaining(
11061116
{
1107-
curveNumber: 2,
1108-
pointNumber: 0,
1109-
x: 3,
1110-
y: 1000
1117+
curveNumber: ptSpec2[0],
1118+
pointNumber: ptSpec2[1],
1119+
x: xval,
1120+
y: ptSpec2[2]
11111121
}));
11121122

11131123
assertHoverLabelContent({
11141124
// There should be 2 pts being hovered over,
11151125
// in two different traces, one in each plot.
1116-
nums: ['110', '1000'],
1117-
name: ['trace 1', 'trace 2'],
1118-
// There should be a single label on the x-axis with the shared x value, 3'
1119-
axis: '3'
1126+
nums: [String(ptSpec1[2]), String(ptSpec2[2])],
1127+
name: [ptSpec1[3], ptSpec2[3]],
1128+
// There should be a single label on the x-axis with the shared x value
1129+
axis: String(xval)
11201130
});
1131+
1132+
// ensure the hover label bounding boxes don't overlap, except a little margin of 5 px
1133+
// testing #2370
1134+
var bBoxes = [];
1135+
d3.selectAll('g.hovertext').each(function() {
1136+
bBoxes.push(this.getBoundingClientRect());
1137+
});
1138+
expect(bBoxes.length).toBe(2);
1139+
var disjointY = bBoxes[0].top >= bBoxes[1].bottom - 5 || bBoxes[1].top >= bBoxes[0].bottom - 5;
1140+
expect(disjointY).toBe(true, bBoxes.map(function(bb) { return {top: bb.top, bottom: bb.bottom}; }));
1141+
}
1142+
1143+
it('responds to hover and keeps the labels from crossing', function() {
1144+
_check(2, [0, 2, 12, 'trace 0'], [1, 0, 100, 'trace 1']);
1145+
_check(3, [1, 1, 120, 'trace 1'], [2, 0, 1000, 'trace 2']);
1146+
_check(4, [1, 2, 100, 'trace 1'], [2, 1, 1100, 'trace 2']);
11211147
});
11221148
});
11231149

0 commit comments

Comments
 (0)