Skip to content

Commit 3d937d0

Browse files
committed
fix #3442 - consider name label height in hoverlabel y-span
1 parent beaaf16 commit 3d937d0

File tree

2 files changed

+64
-17
lines changed

2 files changed

+64
-17
lines changed

src/components/fx/hover.js

+12-9
Original file line numberDiff line numberDiff line change
@@ -990,6 +990,7 @@ function createHoverText(hoverData, opts, gd) {
990990

991991
var tx2 = g.select('text.name');
992992
var tx2width = 0;
993+
var tx2height = 0;
993994

994995
// secondary label for non-empty 'name'
995996
if(name && name !== text) {
@@ -1001,18 +1002,20 @@ function createHoverText(hoverData, opts, gd) {
10011002
.attr('data-notex', 1)
10021003
.call(svgTextUtils.positionText, 0, 0)
10031004
.call(svgTextUtils.convertToTspans, gd);
1004-
tx2width = tx2.node().getBoundingClientRect().width + 2 * HOVERTEXTPAD;
1005-
}
1006-
else {
1005+
1006+
var t2bb = tx2.node().getBoundingClientRect();
1007+
tx2width = t2bb.width + 2 * HOVERTEXTPAD;
1008+
tx2height = t2bb.height + 2 * HOVERTEXTPAD;
1009+
} else {
10071010
tx2.remove();
10081011
g.select('rect').remove();
10091012
}
10101013

1011-
g.select('path')
1012-
.style({
1013-
fill: numsColor,
1014-
stroke: contrastColor
1015-
});
1014+
g.select('path').style({
1015+
fill: numsColor,
1016+
stroke: contrastColor
1017+
});
1018+
10161019
var tbb = tx.node().getBoundingClientRect();
10171020
var htx = d.xa._offset + (d.x0 + d.x1) / 2;
10181021
var hty = d.ya._offset + (d.y0 + d.y1) / 2;
@@ -1023,7 +1026,7 @@ function createHoverText(hoverData, opts, gd) {
10231026

10241027
d.ty0 = outerTop - tbb.top;
10251028
d.bx = tbb.width + 2 * HOVERTEXTPAD;
1026-
d.by = tbb.height + 2 * HOVERTEXTPAD;
1029+
d.by = Math.max(tbb.height + 2 * HOVERTEXTPAD, tx2height);
10271030
d.anchor = 'start';
10281031
d.txwidth = tbb.width;
10291032
d.tx2width = tx2width;

test/jasmine/tests/hover_label_test.js

+52-8
Original file line numberDiff line numberDiff line change
@@ -1476,6 +1476,14 @@ describe('hover info', function() {
14761476
msgPrefixFmt + 'Top edges of primary and secondary boxes aligned');
14771477
}
14781478

1479+
function calcLineOverlap(minA, maxA, minB, maxB) {
1480+
expect(minA).toBeLessThan(maxA);
1481+
expect(minB).toBeLessThan(maxB);
1482+
1483+
var overlap = Math.min(maxA, maxB) - Math.max(minA, minB);
1484+
return Math.max(0, overlap);
1485+
}
1486+
14791487
it('centered-aligned, should render labels inside boxes', function(done) {
14801488
var trace1 = {
14811489
x: ['giraffes'],
@@ -1506,14 +1514,6 @@ describe('hover info', function() {
15061514
});
15071515

15081516
it('centered-aligned, should stack nicely upon each other', function(done) {
1509-
function calcLineOverlap(minA, maxA, minB, maxB) {
1510-
expect(minA).toBeLessThan(maxA);
1511-
expect(minB).toBeLessThan(maxB);
1512-
1513-
var overlap = Math.min(maxA, maxB) - Math.max(minA, minB);
1514-
return Math.max(0, overlap);
1515-
}
1516-
15171517
var trace1 = {
15181518
x: ['giraffes'],
15191519
y: [5],
@@ -1561,6 +1561,50 @@ describe('hover info', function() {
15611561
.catch(failTest)
15621562
.then(done);
15631563
});
1564+
1565+
it('should stack multi-line trace-name labels nicely', function(done) {
1566+
var name = 'Multi<br>line<br>trace<br>name';
1567+
var name2 = 'Multi<br>line<br>trace<br>name2';
1568+
1569+
Plotly.plot(gd, [{
1570+
y: [1, 2, 1],
1571+
name: name,
1572+
hoverlabel: {namelength: -1},
1573+
hoverinfo: 'x+y+name'
1574+
}, {
1575+
y: [1, 2, 1],
1576+
name: name2,
1577+
hoverinfo: 'x+y+name',
1578+
hoverlabel: {namelength: -1}
1579+
}], {
1580+
width: 600,
1581+
height: 300
1582+
})
1583+
.then(function() { _hoverNatural(gd, 209, 12); })
1584+
.then(function() {
1585+
var nodes = hoverInfoNodes(name);
1586+
var nodes2 = hoverInfoNodes(name2);
1587+
1588+
assertLabelsInsideBoxes(nodes, 'trace 0');
1589+
assertLabelsInsideBoxes(nodes2, 'trace 2');
1590+
assertSecondaryRightToPrimaryBox(nodes, 'trace 0');
1591+
assertSecondaryRightToPrimaryBox(nodes2, 'trace 2');
1592+
1593+
var primaryBB = nodes.primaryBox.getBoundingClientRect();
1594+
var primaryBB2 = nodes2.primaryBox.getBoundingClientRect();
1595+
expect(calcLineOverlap(primaryBB.top, primaryBB.bottom, primaryBB2.top, primaryBB2.bottom))
1596+
.toBeWithin(0, 1);
1597+
1598+
// there's a bit of a gap in the secondary as they do have
1599+
// a border (for now)
1600+
var secondaryBB = nodes.secondaryBox.getBoundingClientRect();
1601+
var secondaryBB2 = nodes2.secondaryBox.getBoundingClientRect();
1602+
expect(calcLineOverlap(secondaryBB.top, secondaryBB.bottom, secondaryBB2.top, secondaryBB2.bottom))
1603+
.toBeWithin(2, 1);
1604+
})
1605+
.catch(failTest)
1606+
.then(done);
1607+
});
15641608
});
15651609

15661610
describe('hovertemplate', function() {

0 commit comments

Comments
 (0)