diff --git a/src/lib/index.js b/src/lib/index.js index 32f3f811a67..84a5a11d2e6 100644 --- a/src/lib/index.js +++ b/src/lib/index.js @@ -379,7 +379,9 @@ lib.getPlotDiv = function(el) { lib.isPlotDiv = function(el) { var el3 = d3.select(el); - return el3.size() && el3.classed('js-plotly-plot'); + return el3.node() instanceof HTMLElement && + el3.size() && + el3.classed('js-plotly-plot'); }; lib.removeElement = function(el) { diff --git a/src/plot_api/plot_api.js b/src/plot_api/plot_api.js index bbec2816a19..041e1ae3549 100644 --- a/src/plot_api/plot_api.js +++ b/src/plot_api/plot_api.js @@ -409,10 +409,6 @@ function plotPolar(gd, data, layout) { if(layout) gd.layout = layout; Plotly.micropolar.manager.fillLayout(gd); - if(gd._fullLayout.autosize === 'initial' && gd._context.autosizable) { - plotAutoSize(gd, {}); - gd._fullLayout.autosize = layout.autosize = true; - } // resize canvas paperDiv.style({ width: gd._fullLayout.width + 'px', @@ -2148,8 +2144,6 @@ Plotly.relayout = function relayout(gd, astr, val) { return (fullLayout[axName] || {}).autorange; } - var hw = ['height', 'width']; - // alter gd.layout for(var ai in aobj) { var p = Lib.nestedProperty(layout, ai), @@ -2172,14 +2166,8 @@ Plotly.relayout = function relayout(gd, astr, val) { // op and has no flag. undoit[ai] = (pleaf === 'reverse') ? vi : p.get(); - // check autosize or autorange vs size and range - if(hw.indexOf(ai) !== -1) { - doextra('autosize', false); - } - else if(ai === 'autosize') { - doextra(hw, undefined); - } - else if(pleafPlus.match(/^[xyz]axis[0-9]*\.range(\[[0|1]\])?$/)) { + // check autorange vs range + if(pleafPlus.match(/^[xyz]axis[0-9]*\.range(\[[0|1]\])?$/)) { doextra(ptrunk + '.autorange', false); } else if(pleafPlus.match(/^[xyz]axis[0-9]*\.autorange$/)) { @@ -2357,11 +2345,20 @@ Plotly.relayout = function relayout(gd, astr, val) { Queue.add(gd, relayout, [gd, undoit], relayout, [gd, redoit]); } - // calculate autosizing - if size hasn't changed, - // will remove h&w so we don't need to redraw - if(aobj.autosize) aobj = plotAutoSize(gd, aobj); + var oldWidth = gd._fullLayout.width, + oldHeight = gd._fullLayout.height; - if(aobj.height || aobj.width || aobj.autosize) docalc = true; + // coerce the updated layout + Plots.supplyDefaults(gd); + + // calculate autosizing + if(gd.layout.autosize) Plots.plotAutoSize(gd, gd.layout, gd._fullLayout); + + // avoid unnecessary redraws + var changed = aobj.height || aobj.width || + (gd._fullLayout.width !== oldWidth) || + (gd._fullLayout.height !== oldHeight); + if(changed) docalc = true; // redraw // first check if there's still anything to do @@ -2382,7 +2379,6 @@ Plotly.relayout = function relayout(gd, astr, val) { } else if(ak.length) { // if we didn't need to redraw entirely, just do the needed parts - Plots.supplyDefaults(gd); fullLayout = gd._fullLayout; if(dolegend) { @@ -2491,86 +2487,6 @@ Plotly.purge = function purge(gd) { return gd; }; -/** - * Reduce all reserved margin objects to a single required margin reservation. - * - * @param {Object} margins - * @returns {{left: number, right: number, bottom: number, top: number}} - */ -function calculateReservedMargins(margins) { - var resultingMargin = {left: 0, right: 0, bottom: 0, top: 0}, - marginName; - - if(margins) { - for(marginName in margins) { - if(margins.hasOwnProperty(marginName)) { - resultingMargin.left += margins[marginName].left || 0; - resultingMargin.right += margins[marginName].right || 0; - resultingMargin.bottom += margins[marginName].bottom || 0; - resultingMargin.top += margins[marginName].top || 0; - } - } - } - return resultingMargin; -} - -function plotAutoSize(gd, aobj) { - var fullLayout = gd._fullLayout, - context = gd._context, - computedStyle; - - var newHeight, newWidth; - - gd.emit('plotly_autosize'); - - // embedded in an iframe - just take the full iframe size - // if we get to this point, with no aspect ratio restrictions - if(gd._context.fillFrame) { - newWidth = window.innerWidth; - newHeight = window.innerHeight; - - // somehow we get a few extra px height sometimes... - // just hide it - document.body.style.overflow = 'hidden'; - } - else if(isNumeric(context.frameMargins) && context.frameMargins > 0) { - var reservedMargins = calculateReservedMargins(gd._boundingBoxMargins), - reservedWidth = reservedMargins.left + reservedMargins.right, - reservedHeight = reservedMargins.bottom + reservedMargins.top, - gdBB = fullLayout._container.node().getBoundingClientRect(), - factor = 1 - 2 * context.frameMargins; - - newWidth = Math.round(factor * (gdBB.width - reservedWidth)); - newHeight = Math.round(factor * (gdBB.height - reservedHeight)); - } - else { - // plotly.js - let the developers do what they want, either - // provide height and width for the container div, - // specify size in layout, or take the defaults, - // but don't enforce any ratio restrictions - computedStyle = window.getComputedStyle(gd); - newHeight = parseFloat(computedStyle.height) || fullLayout.height; - newWidth = parseFloat(computedStyle.width) || fullLayout.width; - } - - if(Math.abs(fullLayout.width - newWidth) > 1 || - Math.abs(fullLayout.height - newHeight) > 1) { - fullLayout.height = gd.layout.height = newHeight; - fullLayout.width = gd.layout.width = newWidth; - } - // if there's no size change, update layout but - // delete the autosize attr so we don't redraw - // but can't call layoutStyles for initial autosize - else if(fullLayout.autosize !== 'initial') { - delete(aobj.autosize); - fullLayout.autosize = gd.layout.autosize = true; - } - - Plots.sanitizeMargins(fullLayout); - - return aobj; -} - // ------------------------------------------------------- // makePlotFramework: Create the plot container and axes // ------------------------------------------------------- @@ -2590,13 +2506,6 @@ function makePlotFramework(gd) { .classed('svg-container', true) .style('position', 'relative'); - // Initial autosize - if(fullLayout.autosize === 'initial') { - plotAutoSize(gd, {}); - fullLayout.autosize = true; - gd.layout.autosize = true; - } - // Make the graph containers // start fresh each time we get here, so we know the order comes out // right, rather than enter/exit which can muck up the order diff --git a/src/plot_api/plot_config.js b/src/plot_api/plot_config.js index fc966daad7b..ee3b93ea6ce 100644 --- a/src/plot_api/plot_config.js +++ b/src/plot_api/plot_config.js @@ -26,7 +26,8 @@ module.exports = { // we can edit titles, move annotations, etc editable: false, - // plot will respect layout.autosize=true and infer its container size + // DO autosize once regardless of layout.autosize + // (use default width or height values otherwise) autosizable: false, // if we DO autosize, do we fill the container or the screen? diff --git a/src/plots/layout_attributes.js b/src/plots/layout_attributes.js index 06b4ab0913c..030f99eca75 100644 --- a/src/plots/layout_attributes.js +++ b/src/plots/layout_attributes.js @@ -45,13 +45,17 @@ module.exports = { description: 'Sets the title font.' }), autosize: { - valType: 'enumerated', + valType: 'boolean', role: 'info', - // TODO: better handling of 'initial' - values: [true, false, 'initial'], + dflt: false, description: [ - 'Determines whether or not the dimensions of the figure are', - 'computed as a function of the display size.' + 'Determines whether or not a layout width or height', + 'that has been left undefined by the user', + 'is initialized on each relayout.', + + 'Note that, regardless of this attribute,', + 'an undefined layout width or height', + 'is always initialized on the first call to plot.' ].join(' ') }, width: { diff --git a/src/plots/plots.js b/src/plots/plots.js index 4b814bfd85c..29025dd999b 100644 --- a/src/plots/plots.js +++ b/src/plots/plots.js @@ -287,17 +287,26 @@ plots.resize = function(gd) { if(gd._redrawTimer) clearTimeout(gd._redrawTimer); gd._redrawTimer = setTimeout(function() { - if((gd._fullLayout || {}).autosize) { - // autosizing doesn't count as a change that needs saving - var oldchanged = gd.changed; + // return if there is nothing to resize + if(gd.layout.width && gd.layout.height) { + resolve(gd); + return; + } + + delete gd._fullLayout._initialAutoSizeIsDone; + if(!gd.layout.width) delete (gd._fullLayout || {}).width; + if(!gd.layout.height) delete (gd._fullLayout || {}).height; - // nor should it be included in the undo queue - gd.autoplay = true; + // autosizing doesn't count as a change that needs saving + var oldchanged = gd.changed; - Plotly.relayout(gd, { autosize: true }); + // nor should it be included in the undo queue + gd.autoplay = true; + + Plotly.plot(gd).then(function() { gd.changed = oldchanged; resolve(gd); - } + }); }, 100); }); }; @@ -468,7 +477,36 @@ plots.supplyDefaults = function(gd) { // first fill in what we can of layout without looking at data // because fullData needs a few things from layout - plots.supplyLayoutGlobalDefaults(newLayout, newFullLayout); + + if(oldFullLayout._initialAutoSizeIsDone) { + // coerce the updated layout while preserving width and height + var oldWidth = oldFullLayout.width, + oldHeight = oldFullLayout.height; + + plots.supplyLayoutGlobalDefaults(newLayout, newFullLayout); + + if(!newLayout.width) newFullLayout.width = oldWidth; + if(!newLayout.height) newFullLayout.height = oldHeight; + } + else { + // coerce the updated layout and autosize if needed + plots.supplyLayoutGlobalDefaults(newLayout, newFullLayout); + + var missingWidthOrHeight = (!newLayout.width || !newLayout.height), + autosize = newFullLayout.autosize, + autosizable = gd._context && gd._context.autosizable, + initialAutoSize = missingWidthOrHeight && (autosize || autosizable); + if(initialAutoSize) plots.plotAutoSize(gd, newLayout, newFullLayout); + else if(missingWidthOrHeight) plots.sanitizeMargins(gd); + + // for backwards-compatibility with Plotly v1.x.x + if(!autosize && missingWidthOrHeight) { + newLayout.width = newFullLayout.width; + newLayout.height = newFullLayout.height; + } + } + + newFullLayout._initialAutoSizeIsDone = true; // keep track of how many traces are inputted newFullLayout._dataLength = newData.length; @@ -522,6 +560,7 @@ plots.supplyDefaults = function(gd) { // relink functions and _ attributes to promote consistency between plots relinkPrivateKeys(newFullLayout, oldFullLayout); + // TODO may return a promise plots.doAutoMargin(gd); // can't quite figure out how to get rid of this... each axis needs @@ -730,11 +769,9 @@ plots.supplyLayoutGlobalDefaults = function(layoutIn, layoutOut) { color: globalFont.color }); - var autosize = coerce('autosize', - (layoutIn.width && layoutIn.height) ? false : 'initial'); + coerce('autosize'); coerce('width'); coerce('height'); - coerce('margin.l'); coerce('margin.r'); coerce('margin.t'); @@ -742,8 +779,7 @@ plots.supplyLayoutGlobalDefaults = function(layoutIn, layoutOut) { coerce('margin.pad'); coerce('margin.autoexpand'); - // called in plotAutoSize otherwise - if(autosize !== 'initial') plots.sanitizeMargins(layoutOut); + if(layoutIn.width && layoutIn.height) plots.sanitizeMargins(layoutOut); coerce('paper_bgcolor'); @@ -752,6 +788,93 @@ plots.supplyLayoutGlobalDefaults = function(layoutIn, layoutOut) { coerce('smith'); }; +plots.plotAutoSize = function plotAutoSize(gd, layout, fullLayout) { + var context = gd._context || {}, + frameMargins = context.frameMargins, + newWidth, + newHeight; + + var isPlotDiv = Lib.isPlotDiv(gd); + + if(isPlotDiv) gd.emit('plotly_autosize'); + + // embedded in an iframe - just take the full iframe size + // if we get to this point, with no aspect ratio restrictions + if(context.fillFrame) { + newWidth = window.innerWidth; + newHeight = window.innerHeight; + + // somehow we get a few extra px height sometimes... + // just hide it + document.body.style.overflow = 'hidden'; + } + else if(isNumeric(frameMargins) && frameMargins > 0) { + var reservedMargins = calculateReservedMargins(gd._boundingBoxMargins), + reservedWidth = reservedMargins.left + reservedMargins.right, + reservedHeight = reservedMargins.bottom + reservedMargins.top, + factor = 1 - 2 * frameMargins; + + var gdBB = fullLayout._container && fullLayout._container.node ? + fullLayout._container.node().getBoundingClientRect() : { + width: fullLayout.width, + height: fullLayout.height + }; + + newWidth = Math.round(factor * (gdBB.width - reservedWidth)); + newHeight = Math.round(factor * (gdBB.height - reservedHeight)); + } + else { + // plotly.js - let the developers do what they want, either + // provide height and width for the container div, + // specify size in layout, or take the defaults, + // but don't enforce any ratio restrictions + var computedStyle = isPlotDiv ? window.getComputedStyle(gd) : {}; + + newWidth = parseFloat(computedStyle.width) || fullLayout.width; + newHeight = parseFloat(computedStyle.height) || fullLayout.height; + } + + var minWidth = plots.layoutAttributes.width.min, + minHeight = plots.layoutAttributes.height.min; + if(newWidth < minWidth) newWidth = minWidth; + if(newHeight < minHeight) newHeight = minHeight; + + var widthHasChanged = !layout.width && + (Math.abs(fullLayout.width - newWidth) > 1), + heightHasChanged = !layout.height && + (Math.abs(fullLayout.height - newHeight) > 1); + + if(heightHasChanged || widthHasChanged) { + if(widthHasChanged) fullLayout.width = newWidth; + if(heightHasChanged) fullLayout.height = newHeight; + } + + plots.sanitizeMargins(fullLayout); +}; + +/** + * Reduce all reserved margin objects to a single required margin reservation. + * + * @param {Object} margins + * @returns {{left: number, right: number, bottom: number, top: number}} + */ +function calculateReservedMargins(margins) { + var resultingMargin = {left: 0, right: 0, bottom: 0, top: 0}, + marginName; + + if(margins) { + for(marginName in margins) { + if(margins.hasOwnProperty(marginName)) { + resultingMargin.left += margins[marginName].left || 0; + resultingMargin.right += margins[marginName].right || 0; + resultingMargin.bottom += margins[marginName].bottom || 0; + resultingMargin.top += margins[marginName].top || 0; + } + } + } + return resultingMargin; +} + plots.supplyLayoutModuleDefaults = function(layoutIn, layoutOut, fullData) { var i, _module; diff --git a/test/image/baselines/ternary_simple.png b/test/image/baselines/ternary_simple.png index c6d5869de40..111ead3bf5f 100644 Binary files a/test/image/baselines/ternary_simple.png and b/test/image/baselines/ternary_simple.png differ diff --git a/test/image/mocks/ternary_simple.json b/test/image/mocks/ternary_simple.json index ea1d78ff2a3..0f092db4a96 100644 --- a/test/image/mocks/ternary_simple.json +++ b/test/image/mocks/ternary_simple.json @@ -46,7 +46,6 @@ "bgcolor": "#eee" }, "height": 450, - "width": 700, - "autosize": true + "width": 700 } } diff --git a/test/jasmine/tests/config_test.js b/test/jasmine/tests/config_test.js index eeda25ab966..f066d4a1f07 100644 --- a/test/jasmine/tests/config_test.js +++ b/test/jasmine/tests/config_test.js @@ -1,10 +1,147 @@ var Plotly = require('@lib/index'); +var Plots = Plotly.Plots; var createGraphDiv = require('../assets/create_graph_div'); var destroyGraphDiv = require('../assets/destroy_graph_div'); var mouseEvent = require('../assets/mouse_event'); describe('config argument', function() { + describe('attribute layout.autosize', function() { + var layoutWidth = 1111, + relayoutWidth = 555, + containerWidthBeforePlot = 888, + containerWidthBeforeRelayout = 666, + containerHeightBeforePlot = 543, + containerHeightBeforeRelayout = 321, + data = [], + gd; + + beforeEach(function() { + gd = createGraphDiv(); + }); + + afterEach(destroyGraphDiv); + + function checkLayoutSize(width, height) { + expect(gd._fullLayout.width).toBe(width); + expect(gd._fullLayout.height).toBe(height); + + var svg = document.getElementsByClassName('main-svg')[0]; + expect(+svg.getAttribute('width')).toBe(width); + expect(+svg.getAttribute('height')).toBe(height); + } + + function compareLayoutAndFullLayout(gd) { + expect(gd.layout.width).toBe(gd._fullLayout.width); + expect(gd.layout.height).toBe(gd._fullLayout.height); + } + + function testAutosize(autosize, config, layoutHeight, relayoutHeight, done) { + var layout = { + autosize: autosize, + width: layoutWidth + + }, + relayout = { + width: relayoutWidth + }; + + var container = document.getElementById('graph'); + container.style.width = containerWidthBeforePlot + 'px'; + container.style.height = containerHeightBeforePlot + 'px'; + + Plotly.plot(gd, data, layout, config).then(function() { + checkLayoutSize(layoutWidth, layoutHeight); + if(!autosize) compareLayoutAndFullLayout(gd); + + container.style.width = containerWidthBeforeRelayout + 'px'; + container.style.height = containerHeightBeforeRelayout + 'px'; + + Plotly.relayout(gd, relayout).then(function() { + checkLayoutSize(relayoutWidth, relayoutHeight); + if(!autosize) compareLayoutAndFullLayout(gd); + done(); + }); + }); + } + + it('should fill the frame when autosize: false, fillFrame: true, frameMargins: undefined', function(done) { + var autosize = false, + config = { + autosizable: true, + fillFrame: true + }, + layoutHeight = window.innerHeight, + relayoutHeight = layoutHeight; + testAutosize(autosize, config, layoutHeight, relayoutHeight, done); + }); + + it('should fill the frame when autosize: true, fillFrame: true and frameMargins: undefined', function(done) { + var autosize = true, + config = { + fillFrame: true + }, + layoutHeight = window.innerHeight, + relayoutHeight = window.innerHeight; + testAutosize(autosize, config, layoutHeight, relayoutHeight, done); + }); + + it('should fill the container when autosize: false, fillFrame: false and frameMargins: undefined', function(done) { + var autosize = false, + config = { + autosizable: true, + fillFrame: false + }, + layoutHeight = containerHeightBeforePlot, + relayoutHeight = layoutHeight; + testAutosize(autosize, config, layoutHeight, relayoutHeight, done); + }); + + it('should fill the container when autosize: true, fillFrame: false and frameMargins: undefined', function(done) { + var autosize = true, + config = { + fillFrame: false + }, + layoutHeight = containerHeightBeforePlot, + relayoutHeight = containerHeightBeforeRelayout; + testAutosize(autosize, config, layoutHeight, relayoutHeight, done); + }); + + it('should fill the container when autosize: false, fillFrame: false and frameMargins: 0.1', function(done) { + var autosize = false, + config = { + autosizable: true, + fillFrame: false, + frameMargins: 0.1 + }, + layoutHeight = 360, + relayoutHeight = layoutHeight; + testAutosize(autosize, config, layoutHeight, relayoutHeight, done); + }); + + it('should fill the container when autosize: true, fillFrame: false and frameMargins: 0.1', function(done) { + var autosize = true, + config = { + fillFrame: false, + frameMargins: 0.1 + }, + layoutHeight = 360, + relayoutHeight = 288; + testAutosize(autosize, config, layoutHeight, relayoutHeight, done); + }); + + it('should respect attribute autosizable: false', function(done) { + var autosize = false, + config = { + autosizable: false, + fillFrame: true + }, + layoutHeight = Plots.layoutAttributes.height.dflt, + relayoutHeight = layoutHeight; + testAutosize(autosize, config, layoutHeight, relayoutHeight, done); + }); + }); + describe('showLink attribute', function() { var gd; diff --git a/test/jasmine/tests/lib_test.js b/test/jasmine/tests/lib_test.js index b736d31a73e..223ce6c1d3a 100644 --- a/test/jasmine/tests/lib_test.js +++ b/test/jasmine/tests/lib_test.js @@ -1041,4 +1041,10 @@ describe('Test lib.js:', function() { }).toThrowError('Separator string required for formatting!'); }); }); + + describe('isPlotDiv', function() { + it('should work on plain objects', function() { + expect(Lib.isPlotDiv({})).toBe(false); + }); + }); }); diff --git a/test/jasmine/tests/modebar_test.js b/test/jasmine/tests/modebar_test.js index b8a5c460e12..a0a020c3c3c 100644 --- a/test/jasmine/tests/modebar_test.js +++ b/test/jasmine/tests/modebar_test.js @@ -643,6 +643,7 @@ describe('ModeBar', function() { }]; var mockLayout = { + autosize: true, xaxis: { anchor: 'y', domain: [0, 0.5], diff --git a/test/jasmine/tests/plot_api_test.js b/test/jasmine/tests/plot_api_test.js index 7c92bbad4d0..3a34732fdb1 100644 --- a/test/jasmine/tests/plot_api_test.js +++ b/test/jasmine/tests/plot_api_test.js @@ -786,4 +786,35 @@ describe('Test plot api', function() { expect(gd.data[1].contours).toBeUndefined(); }); }); + + describe('Plotly.newPlot', function() { + var gd; + + beforeEach(function() { + gd = createGraphDiv(); + }); + + afterEach(destroyGraphDiv); + + it('should respect layout.width and layout.height', function(done) { + + // See issue https://github.com/plotly/plotly.js/issues/537 + var data = [{ + x: [1, 2], + y: [1, 2] + }]; + + Plotly.plot(gd, data).then(function() { + var height = 50; + + Plotly.newPlot(gd, data, { height: height }).then(function() { + var fullLayout = gd._fullLayout, + svg = document.getElementsByClassName('main-svg')[0]; + + expect(fullLayout.height).toBe(height); + expect(+svg.getAttribute('height')).toBe(height); + }).then(done); + }); + }); + }); }); diff --git a/test/jasmine/tests/plots_test.js b/test/jasmine/tests/plots_test.js index 3d46f8bd298..33226b1c1c3 100644 --- a/test/jasmine/tests/plots_test.js +++ b/test/jasmine/tests/plots_test.js @@ -7,6 +7,63 @@ var destroyGraphDiv = require('../assets/destroy_graph_div'); describe('Test Plots', function() { 'use strict'; + describe('Plotly.supplyDefaults', function() { + function testSanitizeMarginsHasBeenCalledOnlyOnce(gd) { + spyOn(Plots, 'sanitizeMargins').and.callThrough(); + Plots.supplyDefaults(gd); + expect(Plots.sanitizeMargins).toHaveBeenCalledTimes(1); + } + + it('should not throw an error when gd is a plain object', function() { + var height = 100, + gd = { + layout: { + height: height + } + }; + + Plots.supplyDefaults(gd); + expect(gd.layout.height).toBe(height); + expect(gd._fullLayout).toBeDefined(); + expect(gd._fullLayout.height).toBe(height); + expect(gd._fullLayout.width).toBe(Plots.layoutAttributes.width.dflt); + expect(gd._fullData).toBeDefined(); + }); + + it('should call sanitizeMargins only once when both width and height are defined', function() { + var gd = { + layout: { + width: 100, + height: 100 + } + }; + + testSanitizeMarginsHasBeenCalledOnlyOnce(gd); + }); + + it('should call sanitizeMargins only once when autosize is false', function() { + var gd = { + layout: { + autosize: false, + height: 100 + } + }; + + testSanitizeMarginsHasBeenCalledOnlyOnce(gd); + }); + + it('should call sanitizeMargins only once when autosize is true', function() { + var gd = { + layout: { + autosize: true, + height: 100 + } + }; + + testSanitizeMarginsHasBeenCalledOnlyOnce(gd); + }); + }); + describe('Plots.supplyLayoutGlobalDefaults should', function() { var layoutIn, layoutOut, @@ -326,7 +383,7 @@ describe('Test Plots', function() { beforeEach(function(done) { gd = createGraphDiv(); - Plotly.plot(gd, [{ x: [1, 2, 3], y: [2, 3, 4] }], {}) + Plotly.plot(gd, [{ x: [1, 2, 3], y: [2, 3, 4] }], { autosize: true }) .then(function() { gd.style.width = '400px'; gd.style.height = '400px'; diff --git a/test/jasmine/tests/toimage_test.js b/test/jasmine/tests/toimage_test.js index e9c28694f62..a8a2bd007dd 100644 --- a/test/jasmine/tests/toimage_test.js +++ b/test/jasmine/tests/toimage_test.js @@ -70,6 +70,8 @@ describe('Plotly.toImage', function() { subplotMock.layout.width = 700; Plotly.plot(gd, subplotMock.data, subplotMock.layout).then(function(gd) { + expect(gd.layout.height).toBe(600); + expect(gd.layout.width).toBe(700); return Plotly.toImage(gd); }).then(function(url) { return new Promise(function(resolve) {