Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions draftlogs/8144_fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +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)]
17 changes: 17 additions & 0 deletions src/plot_api/plot_api.js
Original file line number Diff line number Diff line change
Expand Up @@ -2112,6 +2112,12 @@ function _relayout(gd, aobj) {
if (!newType || newType === '-') newType = 'linear';
Registry.getComponentMethod('annotations', 'convertCoords')(gd, fullProp, newType, doextra);
Registry.getComponentMethod('images', 'convertCoords')(gd, fullProp, newType, doextra);

// a range or autorange in a whole axis object is handled like the dotted keys above
if (!ptrunk && fullProp && vi && (vi.range !== undefined || vi.autorange !== undefined)) {
recordAlteredAxis(`${pleaf}.range`);
fullProp._inputRange = null;
}
}

// alter gd.layout
Expand Down Expand Up @@ -2872,6 +2878,17 @@ function diffLayout(gd, oldFullLayout, newFullLayout, immutable, transition) {
// 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.
}

// Same for _inputRange: constraints compare the range against it, so a stale one
// puts the previous range back
const newRange = newFullLayout[key].range;
const oldRange = oldFullLayout[key].range;
const oldInputRange = oldFullLayout[key]._inputRange;
if (oldInputRange && newRange && oldRange) {
const isInputRange = newRange[0] === oldInputRange[0] && newRange[1] === oldInputRange[1];
const isOldRange = newRange[0] === oldRange[0] && newRange[1] === oldRange[1];
if (!isInputRange && !isOldRange) newFullLayout[key]._inputRange = null;
}
}

var diffOpts = {
Expand Down
55 changes: 55 additions & 0 deletions test/jasmine/tests/axes_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1884,6 +1884,61 @@ describe('Test axes', function() {
.then(done, done.fail);
});

describe('a new range on a constrain:domain axis', () => {
const data = () => [{ x: [0, 20, 50, 80, 100], y: [0, 20, 50, 80, 100] }];
const layout = (xRange) => ({
width: 400,
height: 400,
margin: { l: 0, r: 0, t: 0, b: 0 },
xaxis: { range: xRange, constrain: 'domain' },
yaxis: { range: [0, 100], scaleanchor: 'x', scaleratio: 1 }
});

it('is applied by Plotly.react', (done) => {
Plotly.newPlot(gd, data(), layout([0, 100]))
.then(() => Plotly.react(gd, data(), layout([20, 80])))
.then(() => {
assertRangeDomain('xaxis', [20, 80], [0, 1], [0.2, 0.8]);
expect(gd._fullLayout.xaxis._inputRange).toEqual([20, 80]);
})
.then(done, done.fail);
});

it('is applied by Plotly.relayout with a whole axis object', (done) => {
Plotly.newPlot(gd, data(), layout([0, 100]))
.then(() => Plotly.relayout(gd, { xaxis: layout([20, 80]).xaxis, yaxis: layout().yaxis }))
.then(() => {
assertRangeDomain('xaxis', [20, 80], [0, 1], [0.2, 0.8]);
expect(gd._fullLayout.xaxis._inputRange).toEqual([20, 80]);
})
.then(done, done.fail);
});

[
['dotted keys', { 'xaxis.range': [20, 80] }],
['a whole axis object', { xaxis: layout([20, 80]).xaxis }]
].forEach(([name, update]) => {
it(`lets the other axis rescale when Plotly.relayout sets one range with ${name}`, (done) => {
Plotly.newPlot(gd, data(), layout([0, 100]))
.then(() => Plotly.relayout(gd, update))
.then(() => {
assertRangeDomain('xaxis', [20, 80], [0, 1], [0, 1]);
assertRangeDomain('yaxis', [20, 80], [0, 1], [0, 1]);
})
.then(done, done.fail);
});
});

it('keeps the drawn range when Plotly.react gets the same layout again', (done) => {
Plotly.newPlot(gd, data(), layout([20, 80]))
.then(() => Plotly.react(gd, gd.data, gd.layout))
.then(() => {
assertRangeDomain('xaxis', [20, 80], [0, 1], [0.2, 0.8]);
})
.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
Expand Down