Skip to content

Commit 8731cb5

Browse files
authored
Merge pull request #2440 from plotly/fix-centered-tooltip-layout
Fix layout of centered hover info #2154
2 parents 12e69c8 + 0dd85fa commit 8731cb5

File tree

2 files changed

+89
-2
lines changed

2 files changed

+89
-2
lines changed

src/components/fx/hover.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -1126,7 +1126,7 @@ function alignHoverText(hoverLabels, rotateLabels) {
11261126
offsetY = d.offset;
11271127
if(d.anchor === 'middle') {
11281128
txx -= d.tx2width / 2;
1129-
tx2x -= d.tx2width / 2;
1129+
tx2x += d.txwidth / 2 + HOVERTEXTPAD;
11301130
}
11311131
if(rotateLabels) {
11321132
offsetY *= -YSHIFTY;
@@ -1135,7 +1135,8 @@ function alignHoverText(hoverLabels, rotateLabels) {
11351135

11361136
g.select('path').attr('d', d.anchor === 'middle' ?
11371137
// middle aligned: rect centered on data
1138-
('M-' + (d.bx / 2) + ',-' + (d.by / 2) + 'h' + d.bx + 'v' + d.by + 'h-' + d.bx + 'Z') :
1138+
('M-' + (d.bx / 2 + d.tx2width / 2) + ',-' + (d.by / 2) +
1139+
'h' + d.bx + 'v' + d.by + 'h-' + d.bx + 'Z') :
11391140
// left or right aligned: side rect with arrow to data
11401141
('M0,0L' + (horzSign * HOVERARROWSIZE + offsetX) + ',' + (HOVERARROWSIZE + offsetY) +
11411142
'v' + (d.by / 2 - HOVERARROWSIZE) +

test/jasmine/tests/hover_label_test.js

+86
Original file line numberDiff line numberDiff line change
@@ -1109,6 +1109,92 @@ describe('hover info', function() {
11091109
});
11101110

11111111
});
1112+
1113+
describe('centered', function() {
1114+
var trace1 = {
1115+
x: ['giraffes'],
1116+
y: [5],
1117+
name: 'LA Zoo',
1118+
type: 'bar',
1119+
text: ['Way too long hover info!']
1120+
};
1121+
var trace2 = {
1122+
x: ['giraffes'],
1123+
y: [5],
1124+
name: 'SF Zoo',
1125+
type: 'bar',
1126+
text: ['San Francisco']
1127+
};
1128+
var data = [trace1, trace2];
1129+
var layout = {width: 600, height: 300, barmode: 'stack'};
1130+
1131+
var gd;
1132+
1133+
beforeEach(function(done) {
1134+
gd = createGraphDiv();
1135+
Plotly.plot(gd, data, layout).then(done);
1136+
});
1137+
1138+
function centeredHoverInfoNodes() {
1139+
var g = d3.selectAll('g.hoverlayer g.hovertext').filter(function() {
1140+
return !d3.select(this).select('[data-unformatted="LA Zoo"]').empty();
1141+
});
1142+
1143+
return {
1144+
primaryText: g.select('text:not([data-unformatted="LA Zoo"])').node(),
1145+
primaryBox: g.select('path').node(),
1146+
secondaryText: g.select('[data-unformatted="LA Zoo"]').node(),
1147+
secondaryBox: g.select('rect').node()
1148+
};
1149+
}
1150+
1151+
function ensureCentered(hoverInfoNodes) {
1152+
expect(hoverInfoNodes.primaryText.getAttribute('text-anchor')).toBe('middle');
1153+
expect(hoverInfoNodes.secondaryText.getAttribute('text-anchor')).toBe('middle');
1154+
return hoverInfoNodes;
1155+
}
1156+
1157+
function assertElemInside(elem, container, msg) {
1158+
var elemBB = elem.getBoundingClientRect();
1159+
var contBB = container.getBoundingClientRect();
1160+
expect(contBB.left < elemBB.left &&
1161+
contBB.right > elemBB.right &&
1162+
contBB.top < elemBB.top &&
1163+
contBB.bottom > elemBB.bottom).toBe(true, msg);
1164+
}
1165+
1166+
function assertElemRightTo(elem, refElem, msg) {
1167+
var elemBB = elem.getBoundingClientRect();
1168+
var refElemBB = refElem.getBoundingClientRect();
1169+
expect(elemBB.left >= refElemBB.right).toBe(true, msg);
1170+
}
1171+
1172+
function assertTopsAligned(elem1, elem2, msg) {
1173+
var elem1BB = elem1.getBoundingClientRect();
1174+
var elem2BB = elem2.getBoundingClientRect();
1175+
1176+
// Hint: toBeWithin tolerance is exclusive, hence a
1177+
// diff of exactly 1 would fail the test
1178+
var tolerance = 1.1;
1179+
expect(elem1BB.top - elem2BB.top).toBeWithin(0, tolerance, msg);
1180+
}
1181+
1182+
it('renders labels inside boxes', function() {
1183+
_hover(gd, 300, 150);
1184+
1185+
var nodes = ensureCentered(centeredHoverInfoNodes());
1186+
assertElemInside(nodes.primaryText, nodes.primaryBox, 'Primary text inside box');
1187+
assertElemInside(nodes.secondaryText, nodes.secondaryBox, 'Secondary text inside box');
1188+
});
1189+
1190+
it('renders secondary info box right to primary info box', function() {
1191+
_hover(gd, 300, 150);
1192+
1193+
var nodes = ensureCentered(centeredHoverInfoNodes());
1194+
assertElemRightTo(nodes.secondaryBox, nodes.primaryBox, 'Secondary box right to primary box');
1195+
assertTopsAligned(nodes.secondaryBox, nodes.primaryBox, 'Top edges of primary and secondary boxes aligned');
1196+
});
1197+
});
11121198
});
11131199

11141200
describe('hover info on stacked subplots', function() {

0 commit comments

Comments
 (0)