Skip to content

Commit a4c185a

Browse files
authored
Merge pull request #3690 from plotly/sunburst
Merging #3662 into master
2 parents 20553d5 + a7561ec commit a4c185a

File tree

5 files changed

+186
-18
lines changed

5 files changed

+186
-18
lines changed

src/traces/pie/base_plot.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ exports.name = 'pie';
1616
exports.plot = function(gd) {
1717
var Pie = Registry.getModule('pie');
1818
var cdPie = getModuleCalcData(gd.calcdata, Pie)[0];
19-
20-
if(cdPie.length) Pie.plot(gd, cdPie);
19+
Pie.plot(gd, cdPie);
2120
};
2221

2322
exports.clean = function(newFullData, newFullLayout, oldFullData, oldFullLayout) {

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
@@ -529,12 +529,12 @@ function attachFxHandlers(sliceTop, gd, cd) {
529529

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

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

605-
hasHoverLabel = true;
605+
trace._hasHoverLabel = true;
606606
}
607607

608+
trace._hasHoverEvent = true;
608609
gd.emit('plotly_hover', {
609610
points: [makeEventData(pt, traceNow)],
610611
event: d3.event
611612
});
612-
hasHoverEvent = true;
613613
});
614614

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

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

629-
if(hasHoverLabel) {
629+
if(trace._hasHoverLabel) {
630630
Fx.loneUnhover(fullLayoutNow._hoverlayer.node());
631-
hasHoverLabel = false;
631+
trace._hasHoverLabel = false;
632632
}
633633
});
634634

test/jasmine/tests/pie_test.js

+102
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,26 @@ describe('Pie traces', function() {
818818
.catch(failTest)
819819
.then(done);
820820
});
821+
822+
it('should be able to toggle visibility', function(done) {
823+
var mock = Lib.extendDeep({}, require('@mocks/pie_title_multiple.json'));
824+
825+
function _assert(msg, exp) {
826+
return function() {
827+
var layer = d3.select(gd).select('.pielayer');
828+
expect(layer.selectAll('.trace').size()).toBe(exp, msg);
829+
};
830+
}
831+
832+
Plotly.plot(gd, mock)
833+
.then(_assert('base', 4))
834+
.then(function() { return Plotly.restyle(gd, 'visible', false); })
835+
.then(_assert('both visible:false', 0))
836+
.then(function() { return Plotly.restyle(gd, 'visible', true); })
837+
.then(_assert('back to visible:true', 4))
838+
.catch(failTest)
839+
.then(done);
840+
});
821841
});
822842

823843
describe('pie hovering', function() {
@@ -1434,3 +1454,85 @@ describe('pie relayout', function() {
14341454
.then(done);
14351455
});
14361456
});
1457+
1458+
describe('Test pie interactions edge cases:', function() {
1459+
var gd;
1460+
1461+
beforeEach(function() { gd = createGraphDiv(); });
1462+
1463+
afterEach(destroyGraphDiv);
1464+
1465+
function _mouseEvent(type, v) {
1466+
return function() {
1467+
var el = d3.select(gd).select('.slice:nth-child(' + v + ')').node();
1468+
mouseEvent(type, 0, 0, {element: el});
1469+
};
1470+
}
1471+
1472+
function hover(v) {
1473+
return _mouseEvent('mouseover', v);
1474+
}
1475+
1476+
function unhover(v) {
1477+
return _mouseEvent('mouseout', v);
1478+
}
1479+
1480+
it('should keep tracking hover labels and hover events after *calc* edits', function(done) {
1481+
var mock = Lib.extendFlat({}, require('@mocks/pie_simple.json'));
1482+
var hoverCnt = 0;
1483+
var unhoverCnt = 0;
1484+
1485+
// see https://github.com/plotly/plotly.js/issues/3618
1486+
1487+
function _assert(msg, exp) {
1488+
expect(hoverCnt).toBe(exp.hoverCnt, msg + ' - hover cnt');
1489+
expect(unhoverCnt).toBe(exp.unhoverCnt, msg + ' - unhover cnt');
1490+
1491+
var label = d3.select(gd).select('g.hovertext');
1492+
expect(label.size()).toBe(exp.hoverLabel, msg + ' - hover label cnt');
1493+
1494+
hoverCnt = 0;
1495+
unhoverCnt = 0;
1496+
}
1497+
1498+
Plotly.plot(gd, mock)
1499+
.then(function() {
1500+
gd.on('plotly_hover', function() {
1501+
hoverCnt++;
1502+
// N.B. trigger a 'calc' edit
1503+
Plotly.restyle(gd, 'textinfo', 'percent');
1504+
});
1505+
gd.on('plotly_unhover', function() {
1506+
unhoverCnt++;
1507+
// N.B. trigger a 'calc' edit
1508+
Plotly.restyle(gd, 'textinfo', null);
1509+
});
1510+
})
1511+
.then(hover(1))
1512+
.then(function() {
1513+
_assert('after hovering on first sector', {
1514+
hoverCnt: 1,
1515+
unhoverCnt: 0,
1516+
hoverLabel: 1
1517+
});
1518+
})
1519+
.then(unhover(1))
1520+
.then(function() {
1521+
_assert('after un-hovering from first sector', {
1522+
hoverCnt: 0,
1523+
unhoverCnt: 1,
1524+
hoverLabel: 0
1525+
});
1526+
})
1527+
.then(hover(2))
1528+
.then(function() {
1529+
_assert('after hovering onto second sector', {
1530+
hoverCnt: 1,
1531+
unhoverCnt: 0,
1532+
hoverLabel: 1
1533+
});
1534+
})
1535+
.catch(failTest)
1536+
.then(done);
1537+
});
1538+
});

test/jasmine/tests/sunburst_test.js

+67
Original file line numberDiff line numberDiff line change
@@ -1053,3 +1053,70 @@ describe('Test sunburst tweening:', function() {
10531053
.then(done);
10541054
});
10551055
});
1056+
1057+
describe('Test sunburst interactions edge cases', function() {
1058+
var gd;
1059+
1060+
beforeEach(function() { gd = createGraphDiv(); });
1061+
1062+
afterEach(destroyGraphDiv);
1063+
1064+
it('should keep tracking hover labels and hover events after *calc* edits', function(done) {
1065+
var mock = Lib.extendFlat({}, require('@mocks/sunburst_first.json'));
1066+
var hoverCnt = 0;
1067+
var unhoverCnt = 0;
1068+
1069+
// see https://github.com/plotly/plotly.js/issues/3618
1070+
1071+
function _assert(msg, exp) {
1072+
expect(hoverCnt).toBe(exp.hoverCnt, msg + ' - hover cnt');
1073+
expect(unhoverCnt).toBe(exp.unhoverCnt, msg + ' - unhover cnt');
1074+
1075+
var label = d3.select(gd).select('g.hovertext');
1076+
expect(label.size()).toBe(exp.hoverLabel, msg + ' - hover label cnt');
1077+
1078+
hoverCnt = 0;
1079+
unhoverCnt = 0;
1080+
}
1081+
1082+
Plotly.plot(gd, mock)
1083+
.then(function() {
1084+
gd.on('plotly_hover', function() {
1085+
hoverCnt++;
1086+
// N.B. trigger a 'plot' edit
1087+
Plotly.restyle(gd, 'textinfo', 'none');
1088+
});
1089+
gd.on('plotly_unhover', function() {
1090+
unhoverCnt++;
1091+
// N.B. trigger a 'plot' edit
1092+
Plotly.restyle(gd, 'textinfo', null);
1093+
});
1094+
})
1095+
.then(hover(gd, 1))
1096+
.then(function() {
1097+
_assert('after hovering on first sector', {
1098+
hoverCnt: 1,
1099+
unhoverCnt: 0,
1100+
hoverLabel: 1
1101+
});
1102+
})
1103+
.then(unhover(gd, 1))
1104+
.then(function() {
1105+
_assert('after un-hovering from first sector', {
1106+
hoverCnt: 0,
1107+
unhoverCnt: 1,
1108+
hoverLabel: 0
1109+
});
1110+
})
1111+
.then(hover(gd, 2))
1112+
.then(function() {
1113+
_assert('after hovering onto second sector', {
1114+
hoverCnt: 1,
1115+
unhoverCnt: 0,
1116+
hoverLabel: 1
1117+
});
1118+
})
1119+
.catch(failTest)
1120+
.then(done);
1121+
});
1122+
});

0 commit comments

Comments
 (0)