From 94b8b54cefd59a67b26be571d4d950b2a2719477 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Mon, 8 Apr 2019 16:40:14 -0400 Subject: [PATCH 1/2] lint modebar button tests --- src/components/modebar/buttons.js | 2 -- src/snapshot/download.js | 3 +-- test/jasmine/tests/modebar_test.js | 21 +++++++++++---------- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/components/modebar/buttons.js b/src/components/modebar/buttons.js index 82422887afb..3266783e707 100644 --- a/src/components/modebar/buttons.js +++ b/src/components/modebar/buttons.js @@ -6,7 +6,6 @@ * LICENSE file in the root directory of this source tree. */ - 'use strict'; var Registry = require('../../registry'); @@ -44,7 +43,6 @@ var modeBarButtons = module.exports = {}; * @param {boolean} [toggle] * is the button a toggle button? */ - modeBarButtons.toImage = { name: 'toImage', title: function(gd) { diff --git a/src/snapshot/download.js b/src/snapshot/download.js index b5019520e74..64c3302a159 100644 --- a/src/snapshot/download.js +++ b/src/snapshot/download.js @@ -6,11 +6,10 @@ * LICENSE file in the root directory of this source tree. */ - 'use strict'; var toImage = require('../plot_api/to_image'); -var Lib = require('../lib'); // for isIE +var Lib = require('../lib'); var fileSaver = require('./filesaver'); /** Plotly.downloadImage diff --git a/test/jasmine/tests/modebar_test.js b/test/jasmine/tests/modebar_test.js index 29d06f1f218..37d854c2346 100644 --- a/test/jasmine/tests/modebar_test.js +++ b/test/jasmine/tests/modebar_test.js @@ -11,7 +11,6 @@ var destroyGraphDiv = require('../assets/destroy_graph_div'); var selectButton = require('../assets/modebar_button'); var failTest = require('../assets/fail_test'); - describe('ModeBar', function() { 'use strict'; @@ -960,10 +959,11 @@ describe('ModeBar', function() { Plotly.plot(gd, {data: [], layout: {}}) .then(function() { selectButton(gd._fullLayout._modeBar, 'toImage').click(); - expect(Registry.call).toHaveBeenCalledWith('downloadImage', gd, - {format: 'png'}); - done(); - }); + expect(Registry.call) + .toHaveBeenCalledWith('downloadImage', gd, {format: 'png'}); + }) + .catch(failTest) + .then(done); }); it('should accept overriding defaults', function(done) { @@ -973,13 +973,14 @@ describe('ModeBar', function() { filename: 'x', unsupported: 'should not pass' } - } }) + }}) .then(function() { selectButton(gd._fullLayout._modeBar, 'toImage').click(); - expect(Registry.call).toHaveBeenCalledWith('downloadImage', gd, - {format: 'svg', filename: 'x'}); - done(); - }); + expect(Registry.call) + .toHaveBeenCalledWith('downloadImage', gd, {format: 'svg', filename: 'x'}); + }) + .catch(failTest) + .then(done); }); }); From 6bff217df96dbca73c20c8ea94257ff6a4547e37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Mon, 8 Apr 2019 16:41:33 -0400 Subject: [PATCH 2/2] handle width:null|height:null as toImage valid args ... where in that case, we use graph's current width/height (as found in gd._fullLayout) for the exported dimensions. --- src/components/modebar/buttons.js | 2 +- src/plot_api/to_image.js | 26 +++++++++++++++++++++----- test/jasmine/tests/modebar_test.js | 13 +++++++++++++ test/jasmine/tests/toimage_test.js | 18 ++++++++++++++++++ 4 files changed, 53 insertions(+), 6 deletions(-) diff --git a/src/components/modebar/buttons.js b/src/components/modebar/buttons.js index 3266783e707..62bc7937e81 100644 --- a/src/components/modebar/buttons.js +++ b/src/components/modebar/buttons.js @@ -65,7 +65,7 @@ modeBarButtons.toImage = { } ['filename', 'width', 'height', 'scale'].forEach(function(key) { - if(toImageButtonOptions[key]) { + if(key in toImageButtonOptions) { opts[key] = toImageButtonOptions[key]; } }); diff --git a/src/plot_api/to_image.js b/src/plot_api/to_image.js index 4f27f26c304..c1a8c8733e1 100644 --- a/src/plot_api/to_image.js +++ b/src/plot_api/to_image.js @@ -8,6 +8,8 @@ 'use strict'; +var isNumeric = require('fast-isnumeric'); + var plotApi = require('./plot_api'); var Lib = require('../lib'); @@ -27,7 +29,8 @@ var attrs = { min: 1, description: [ 'Sets the exported image width.', - 'Defaults to the value found in `layout.width`' + 'Defaults to the value found in `layout.width`', + 'If set to *null*, the exported image width will match the current graph width.' ].join(' ') }, height: { @@ -35,7 +38,8 @@ var attrs = { min: 1, description: [ 'Sets the exported image height.', - 'Defaults to the value found in `layout.height`' + 'Defaults to the value found in `layout.height`', + 'If set to *null*, the exported image height will match the current graph height.' ].join(' ') }, scale: { @@ -87,23 +91,27 @@ function toImage(gd, opts) { var data; var layout; var config; + var fullLayout; if(Lib.isPlainObject(gd)) { data = gd.data || []; layout = gd.layout || {}; config = gd.config || {}; + fullLayout = {}; } else { gd = Lib.getGraphDiv(gd); data = Lib.extendDeep([], gd.data); layout = Lib.extendDeep({}, gd.layout); config = gd._context; + fullLayout = gd._fullLayout || {}; } function isImpliedOrValid(attr) { return !(attr in opts) || Lib.validate(opts[attr], attrs[attr]); } - if(!isImpliedOrValid('width') || !isImpliedOrValid('height')) { + if((!isImpliedOrValid('width') && opts.width !== null) || + (!isImpliedOrValid('height') && opts.height !== null)) { throw new Error('Height and width should be pixel values.'); } @@ -132,8 +140,16 @@ function toImage(gd, opts) { // extend layout with image options var layoutImage = Lib.extendFlat({}, layout); - if(width) layoutImage.width = width; - if(height) layoutImage.height = height; + if(width) { + layoutImage.width = width; + } else if(opts.width === null && isNumeric(fullLayout.width)) { + layoutImage.width = fullLayout.width; + } + if(height) { + layoutImage.height = height; + } else if(opts.height === null && isNumeric(fullLayout.height)) { + layoutImage.height = fullLayout.height; + } // extend config for static plot var configImage = Lib.extendFlat({}, config, { diff --git a/test/jasmine/tests/modebar_test.js b/test/jasmine/tests/modebar_test.js index 37d854c2346..923df01c78b 100644 --- a/test/jasmine/tests/modebar_test.js +++ b/test/jasmine/tests/modebar_test.js @@ -982,6 +982,19 @@ describe('ModeBar', function() { .catch(failTest) .then(done); }); + + it('should accept overriding defaults with null values', function(done) { + Plotly.plot(gd, {data: [], layout: {}, config: { + toImageButtonOptions: {width: null, height: null} + }}) + .then(function() { + selectButton(gd._fullLayout._modeBar, 'toImage').click(); + expect(Registry.call) + .toHaveBeenCalledWith('downloadImage', gd, {format: 'png', width: null, height: null}); + }) + .catch(failTest) + .then(done); + }); }); describe('cartesian handlers', function() { diff --git a/test/jasmine/tests/toimage_test.js b/test/jasmine/tests/toimage_test.js index ae3f10c9b09..45252af0aa8 100644 --- a/test/jasmine/tests/toimage_test.js +++ b/test/jasmine/tests/toimage_test.js @@ -115,6 +115,24 @@ describe('Plotly.toImage', function() { .then(done); }); + it('should use width/height of graph div when width/height are set to *null*', function(done) { + var fig = Lib.extendDeep({}, subplotMock); + + gd.style.width = '832px'; + gd.style.height = '502px'; + + Plotly.plot(gd, fig.data, fig.layout).then(function() { + expect(gd.layout.width).toBe(undefined, 'user layout width'); + expect(gd.layout.height).toBe(undefined, 'user layout height'); + expect(gd._fullLayout.width).toBe(832, 'full layout width'); + expect(gd._fullLayout.height).toBe(502, 'full layout height'); + }) + .then(function() { return Plotly.toImage(gd, {width: null, height: null}); }) + .then(function(url) { return assertSize(url, 832, 502); }) + .catch(failTest) + .then(done); + }); + it('should create proper file type', function(done) { var fig = Lib.extendDeep({}, subplotMock);