Skip to content

Commit 1aa0b6f

Browse files
authored
Merge pull request #4167 from plotly/animate-range-edit-leak
Fix multi-axis transition "leaks"
2 parents 5f25eaf + 41a5a83 commit 1aa0b6f

File tree

3 files changed

+145
-10
lines changed

3 files changed

+145
-10
lines changed

Diff for: src/plots/plots.js

+8-9
Original file line numberDiff line numberDiff line change
@@ -2407,26 +2407,25 @@ plots.transition = function(gd, data, layout, traces, frameOpts, transitionOpts)
24072407
var xr0 = xa.range.slice();
24082408
var yr0 = ya.range.slice();
24092409

2410-
var xr1;
2410+
var xr1 = null;
2411+
var yr1 = null;
2412+
var editX = null;
2413+
var editY = null;
2414+
24112415
if(Array.isArray(newLayout[xa._name + '.range'])) {
24122416
xr1 = newLayout[xa._name + '.range'].slice();
24132417
} else if(Array.isArray((newLayout[xa._name] || {}).range)) {
24142418
xr1 = newLayout[xa._name].range.slice();
24152419
}
2416-
2417-
var yr1;
24182420
if(Array.isArray(newLayout[ya._name + '.range'])) {
24192421
yr1 = newLayout[ya._name + '.range'].slice();
24202422
} else if(Array.isArray((newLayout[ya._name] || {}).range)) {
24212423
yr1 = newLayout[ya._name].range.slice();
24222424
}
24232425

2424-
var editX;
24252426
if(xr0 && xr1 && (xr0[0] !== xr1[0] || xr0[1] !== xr1[1])) {
24262427
editX = {xr0: xr0, xr1: xr1};
24272428
}
2428-
2429-
var editY;
24302429
if(yr0 && yr1 && (yr0[0] !== yr1[0] || yr0[1] !== yr1[1])) {
24312430
editY = {yr0: yr0, yr1: yr1};
24322431
}
@@ -2518,12 +2517,12 @@ plots.transitionFromReact = function(gd, restyleFlags, relayoutFlags, oldFullLay
25182517
xa.setScale();
25192518
ya.setScale();
25202519

2521-
var editX;
2520+
var editX = null;
2521+
var editY = null;
2522+
25222523
if(xr0[0] !== xr1[0] || xr0[1] !== xr1[1]) {
25232524
editX = {xr0: xr0, xr1: xr1};
25242525
}
2525-
2526-
var editY;
25272526
if(yr0[0] !== yr1[0] || yr0[1] !== yr1[1]) {
25282527
editY = {yr0: yr0, yr1: yr1};
25292528
}

Diff for: test/jasmine/tests/animate_test.js

+68-1
Original file line numberDiff line numberDiff line change
@@ -708,7 +708,6 @@ describe('Animate API details', function() {
708708
});
709709

710710
describe('Animating multiple axes', function() {
711-
'use strict';
712711
var gd;
713712

714713
beforeEach(function() {
@@ -750,6 +749,74 @@ describe('Animating multiple axes', function() {
750749
.catch(failTest)
751750
.then(done);
752751
});
752+
753+
it('should not leak axis update from subplot to subplot', function(done) {
754+
function _animate(frameLayout) {
755+
return function() {
756+
return Plotly.animate(gd, {layout: frameLayout}, {
757+
frame: {redraw: false, duration: 10},
758+
transition: {duration: 10}
759+
});
760+
};
761+
}
762+
763+
function _assert(msg, exp) {
764+
return function() {
765+
var fullLayout = gd._fullLayout;
766+
for(var k in exp) {
767+
expect(fullLayout[k].range).toBeCloseToArray(exp[k], 2, msg + '| ' + k);
768+
}
769+
};
770+
}
771+
772+
Plotly.plot(gd, [{
773+
x: [0.1, 0.2, 0.3],
774+
y: [0.4, 0.5, 0.6],
775+
}, {
776+
x: [0.2, 0.3, 0.4],
777+
y: [0.5, 0.6, 0.7],
778+
xaxis: 'x2',
779+
yaxis: 'y2',
780+
}, {
781+
x: [0.3, 0.5, 0.7],
782+
y: [0.7, 0.2, 0.2],
783+
xaxis: 'x3',
784+
yaxis: 'y3',
785+
}], {
786+
grid: {rows: 1, columns: 3, pattern: 'independent'},
787+
showlegend: false
788+
})
789+
.then(_assert('base', {
790+
xaxis: [0.0825, 0.3174], xaxis2: [0.1825, 0.417], xaxis3: [0.265, 0.7349],
791+
yaxis: [0.385, 0.614], yaxis2: [0.485, 0.714], yaxis3: [0.163, 0.7366]
792+
}))
793+
.then(_animate({
794+
xaxis: {range: [-10, 10]},
795+
yaxis: {range: [-10, 10]}
796+
}))
797+
.then(_assert('after xy range animate', {
798+
xaxis: [-10, 10], xaxis2: [0.1825, 0.417], xaxis3: [0.265, 0.7349],
799+
yaxis: [-10, 10], yaxis2: [0.485, 0.714], yaxis3: [0.163, 0.7366]
800+
}))
801+
.then(_animate({
802+
xaxis2: {range: [-20, 20]},
803+
yaxis2: {range: [-20, 20]}
804+
}))
805+
.then(_assert('after x2y2 range animate', {
806+
xaxis: [-10, 10], xaxis2: [-20, 20], xaxis3: [0.265, 0.7349],
807+
yaxis: [-10, 10], yaxis2: [-20, 20], yaxis3: [0.163, 0.7366]
808+
}))
809+
.then(_animate({
810+
xaxis3: {range: [-30, 30]},
811+
yaxis3: {range: [-30, 30]}
812+
}))
813+
.then(_assert('after x3y3 range animate', {
814+
xaxis: [-10, 10], xaxis2: [-20, 20], xaxis3: [-30, 30],
815+
yaxis: [-10, 10], yaxis2: [-20, 20], yaxis3: [-30, 30]
816+
}))
817+
.catch(failTest)
818+
.then(done);
819+
});
753820
});
754821

755822
describe('non-animatable fallback', function() {

Diff for: test/jasmine/tests/transition_test.js

+69
Original file line numberDiff line numberDiff line change
@@ -1028,4 +1028,73 @@ describe('Plotly.react transitions:', function() {
10281028
.catch(failTest)
10291029
.then(done);
10301030
});
1031+
1032+
it('should not leak axis update from subplot to subplot', function(done) {
1033+
function _react(modifs) {
1034+
return function() {
1035+
for(var k in modifs) {
1036+
gd.layout[k] = modifs[k];
1037+
}
1038+
return Plotly.react(gd, gd.data, gd.layout);
1039+
};
1040+
}
1041+
1042+
function _assert(msg, exp) {
1043+
return function() {
1044+
var fullLayout = gd._fullLayout;
1045+
for(var k in exp) {
1046+
expect(fullLayout[k].range).toBeCloseToArray(exp[k], 2, msg + '| ' + k);
1047+
}
1048+
};
1049+
}
1050+
1051+
Plotly.plot(gd, [{
1052+
x: [0.1, 0.2, 0.3],
1053+
y: [0.4, 0.5, 0.6],
1054+
}, {
1055+
x: [0.2, 0.3, 0.4],
1056+
y: [0.5, 0.6, 0.7],
1057+
xaxis: 'x2',
1058+
yaxis: 'y2',
1059+
}, {
1060+
x: [0.3, 0.5, 0.7],
1061+
y: [0.7, 0.2, 0.2],
1062+
xaxis: 'x3',
1063+
yaxis: 'y3',
1064+
}], {
1065+
grid: {rows: 1, columns: 3, pattern: 'independent'},
1066+
showlegend: false,
1067+
transition: {duration: 10}
1068+
})
1069+
.then(_assert('base', {
1070+
xaxis: [0.0825, 0.3174], xaxis2: [0.1825, 0.417], xaxis3: [0.265, 0.7349],
1071+
yaxis: [0.385, 0.614], yaxis2: [0.485, 0.714], yaxis3: [0.163, 0.7366]
1072+
}))
1073+
.then(_react({
1074+
xaxis: {range: [-10, 10]},
1075+
yaxis: {range: [-10, 10]}
1076+
}))
1077+
.then(_assert('after xy range transition', {
1078+
xaxis: [-10, 10], xaxis2: [0.1825, 0.417], xaxis3: [0.265, 0.7349],
1079+
yaxis: [-10, 10], yaxis2: [0.485, 0.714], yaxis3: [0.163, 0.7366]
1080+
}))
1081+
.then(_react({
1082+
xaxis2: {range: [-20, 20]},
1083+
yaxis2: {range: [-20, 20]}
1084+
}))
1085+
.then(_assert('after x2y2 range transition', {
1086+
xaxis: [-10, 10], xaxis2: [-20, 20], xaxis3: [0.265, 0.7349],
1087+
yaxis: [-10, 10], yaxis2: [-20, 20], yaxis3: [0.163, 0.7366]
1088+
}))
1089+
.then(_react({
1090+
xaxis3: {range: [-30, 30]},
1091+
yaxis3: {range: [-30, 30]}
1092+
}))
1093+
.then(_assert('after x3y3 range transition', {
1094+
xaxis: [-10, 10], xaxis2: [-20, 20], xaxis3: [-30, 30],
1095+
yaxis: [-10, 10], yaxis2: [-20, 20], yaxis3: [-30, 30]
1096+
}))
1097+
.catch(failTest)
1098+
.then(done);
1099+
});
10311100
});

0 commit comments

Comments
 (0)