Skip to content

Commit

Permalink
Merge pull request #3965 from plotly/one-more-hoverAvoirOverlap-fix
Browse files Browse the repository at this point in the history
More zoomed-in box/violin hover labels fixes
  • Loading branch information
etpinard committed Jun 25, 2019
2 parents 411f61e + ce5e5f9 commit fef1c60
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 16 deletions.
22 changes: 13 additions & 9 deletions src/components/fx/hover.js
Original file line number Diff line number Diff line change
Expand Up @@ -839,10 +839,11 @@ function createHoverText(hoverData, opts, gd) {

// show all the individual labels


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

// make groups of touching points
var pointgroups = new Array(nLabels);
var k = 0;

hoverLabels.each(function(d) {
var ax = d[axKey];
var axIsX = ax._id.charAt(0) === 'x';
var rng = ax.range;

hoverLabels.each(function(d, i) {
var axis = d[ax];
var axIsX = axis._id.charAt(0) === 'x';
var rng = axis.range;
if(!i && rng && ((rng[0] > rng[1]) !== axIsX)) axSign = -1;
pointgroups[i] = [{
if(k === 0 && rng && ((rng[0] > rng[1]) !== axIsX)) {
axSign = -1;
}
pointgroups[k++] = [{
datum: d,
i: i,
traceIndex: d.trace.index,
dp: 0,
pos: d.pos,
Expand Down
3 changes: 2 additions & 1 deletion src/traces/box/hover.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ function hoverOnBoxes(pointData, xval, yval, hovermode) {

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

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

pointData2.attr = attr;
pointData2[vLetter + '0'] = pointData2[vLetter + '1'] = valPx;
pointData2[vLetter + 'LabelVal'] = val;
pointData2[vLetter + 'Label'] = (t.labels ? t.labels[attr] + ' ' : '') + Axes.hoverLabelText(vAxis, val);
Expand Down
21 changes: 19 additions & 2 deletions test/jasmine/tests/box_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,8 @@ describe('Test box hover:', function() {
return fig;
},
nums: [
'q1: 0.3', 'median: 0.45', 'q3: 0.6', 'max: 1', 'median: 0.55', 'min: 0', 'min: 0.2',
'q3: 0.6', 'max: 0.7', 'median: 0.45', 'min: 0.1', 'q3: 0.6', 'max: 0.9'
'q1: 0.3', 'median: 0.45', 'q3: 0.6', 'max: 1', 'median: 0.55', 'min: 0', 'q1: 0.1',
'q3: 0.6', 'max: 0.7', 'median: 0.45', 'q1: 0.2', 'q3: 0.6', 'max: 0.9'
],
name: [
'', 'kale', '', '', 'radishes', '', '',
Expand Down Expand Up @@ -437,6 +437,23 @@ describe('Test box hover:', function() {
},
nums: '0.6',
name: 'pt #0'
}, {
desc: 'when zoomed in, within q1-q3 making min/q1 and max/q3 overlap',
mock: {
data: [{
type: 'box',
y: [1, 2, 2, 3]
}],
layout: {
yaxis: {range: [1.6, 2.4]},
width: 400,
height: 400
}
},
pos: [200, 200],
nums: ['median: 2', 'q1: 1.5', 'q3: 2.5', 'max: 3', 'min: 1'],
name: ['', '', '', '', ''],
axis: 'trace 0'
}].forEach(function(specs) {
it('should generate correct hover labels ' + specs.desc, function(done) {
run(specs).catch(failTest).then(done);
Expand Down
8 changes: 4 additions & 4 deletions test/jasmine/tests/violin_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -388,8 +388,8 @@ describe('Test violin hover:', function() {
},
nums: [
'q3: 0.6', 'median: 0.45', 'q3: 0.6', 'max: 1', 'y: 0.9266848, kde: 0.383',
'median: 0.55', 'min: 0', 'q1: 0.3', 'min: 0.2', 'max: 0.7', 'y: 0.9266848, kde: 0.182',
'median: 0.45', 'min: 0.1', 'q3: 0.6', 'max: 0.9', 'y: 0.9266848, kde: 0.435'
'median: 0.55', 'min: 0', 'q1: 0.3', 'q1: 0.2', 'max: 0.7', 'y: 0.9266848, kde: 0.182',
'median: 0.45', 'q1: 0.1', 'q3: 0.6', 'max: 0.9', 'y: 0.9266848, kde: 0.435'
],
name: [
'', 'kale', '', '', '', 'radishes', '', '', '', '',
Expand Down Expand Up @@ -535,7 +535,7 @@ describe('Test violin hover:', function() {
name: ['', '', '', '', '', ''],
axis: 'Sat',
hoverLabelPos: [
[364, 270], [339, 270], [352, 270],
[364, 270], [352, 270], [339, 270],
[346, 270], [349, 270], [387, 270]
]
}, {
Expand Down Expand Up @@ -745,7 +745,7 @@ describe('Test violin hover:', function() {

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

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

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

0 comments on commit fef1c60

Please sign in to comment.