diff --git a/src/plot_api/plot_api.js b/src/plot_api/plot_api.js index a6875712fd5..6b00272b00a 100644 --- a/src/plot_api/plot_api.js +++ b/src/plot_api/plot_api.js @@ -1922,8 +1922,24 @@ function _relayout(gd, aobj) { // back to its initial value as computed during the first pass in Plots.plotAutoSize. // // To do so, we must manually set them back here using the _initialAutoSize cache. - if(['width', 'height'].indexOf(ai) !== -1 && vi === null) { - fullLayout[ai] = gd._initialAutoSize[ai]; + // can't use impliedEdits for this because behavior depends on vi + if(['width', 'height'].indexOf(ai) !== -1) { + if(vi) { + doextra('autosize', null); + // currently we don't support autosize one dim only - so + // explicitly set the other one. Note that doextra will + // ignore this if the same relayout call also provides oppositeAttr + var oppositeAttr = ai === 'height' ? 'width' : 'height'; + doextra(oppositeAttr, fullLayout[oppositeAttr]); + } + else { + fullLayout[ai] = gd._initialAutoSize[ai]; + } + } + else if(ai === 'autosize') { + // depends on vi here too, so again can't use impliedEdits + doextra('width', vi ? null : fullLayout.width); + doextra('height', vi ? null : fullLayout.height); } // check autorange vs range else if(pleafPlus.match(AX_RANGE_RE)) { diff --git a/test/jasmine/tests/config_test.js b/test/jasmine/tests/config_test.js index e85451e6a5d..395b8f36d4e 100644 --- a/test/jasmine/tests/config_test.js +++ b/test/jasmine/tests/config_test.js @@ -47,7 +47,12 @@ describe('config argument', function() { width: layoutWidth }; var relayout = { - width: relayoutWidth + width: relayoutWidth, + // didn't need this before #3120 - but since we're now + // implicitly clearing autosize when edit width, if you really + // want height to re-autosize you need to explicitly re-add + // autosize + autosize: autosize }; var layout2 = Lib.extendDeep({}, layout); diff --git a/test/jasmine/tests/plot_api_test.js b/test/jasmine/tests/plot_api_test.js index e5ab15363ed..3ff769c6ece 100644 --- a/test/jasmine/tests/plot_api_test.js +++ b/test/jasmine/tests/plot_api_test.js @@ -510,6 +510,43 @@ describe('Test plot api', function() { .catch(failTest) .then(done); }); + + it('updates autosize/width/height correctly', function(done) { + function assertSizeAndThen(width, height, auto, msg, next) { + return function() { + expect(gd._fullLayout.width).toBe(width, msg); + expect(gd._fullLayout.height).toBe(height, msg); + expect(gd._fullLayout.autosize).toBe(auto, msg); + if(!auto) { + expect(gd.layout.width).toBe(width, msg); + expect(gd.layout.height).toBe(height, msg); + } + + if(next) return Plotly.relayout(gd, next); + }; + } + + // give gd css sizing to be picked up by autosize + gd.style.width = '543px'; + gd.style.height = '432px'; + + Plotly.newPlot(gd, [{y: [1, 3, 2]}]) + .then(assertSizeAndThen(543, 432, true, 'initial', + {autosize: false})) + .then(assertSizeAndThen(543, 432, false, 'autosize false with no sizes', + {autosize: true})) + .then(assertSizeAndThen(543, 432, true, 'back to autosized', + {width: 600})) + .then(assertSizeAndThen(600, 432, false, 'explicit width causes explicit height', + {width: null})) + .then(assertSizeAndThen(543, 432, true, 'removed width', + {height: 500, width: 700})) + .then(assertSizeAndThen(700, 500, false, 'explicit height and width', + {autosize: true})) + .then(assertSizeAndThen(543, 432, true, 'final back to autosize')) + .catch(failTest) + .then(done); + }); }); describe('Plotly.relayout subroutines switchboard', function() {