Skip to content

Commit e1084fa

Browse files
committed
fix #3618 edge for pie and sunburst
1 parent 65c2678 commit e1084fa

File tree

4 files changed

+165
-16
lines changed

4 files changed

+165
-16
lines changed

src/traces/pie/plot.js

+8-8
Original file line numberDiff line numberDiff line change
@@ -313,12 +313,12 @@ function attachFxHandlers(sliceTop, gd, cd) {
313313

314314
// hover state vars
315315
// have we drawn a hover label, so it should be cleared later
316-
var hasHoverLabel = false;
316+
if(!('_hasHoverLabel' in trace)) trace._hasHoverLabel = false;
317317
// have we emitted a hover event, so later an unhover event should be emitted
318318
// note that click events do not depend on this - you can still get them
319319
// with hovermode: false or if you were earlier dragging, then clicked
320320
// in the same slice that you moused up in
321-
var hasHoverEvent = false;
321+
if(!('_hasHoverEvent' in trace)) trace._hasHoverEvent = false;
322322

323323
sliceTop.on('mouseover', function(pt) {
324324
// in case fullLayout or fullData has changed without a replot
@@ -390,33 +390,33 @@ function attachFxHandlers(sliceTop, gd, cd) {
390390
gd: gd
391391
});
392392

393-
hasHoverLabel = true;
393+
trace._hasHoverLabel = true;
394394
}
395395

396+
trace._hasHoverEvent = true;
396397
gd.emit('plotly_hover', {
397398
points: [eventData(pt, trace2)],
398399
event: d3.event
399400
});
400-
hasHoverEvent = true;
401401
});
402402

403403
sliceTop.on('mouseout', function(evt) {
404404
var fullLayout2 = gd._fullLayout;
405405
var trace2 = gd._fullData[trace.index];
406406
var pt = d3.select(this).datum();
407407

408-
if(hasHoverEvent) {
408+
if(trace._hasHoverEvent) {
409409
evt.originalEvent = d3.event;
410410
gd.emit('plotly_unhover', {
411411
points: [eventData(pt, trace2)],
412412
event: d3.event
413413
});
414-
hasHoverEvent = false;
414+
trace._hasHoverEvent = false;
415415
}
416416

417-
if(hasHoverLabel) {
417+
if(trace._hasHoverLabel) {
418418
Fx.loneUnhover(fullLayout2._hoverlayer.node());
419-
hasHoverLabel = false;
419+
trace._hasHoverLabel = false;
420420
}
421421
});
422422

src/traces/sunburst/plot.js

+8-8
Original file line numberDiff line numberDiff line change
@@ -530,12 +530,12 @@ function attachFxHandlers(sliceTop, gd, cd) {
530530

531531
// hover state vars
532532
// have we drawn a hover label, so it should be cleared later
533-
var hasHoverLabel = false;
533+
if(!('_hasHoverLabel' in trace)) trace._hasHoverLabel = false;
534534
// have we emitted a hover event, so later an unhover event should be emitted
535535
// note that click events do not depend on this - you can still get them
536536
// with hovermode: false or if you were earlier dragging, then clicked
537537
// in the same slice that you moused up in
538-
var hasHoverEvent = false;
538+
if(!('_hasHoverEvent' in trace)) trace._hasHoverEvent = false;
539539

540540
sliceTop.on('mouseover', function(pt) {
541541
var fullLayoutNow = gd._fullLayout;
@@ -603,33 +603,33 @@ function attachFxHandlers(sliceTop, gd, cd) {
603603
gd: gd
604604
});
605605

606-
hasHoverLabel = true;
606+
trace._hasHoverLabel = true;
607607
}
608608

609+
trace._hasHoverEvent = true;
609610
gd.emit('plotly_hover', {
610611
points: [makeEventData(pt, traceNow)],
611612
event: d3.event
612613
});
613-
hasHoverEvent = true;
614614
});
615615

616616
sliceTop.on('mouseout', function(evt) {
617617
var fullLayoutNow = gd._fullLayout;
618618
var traceNow = gd._fullData[trace.index];
619619
var pt = d3.select(this).datum();
620620

621-
if(hasHoverEvent) {
621+
if(trace._hasHoverEvent) {
622622
evt.originalEvent = d3.event;
623623
gd.emit('plotly_unhover', {
624624
points: [makeEventData(pt, traceNow)],
625625
event: d3.event
626626
});
627-
hasHoverEvent = false;
627+
trace._hasHoverEvent = false;
628628
}
629629

630-
if(hasHoverLabel) {
630+
if(trace._hasHoverLabel) {
631631
Fx.loneUnhover(fullLayoutNow._hoverlayer.node());
632-
hasHoverLabel = false;
632+
trace._hasHoverLabel = false;
633633
}
634634
});
635635

test/jasmine/tests/pie_test.js

+82
Original file line numberDiff line numberDiff line change
@@ -1404,3 +1404,85 @@ describe('pie relayout', function() {
14041404
.then(done);
14051405
});
14061406
});
1407+
1408+
describe('Test pie interactions edge cases:', function() {
1409+
var gd;
1410+
1411+
beforeEach(function() { gd = createGraphDiv(); });
1412+
1413+
afterEach(destroyGraphDiv);
1414+
1415+
function _mouseEvent(type, v) {
1416+
return function() {
1417+
var el = d3.select(gd).select('.slice:nth-child(' + v + ')').node();
1418+
mouseEvent(type, 0, 0, {element: el});
1419+
};
1420+
}
1421+
1422+
function hover(v) {
1423+
return _mouseEvent('mouseover', v);
1424+
}
1425+
1426+
function unhover(v) {
1427+
return _mouseEvent('mouseout', v);
1428+
}
1429+
1430+
it('should keep tracking hover labels and hover events after *calc* edits', function(done) {
1431+
var mock = Lib.extendFlat({}, require('@mocks/pie_simple.json'));
1432+
var hoverCnt = 0;
1433+
var unhoverCnt = 0;
1434+
1435+
// see https://github.com/plotly/plotly.js/issues/3618
1436+
1437+
function _assert(msg, exp) {
1438+
expect(hoverCnt).toBe(exp.hoverCnt, msg + ' - hover cnt');
1439+
expect(unhoverCnt).toBe(exp.unhoverCnt, msg + ' - unhover cnt');
1440+
1441+
var label = d3.select(gd).select('g.hovertext');
1442+
expect(label.size()).toBe(exp.hoverLabel, msg + ' - hover label cnt');
1443+
1444+
hoverCnt = 0;
1445+
unhoverCnt = 0;
1446+
}
1447+
1448+
Plotly.plot(gd, mock)
1449+
.then(function() {
1450+
gd.on('plotly_hover', function() {
1451+
hoverCnt++;
1452+
// N.B. trigger a 'calc' edit
1453+
Plotly.restyle(gd, 'textinfo', 'percent');
1454+
});
1455+
gd.on('plotly_unhover', function() {
1456+
unhoverCnt++;
1457+
// N.B. trigger a 'calc' edit
1458+
Plotly.restyle(gd, 'textinfo', null);
1459+
});
1460+
})
1461+
.then(hover(1))
1462+
.then(function() {
1463+
_assert('after hovering on first sector', {
1464+
hoverCnt: 1,
1465+
unhoverCnt: 0,
1466+
hoverLabel: 1
1467+
});
1468+
})
1469+
.then(unhover(1))
1470+
.then(function() {
1471+
_assert('after un-hovering from first sector', {
1472+
hoverCnt: 0,
1473+
unhoverCnt: 1,
1474+
hoverLabel: 0
1475+
});
1476+
})
1477+
.then(hover(2))
1478+
.then(function() {
1479+
_assert('after hovering onto second sector', {
1480+
hoverCnt: 1,
1481+
unhoverCnt: 0,
1482+
hoverLabel: 1
1483+
});
1484+
})
1485+
.catch(failTest)
1486+
.then(done);
1487+
});
1488+
});

test/jasmine/tests/sunburst_test.js

+67
Original file line numberDiff line numberDiff line change
@@ -1031,3 +1031,70 @@ describe('Test sunburst tweening:', function() {
10311031
.then(done);
10321032
});
10331033
});
1034+
1035+
describe('Test sunburst interactions edge cases', function() {
1036+
var gd;
1037+
1038+
beforeEach(function() { gd = createGraphDiv(); });
1039+
1040+
afterEach(destroyGraphDiv);
1041+
1042+
it('should keep tracking hover labels and hover events after *calc* edits', function(done) {
1043+
var mock = Lib.extendFlat({}, require('@mocks/sunburst_first.json'));
1044+
var hoverCnt = 0;
1045+
var unhoverCnt = 0;
1046+
1047+
// see https://github.com/plotly/plotly.js/issues/3618
1048+
1049+
function _assert(msg, exp) {
1050+
expect(hoverCnt).toBe(exp.hoverCnt, msg + ' - hover cnt');
1051+
expect(unhoverCnt).toBe(exp.unhoverCnt, msg + ' - unhover cnt');
1052+
1053+
var label = d3.select(gd).select('g.hovertext');
1054+
expect(label.size()).toBe(exp.hoverLabel, msg + ' - hover label cnt');
1055+
1056+
hoverCnt = 0;
1057+
unhoverCnt = 0;
1058+
}
1059+
1060+
Plotly.plot(gd, mock)
1061+
.then(function() {
1062+
gd.on('plotly_hover', function() {
1063+
hoverCnt++;
1064+
// N.B. trigger a 'plot' edit
1065+
Plotly.restyle(gd, 'textinfo', 'none');
1066+
});
1067+
gd.on('plotly_unhover', function() {
1068+
unhoverCnt++;
1069+
// N.B. trigger a 'plot' edit
1070+
Plotly.restyle(gd, 'textinfo', null);
1071+
});
1072+
})
1073+
.then(hover(gd, 1))
1074+
.then(function() {
1075+
_assert('after hovering on first sector', {
1076+
hoverCnt: 1,
1077+
unhoverCnt: 0,
1078+
hoverLabel: 1
1079+
});
1080+
})
1081+
.then(unhover(gd, 1))
1082+
.then(function() {
1083+
_assert('after un-hovering from first sector', {
1084+
hoverCnt: 0,
1085+
unhoverCnt: 1,
1086+
hoverLabel: 0
1087+
});
1088+
})
1089+
.then(hover(gd, 2))
1090+
.then(function() {
1091+
_assert('after hovering onto second sector', {
1092+
hoverCnt: 1,
1093+
unhoverCnt: 0,
1094+
hoverLabel: 1
1095+
});
1096+
})
1097+
.catch(failTest)
1098+
.then(done);
1099+
});
1100+
});

0 commit comments

Comments
 (0)