Skip to content

Commit 782bc99

Browse files
author
Daniel Gröger
committed
Apply changes only when hover labels intersect axis hover label
1 parent 126e432 commit 782bc99

File tree

1 file changed

+67
-20
lines changed

1 file changed

+67
-20
lines changed

src/components/fx/hover.js

Lines changed: 67 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -209,14 +209,15 @@ exports.loneHover = function loneHover(hoverItems, opts) {
209209

210210
var rotateLabels = false;
211211

212-
var hoverLabel = createHoverText(pointsData, {
212+
var hoverText = createHoverText(pointsData, {
213213
gd: gd,
214214
hovermode: 'closest',
215215
rotateLabels: rotateLabels,
216216
bgColor: opts.bgColor || Color.background,
217217
container: d3.select(opts.container),
218218
outerContainer: opts.outerContainer || opts.container
219219
});
220+
var hoverLabel = hoverText.hoverLabels;
220221

221222
// Fix vertical overlap
222223
var tooltipSpacing = 5;
@@ -819,7 +820,7 @@ function _hover(gd, evt, subplot, noHoverEvent, eventTarget) {
819820
fullLayout.paper_bgcolor
820821
);
821822

822-
var hoverLabels = createHoverText(hoverData, {
823+
var hoverText = createHoverText(hoverData, {
823824
gd: gd,
824825
hovermode: hovermode,
825826
rotateLabels: rotateLabels,
@@ -829,9 +830,10 @@ function _hover(gd, evt, subplot, noHoverEvent, eventTarget) {
829830
commonLabelOpts: fullLayout.hoverlabel,
830831
hoverdistance: fullLayout.hoverdistance
831832
});
833+
var hoverLabels = hoverText.hoverLabels;
832834

833835
if(!helpers.isUnifiedHover(hovermode)) {
834-
hoverAvoidOverlaps(hoverLabels, rotateLabels ? 'xa' : 'ya', fullLayout);
836+
hoverAvoidOverlaps(hoverLabels, rotateLabels ? 'xa' : 'ya', fullLayout, hoverText.commonLabel);
835837
alignHoverText(hoverLabels, rotateLabels, fullLayout._invScaleX, fullLayout._invScaleY);
836838
} // TODO: tagName hack is needed to appease geo.js's hack of using eventTarget=true
837839
// we should improve the "fx" API so other plots can use it without these hack.
@@ -942,6 +944,7 @@ function createHoverText(hoverData, opts) {
942944
.classed('axistext', true);
943945
commonLabel.exit().remove();
944946

947+
var commonLabelLx, commonLabelLy;
945948
commonLabel.each(function() {
946949
var label = d3.select(this);
947950
var lpath = Lib.ensureSingle(label, 'path', '', function(s) {
@@ -1087,6 +1090,9 @@ function createHoverText(hoverData, opts) {
10871090
}
10881091

10891092
label.attr('transform', strTranslate(lx, ly));
1093+
1094+
commonLabelLx = lx;
1095+
commonLabelLy = ly;
10901096
});
10911097

10921098
// Show a single hover label
@@ -1370,7 +1376,10 @@ function createHoverText(hoverData, opts) {
13701376
} else if(anchorStartOK) {
13711377
hty += dy / 2;
13721378
d.anchor = 'start';
1373-
} else d.anchor = 'middle';
1379+
} else {
1380+
d.anchor = 'middle';
1381+
}
1382+
d.crossPos = hty;
13741383
} else {
13751384
d.pos = hty;
13761385
anchorStartOK = htx + dx / 2 + txTotalWidth <= outerWidth;
@@ -1391,6 +1400,7 @@ function createHoverText(hoverData, opts) {
13911400
if(overflowR > 0) htx -= overflowR;
13921401
if(overflowL < 0) htx += -overflowL;
13931402
}
1403+
d.crossPos = htx;
13941404
}
13951405

13961406
tx.attr('text-anchor', d.anchor);
@@ -1399,7 +1409,14 @@ function createHoverText(hoverData, opts) {
13991409
(rotateLabels ? strRotate(YANGLE) : ''));
14001410
});
14011411

1402-
return hoverLabels;
1412+
return {
1413+
hoverLabels: hoverLabels,
1414+
commonLabel: {
1415+
lx: commonLabelLx,
1416+
ly: commonLabelLy,
1417+
label: commonLabel
1418+
}
1419+
};
14031420
}
14041421

14051422
function getHoverLabelText(d, showCommonLabel, hovermode, fullLayout, t0, g) {
@@ -1493,7 +1510,7 @@ function getHoverLabelText(d, showCommonLabel, hovermode, fullLayout, t0, g) {
14931510
// know what happens if the group spans all the way from one edge to
14941511
// the other, though it hardly matters - there's just too much
14951512
// information then.
1496-
function hoverAvoidOverlaps(hoverLabels, axKey, fullLayout) {
1513+
function hoverAvoidOverlaps(hoverLabels, axKey, fullLayout, commonLabel) {
14971514
var crossAxKey = axKey === 'xa' ? 'ya' : 'xa';
14981515
var nummoves = 0;
14991516
var axSign = 1;
@@ -1503,6 +1520,27 @@ function hoverAvoidOverlaps(hoverLabels, axKey, fullLayout) {
15031520
var pointgroups = new Array(nLabels);
15041521
var k = 0;
15051522

1523+
// get extent of axis hover label
1524+
var axisLabelMinX, axisLabelMaxX, axisLabelMinY, axisLabelMaxY;
1525+
if(commonLabel) {
1526+
commonLabel.label.each(function() {
1527+
var selection = d3.select(this);
1528+
if(selection && selection.length) {
1529+
var labels = selection[0];
1530+
if(labels && labels.length) {
1531+
var label = labels[0];
1532+
var bbox = label.getBBox();
1533+
if(bbox) {
1534+
axisLabelMinX = commonLabel.lx;
1535+
axisLabelMaxX = commonLabel.lx + bbox.width;
1536+
axisLabelMinY = commonLabel.ly;
1537+
axisLabelMaxY = commonLabel.ly + bbox.height;
1538+
}
1539+
}
1540+
}
1541+
});
1542+
}
1543+
15061544
hoverLabels.each(function(d) {
15071545
var ax = d[axKey];
15081546
var crossAx = d[crossAxKey];
@@ -1514,20 +1552,29 @@ function hoverAvoidOverlaps(hoverLabels, axKey, fullLayout) {
15141552
}
15151553
var pmin = 0;
15161554
var pmax = (axIsX ? fullLayout.width : fullLayout.height);
1517-
if (fullLayout.hovermode === 'x' || fullLayout.hovermode === 'y') {
1518-
if (axIsX) {
1519-
if (crossAx.side === 'left') {
1520-
pmin = crossAx._mainLinePosition;
1521-
pmax = fullLayout.width;
1522-
} else {
1523-
pmax = crossAx._mainLinePosition;
1555+
if(fullLayout.hovermode === 'x' || fullLayout.hovermode === 'y') {
1556+
// extent of hover label on cross axis:
1557+
var labelMinX = d.crossPos;
1558+
var labelMaxX = d.crossPos + d.txwidth;
1559+
if(axIsX) {
1560+
if(Math.max(labelMinX, axisLabelMinY) <= Math.min(labelMaxX, axisLabelMaxY)) {
1561+
// has overlap with axis label
1562+
if(crossAx.side === 'left') {
1563+
pmin = crossAx._mainLinePosition;
1564+
pmax = fullLayout.width;
1565+
} else {
1566+
pmax = crossAx._mainLinePosition;
1567+
}
15241568
}
15251569
} else {
1526-
if (crossAx.side === 'top') {
1527-
pmin = crossAx._mainLinePosition;
1528-
pmax = fullLayout.height;
1529-
} else {
1530-
pmax = crossAx._mainLinePosition;
1570+
if(Math.max(labelMinX, axisLabelMinX) <= Math.min(labelMaxX, axisLabelMaxX)) {
1571+
// has overlap with axis label
1572+
if(crossAx.side === 'top') {
1573+
pmin = crossAx._mainLinePosition;
1574+
pmax = fullLayout.height;
1575+
} else {
1576+
pmax = crossAx._mainLinePosition;
1577+
}
15311578
}
15321579
}
15331580
}
@@ -1539,8 +1586,8 @@ function hoverAvoidOverlaps(hoverLabels, axKey, fullLayout) {
15391586
pos: d.pos,
15401587
posref: d.posref,
15411588
size: d.by * (axIsX ? YFACTOR : 1) / 2,
1542-
pmin,
1543-
pmax
1589+
pmin: pmin,
1590+
pmax: pmax
15441591
}];
15451592
});
15461593

0 commit comments

Comments
 (0)