Skip to content

Commit fef1c60

Browse files
authored
Merge pull request #3965 from plotly/one-more-hoverAvoirOverlap-fix
More zoomed-in box/violin hover labels fixes
2 parents 411f61e + ce5e5f9 commit fef1c60

File tree

4 files changed

+38
-16
lines changed

4 files changed

+38
-16
lines changed

src/components/fx/hover.js

+13-9
Original file line numberDiff line numberDiff line change
@@ -839,10 +839,11 @@ function createHoverText(hoverData, opts, gd) {
839839

840840
// show all the individual labels
841841

842-
843842
// first create the objects
844843
var hoverLabels = container.selectAll('g.hovertext')
845844
.data(hoverData, function(d) {
845+
// N.B. when multiple items have the same result key-function value,
846+
// only the first of those items in hoverData gets rendered
846847
return [d.trace.index, d.index, d.x0, d.y0, d.name, d.attr, d.xa, d.ya || ''].join(',');
847848
});
848849
hoverLabels.enter().append('g')
@@ -1059,22 +1060,25 @@ function createHoverText(hoverData, opts, gd) {
10591060
// know what happens if the group spans all the way from one edge to
10601061
// the other, though it hardly matters - there's just too much
10611062
// information then.
1062-
function hoverAvoidOverlaps(hoverLabels, ax, fullLayout) {
1063+
function hoverAvoidOverlaps(hoverLabels, axKey, fullLayout) {
10631064
var nummoves = 0;
10641065
var axSign = 1;
10651066
var nLabels = hoverLabels.size();
10661067

10671068
// make groups of touching points
10681069
var pointgroups = new Array(nLabels);
1070+
var k = 0;
1071+
1072+
hoverLabels.each(function(d) {
1073+
var ax = d[axKey];
1074+
var axIsX = ax._id.charAt(0) === 'x';
1075+
var rng = ax.range;
10691076

1070-
hoverLabels.each(function(d, i) {
1071-
var axis = d[ax];
1072-
var axIsX = axis._id.charAt(0) === 'x';
1073-
var rng = axis.range;
1074-
if(!i && rng && ((rng[0] > rng[1]) !== axIsX)) axSign = -1;
1075-
pointgroups[i] = [{
1077+
if(k === 0 && rng && ((rng[0] > rng[1]) !== axIsX)) {
1078+
axSign = -1;
1079+
}
1080+
pointgroups[k++] = [{
10761081
datum: d,
1077-
i: i,
10781082
traceIndex: d.trace.index,
10791083
dp: 0,
10801084
pos: d.pos,

src/traces/box/hover.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ function hoverOnBoxes(pointData, xval, yval, hovermode) {
151151

152152
// box plots: each "point" gets many labels
153153
var usedVals = {};
154-
var attrs = ['med', 'min', 'q1', 'q3', 'max'];
154+
var attrs = ['med', 'q1', 'q3', 'min', 'max'];
155155

156156
if(trace.boxmean || (trace.meanline || {}).visible) {
157157
attrs.push('mean');
@@ -171,6 +171,7 @@ function hoverOnBoxes(pointData, xval, yval, hovermode) {
171171
var valPx = vAxis.c2p(val, true);
172172
var pointData2 = Lib.extendFlat({}, pointData);
173173

174+
pointData2.attr = attr;
174175
pointData2[vLetter + '0'] = pointData2[vLetter + '1'] = valPx;
175176
pointData2[vLetter + 'LabelVal'] = val;
176177
pointData2[vLetter + 'Label'] = (t.labels ? t.labels[attr] + ' ' : '') + Axes.hoverLabelText(vAxis, val);

test/jasmine/tests/box_test.js

+19-2
Original file line numberDiff line numberDiff line change
@@ -274,8 +274,8 @@ describe('Test box hover:', function() {
274274
return fig;
275275
},
276276
nums: [
277-
'q1: 0.3', 'median: 0.45', 'q3: 0.6', 'max: 1', 'median: 0.55', 'min: 0', 'min: 0.2',
278-
'q3: 0.6', 'max: 0.7', 'median: 0.45', 'min: 0.1', 'q3: 0.6', 'max: 0.9'
277+
'q1: 0.3', 'median: 0.45', 'q3: 0.6', 'max: 1', 'median: 0.55', 'min: 0', 'q1: 0.1',
278+
'q3: 0.6', 'max: 0.7', 'median: 0.45', 'q1: 0.2', 'q3: 0.6', 'max: 0.9'
279279
],
280280
name: [
281281
'', 'kale', '', '', 'radishes', '', '',
@@ -437,6 +437,23 @@ describe('Test box hover:', function() {
437437
},
438438
nums: '0.6',
439439
name: 'pt #0'
440+
}, {
441+
desc: 'when zoomed in, within q1-q3 making min/q1 and max/q3 overlap',
442+
mock: {
443+
data: [{
444+
type: 'box',
445+
y: [1, 2, 2, 3]
446+
}],
447+
layout: {
448+
yaxis: {range: [1.6, 2.4]},
449+
width: 400,
450+
height: 400
451+
}
452+
},
453+
pos: [200, 200],
454+
nums: ['median: 2', 'q1: 1.5', 'q3: 2.5', 'max: 3', 'min: 1'],
455+
name: ['', '', '', '', ''],
456+
axis: 'trace 0'
440457
}].forEach(function(specs) {
441458
it('should generate correct hover labels ' + specs.desc, function(done) {
442459
run(specs).catch(failTest).then(done);

test/jasmine/tests/violin_test.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -388,8 +388,8 @@ describe('Test violin hover:', function() {
388388
},
389389
nums: [
390390
'q3: 0.6', 'median: 0.45', 'q3: 0.6', 'max: 1', 'y: 0.9266848, kde: 0.383',
391-
'median: 0.55', 'min: 0', 'q1: 0.3', 'min: 0.2', 'max: 0.7', 'y: 0.9266848, kde: 0.182',
392-
'median: 0.45', 'min: 0.1', 'q3: 0.6', 'max: 0.9', 'y: 0.9266848, kde: 0.435'
391+
'median: 0.55', 'min: 0', 'q1: 0.3', 'q1: 0.2', 'max: 0.7', 'y: 0.9266848, kde: 0.182',
392+
'median: 0.45', 'q1: 0.1', 'q3: 0.6', 'max: 0.9', 'y: 0.9266848, kde: 0.435'
393393
],
394394
name: [
395395
'', 'kale', '', '', '', 'radishes', '', '', '', '',
@@ -535,7 +535,7 @@ describe('Test violin hover:', function() {
535535
name: ['', '', '', '', '', ''],
536536
axis: 'Sat',
537537
hoverLabelPos: [
538-
[364, 270], [339, 270], [352, 270],
538+
[364, 270], [352, 270], [339, 270],
539539
[346, 270], [349, 270], [387, 270]
540540
]
541541
}, {
@@ -745,7 +745,7 @@ describe('Test violin hover:', function() {
745745

746746
actual = actual.sort(function(a, b) { return a[1].top - b[1].top; });
747747

748-
expect(actual.length).toBe(7, '# of value hover labels');
748+
expect(actual.length).toBe(8, '# of value hover labels');
749749

750750
for(var i = 0; i < actual.length - 1; i++) {
751751
var a = actual[i];

0 commit comments

Comments
 (0)