Skip to content

Commit bb3fedf

Browse files
authored
Merge pull request #8144 from Roshan1299/fix/8110-react-input-range
fix: Clear a stale _inputRange when Plotly.react or a whole axis object sets a new range
2 parents 0316e60 + 620c95b commit bb3fedf

3 files changed

Lines changed: 73 additions & 0 deletions

File tree

‎draftlogs/8144_fix.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Fix `Plotly.react` and `Plotly.relayout` with a whole axis object ignoring a new range on an axis with `constrain: 'domain'` [[#8144](https://github.com/plotly/plotly.js/pull/8144)], with thanks to @Roshan1299 for the contribution!

‎src/plot_api/plot_api.js‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2112,6 +2112,12 @@ function _relayout(gd, aobj) {
21122112
if (!newType || newType === '-') newType = 'linear';
21132113
Registry.getComponentMethod('annotations', 'convertCoords')(gd, fullProp, newType, doextra);
21142114
Registry.getComponentMethod('images', 'convertCoords')(gd, fullProp, newType, doextra);
2115+
2116+
// a range or autorange in a whole axis object is handled like the dotted keys above
2117+
if (!ptrunk && fullProp && vi && (vi.range !== undefined || vi.autorange !== undefined)) {
2118+
recordAlteredAxis(`${pleaf}.range`);
2119+
fullProp._inputRange = null;
2120+
}
21152121
}
21162122

21172123
// alter gd.layout
@@ -2872,6 +2878,17 @@ function diffLayout(gd, oldFullLayout, newFullLayout, immutable, transition) {
28722878
// because it's likely that if the newDomain and oldDomain are the same, the user
28732879
// passed in the same layout object and we should keep the _inputDomain.
28742880
}
2881+
2882+
// Same for _inputRange: constraints compare the range against it, so a stale one
2883+
// puts the previous range back
2884+
const newRange = newFullLayout[key].range;
2885+
const oldRange = oldFullLayout[key].range;
2886+
const oldInputRange = oldFullLayout[key]._inputRange;
2887+
if (oldInputRange && newRange && oldRange) {
2888+
const isInputRange = newRange[0] === oldInputRange[0] && newRange[1] === oldInputRange[1];
2889+
const isOldRange = newRange[0] === oldRange[0] && newRange[1] === oldRange[1];
2890+
if (!isInputRange && !isOldRange) newFullLayout[key]._inputRange = null;
2891+
}
28752892
}
28762893

28772894
var diffOpts = {

‎test/jasmine/tests/axes_test.js‎

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1884,6 +1884,61 @@ describe('Test axes', function() {
18841884
.then(done, done.fail);
18851885
});
18861886

1887+
describe('a new range on a constrain:domain axis', () => {
1888+
const data = () => [{ x: [0, 20, 50, 80, 100], y: [0, 20, 50, 80, 100] }];
1889+
const layout = (xRange) => ({
1890+
width: 400,
1891+
height: 400,
1892+
margin: { l: 0, r: 0, t: 0, b: 0 },
1893+
xaxis: { range: xRange, constrain: 'domain' },
1894+
yaxis: { range: [0, 100], scaleanchor: 'x', scaleratio: 1 }
1895+
});
1896+
1897+
it('is applied by Plotly.react', (done) => {
1898+
Plotly.newPlot(gd, data(), layout([0, 100]))
1899+
.then(() => Plotly.react(gd, data(), layout([20, 80])))
1900+
.then(() => {
1901+
assertRangeDomain('xaxis', [20, 80], [0, 1], [0.2, 0.8]);
1902+
expect(gd._fullLayout.xaxis._inputRange).toEqual([20, 80]);
1903+
})
1904+
.then(done, done.fail);
1905+
});
1906+
1907+
it('is applied by Plotly.relayout with a whole axis object', (done) => {
1908+
Plotly.newPlot(gd, data(), layout([0, 100]))
1909+
.then(() => Plotly.relayout(gd, { xaxis: layout([20, 80]).xaxis, yaxis: layout().yaxis }))
1910+
.then(() => {
1911+
assertRangeDomain('xaxis', [20, 80], [0, 1], [0.2, 0.8]);
1912+
expect(gd._fullLayout.xaxis._inputRange).toEqual([20, 80]);
1913+
})
1914+
.then(done, done.fail);
1915+
});
1916+
1917+
[
1918+
['dotted keys', { 'xaxis.range': [20, 80] }],
1919+
['a whole axis object', { xaxis: layout([20, 80]).xaxis }]
1920+
].forEach(([name, update]) => {
1921+
it(`lets the other axis rescale when Plotly.relayout sets one range with ${name}`, (done) => {
1922+
Plotly.newPlot(gd, data(), layout([0, 100]))
1923+
.then(() => Plotly.relayout(gd, update))
1924+
.then(() => {
1925+
assertRangeDomain('xaxis', [20, 80], [0, 1], [0, 1]);
1926+
assertRangeDomain('yaxis', [20, 80], [0, 1], [0, 1]);
1927+
})
1928+
.then(done, done.fail);
1929+
});
1930+
});
1931+
1932+
it('keeps the drawn range when Plotly.react gets the same layout again', (done) => {
1933+
Plotly.newPlot(gd, data(), layout([20, 80]))
1934+
.then(() => Plotly.react(gd, gd.data, gd.layout))
1935+
.then(() => {
1936+
assertRangeDomain('xaxis', [20, 80], [0, 1], [0.2, 0.8]);
1937+
})
1938+
.then(done, done.fail);
1939+
});
1940+
});
1941+
18871942
it('can change per-axis constrain:domain/range and constraintoward', function(done) {
18881943
Plotly.newPlot(gd,
18891944
// start with a heatmap as it has no padding so calculations are easy

0 commit comments

Comments
 (0)