From cf6e5db91972561a202ca1d0ca1747342a99af80 Mon Sep 17 00:00:00 2001 From: Martha Cryan Date: Fri, 22 Nov 2024 17:33:13 -0600 Subject: [PATCH 1/6] Clear inputDomain in diffLayout --- src/plot_api/plot_api.js | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/plot_api/plot_api.js b/src/plot_api/plot_api.js index 39f9bc93496..0b6375b3526 100644 --- a/src/plot_api/plot_api.js +++ b/src/plot_api/plot_api.js @@ -2811,6 +2811,29 @@ function diffLayout(gd, oldFullLayout, newFullLayout, immutable, transition) { return PlotSchema.getLayoutValObject(newFullLayout, parts); } + // Clear out any _inputDomain that's no longer valid + for (var key in newFullLayout) { + if (!key.startsWith('xaxis') && !key.startsWith('yaxis')) { + continue; + } + if (!oldFullLayout[key]) { + continue; + } + var newDomain = newFullLayout[key].domain; + var oldDomain = oldFullLayout[key].domain; + var oldInputDomain = oldFullLayout[key]._inputDomain; + if (oldFullLayout[key]._inputDomain) { + if (newDomain[0] === oldInputDomain[0] && newDomain[1] === oldInputDomain[1]) { + // what you're asking for hasn't changed, so let plotly.js start with what it + // concluded last time and iterate from there + newFullLayout[key].domain = oldFullLayout[key].domain; + } else if (newDomain[0] !== oldDomain[0] || newDomain[1] !== oldDomain[1]) { + // what you're asking for HAS changed, so clear _inputDomain and let us start from scratch + newFullLayout[key]._inputDomain = null; + } + } + } + var diffOpts = { getValObject: getLayoutValObject, flags: flags, @@ -2863,11 +2886,6 @@ function getDiffFlags(oldContainer, newContainer, outerparts, opts) { flags.rangesAltered[outerparts[0]] = 1; } - // clear _inputDomain on cartesian axes with altered domains - if(AX_DOMAIN_RE.test(astr)) { - nestedProperty(newContainer, '_inputDomain').set(null); - } - // track datarevision changes if(key === 'datarevision') { flags.newDataRevision = 1; From e506f43a33145518d6c4901ab94f6599e4e43e65 Mon Sep 17 00:00:00 2001 From: Martha Cryan Date: Mon, 25 Nov 2024 13:56:43 -0600 Subject: [PATCH 2/6] Add test that reproduces bug --- test/jasmine/tests/axes_test.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/jasmine/tests/axes_test.js b/test/jasmine/tests/axes_test.js index 2d6e1c9d970..9916a72b4bf 100644 --- a/test/jasmine/tests/axes_test.js +++ b/test/jasmine/tests/axes_test.js @@ -1796,6 +1796,25 @@ describe('Test axes', function() { 'input range, ' + msg + ': ' + ax.range); } + it('can change _inputDomain on call to react when template is present', function(done) { + Plotly.newPlot(gd, + [{z: [[0, 1], [2, 3]], type: 'heatmap'}], + { template: {}, xaxis: { domain: [0,1], scaleanchor: 'y' } } + ).then(function() { + assertRangeDomain('xaxis', [-1.451851851851852,2.4518518518518517], [0, 1], [0, 1]); + }) + .then(function() { + return Plotly.react(gd, + [{z: [[0, 1], [2, 3]], type: 'heatmap'}], + { template: {}, xaxis: { domain: [0.1, 0.9] } } + ); + }) + .then(function() { + assertRangeDomain('xaxis', [-0.5,1.5], [0.1, 0.9], [0.1, 0.9]); + }) + .then(done, done.fail); + }); + it('can change per-axis constrain:domain/range and constraintoward', function(done) { Plotly.newPlot(gd, // start with a heatmap as it has no padding so calculations are easy From 33b3ec4552f4846f26fa0b019ab892258f770b49 Mon Sep 17 00:00:00 2001 From: Martha Cryan Date: Mon, 25 Nov 2024 14:00:55 -0600 Subject: [PATCH 3/6] Add draftlogs entry --- draftlogs/7283_fix.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 draftlogs/7283_fix.md diff --git a/draftlogs/7283_fix.md b/draftlogs/7283_fix.md new file mode 100644 index 00000000000..d848bdd74b7 --- /dev/null +++ b/draftlogs/7283_fix.md @@ -0,0 +1 @@ +- Fix handling of new domain values given in the Plotly.react function to prevent loss of new domain values. [[#7283](https://github.com/plotly/plotly.js/pull/7283)] \ No newline at end of file From 32abe6a31a225fa4022996361bcc190196a09e28 Mon Sep 17 00:00:00 2001 From: Martha Cryan Date: Mon, 25 Nov 2024 15:29:29 -0600 Subject: [PATCH 4/6] Remove initial check of domain --- test/jasmine/tests/axes_test.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/jasmine/tests/axes_test.js b/test/jasmine/tests/axes_test.js index 9916a72b4bf..10422d3386f 100644 --- a/test/jasmine/tests/axes_test.js +++ b/test/jasmine/tests/axes_test.js @@ -1800,9 +1800,7 @@ describe('Test axes', function() { Plotly.newPlot(gd, [{z: [[0, 1], [2, 3]], type: 'heatmap'}], { template: {}, xaxis: { domain: [0,1], scaleanchor: 'y' } } - ).then(function() { - assertRangeDomain('xaxis', [-1.451851851851852,2.4518518518518517], [0, 1], [0, 1]); - }) + ) .then(function() { return Plotly.react(gd, [{z: [[0, 1], [2, 3]], type: 'heatmap'}], From 7e3c6c970e1df10e80f39644ced7dd1e21a7ffdd Mon Sep 17 00:00:00 2001 From: Martha Cryan Date: Mon, 25 Nov 2024 16:49:52 -0600 Subject: [PATCH 5/6] Change name of test to be more result oriented --- test/jasmine/tests/axes_test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/jasmine/tests/axes_test.js b/test/jasmine/tests/axes_test.js index 10422d3386f..e42cf4a60df 100644 --- a/test/jasmine/tests/axes_test.js +++ b/test/jasmine/tests/axes_test.js @@ -1796,7 +1796,7 @@ describe('Test axes', function() { 'input range, ' + msg + ': ' + ax.range); } - it('can change _inputDomain on call to react when template is present', function(done) { + it('can change axis domain on call to react when template is present', function(done) { Plotly.newPlot(gd, [{z: [[0, 1], [2, 3]], type: 'heatmap'}], { template: {}, xaxis: { domain: [0,1], scaleanchor: 'y' } } From 5f128bbe7b362dcd4d4a7db47ba43452f5ffbf14 Mon Sep 17 00:00:00 2001 From: Martha Cryan Date: Mon, 25 Nov 2024 17:05:37 -0600 Subject: [PATCH 6/6] Add comment to explain else case --- src/plot_api/plot_api.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plot_api/plot_api.js b/src/plot_api/plot_api.js index 0b6375b3526..d38f3c861d0 100644 --- a/src/plot_api/plot_api.js +++ b/src/plot_api/plot_api.js @@ -2831,6 +2831,9 @@ function diffLayout(gd, oldFullLayout, newFullLayout, immutable, transition) { // what you're asking for HAS changed, so clear _inputDomain and let us start from scratch newFullLayout[key]._inputDomain = null; } + // We skip the else case (newDomain !== oldInputDomain && newDomain === oldDomain) + // because it's likely that if the newDomain and oldDomain are the same, the user + // passed in the same layout object and we should keep the _inputDomain. } }