diff --git a/draftlogs/6307_add.md b/draftlogs/6307_add.md
new file mode 100644
index 00000000000..f3240a3a6a7
--- /dev/null
+++ b/draftlogs/6307_add.md
@@ -0,0 +1 @@
+Add `minreducedwidth` and `minreducedheight` as layout parameters [[#6307](https://github.com/plotly/plotly.js/pull/6307)]
\ No newline at end of file
diff --git a/src/plots/layout_attributes.js b/src/plots/layout_attributes.js
index cc6e4d973a5..38fe31ed189 100644
--- a/src/plots/layout_attributes.js
+++ b/src/plots/layout_attributes.js
@@ -189,6 +189,20 @@ module.exports = {
'Sets the plot\'s height (in px).'
].join(' ')
},
+ minreducedwidth: {
+ valType: 'number',
+ min: 2,
+ dflt: 64,
+ editType: 'plot',
+ description: 'Minimum width of the plot with margin.automargin applied (in px)'
+ },
+ minreducedheight: {
+ valType: 'number',
+ min: 2,
+ dflt: 64,
+ editType: 'plot',
+ description: 'Minimum height of the plot with margin.automargin applied (in px)'
+ },
margin: {
l: {
valType: 'number',
diff --git a/src/plots/plots.js b/src/plots/plots.js
index e7018f70647..7b28bc9b543 100644
--- a/src/plots/plots.js
+++ b/src/plots/plots.js
@@ -1506,6 +1506,9 @@ plots.supplyLayoutGlobalDefaults = function(layoutIn, layoutOut, formatObj) {
coerce('width');
coerce('height');
+ coerce('minreducedwidth');
+ coerce('minreducedheight');
+
coerce('margin.l');
coerce('margin.r');
coerce('margin.t');
@@ -1861,10 +1864,6 @@ function initMargins(fullLayout) {
var MIN_SPECIFIED_WIDTH = 2;
var MIN_SPECIFIED_HEIGHT = 2;
-// could be exposed as an option - the smallest we will allow automargin to shrink a larger plot
-var MIN_REDUCED_WIDTH = 64;
-var MIN_REDUCED_HEIGHT = 64;
-
/**
* autoMargin: called by components that may need to expand the margins to
* be rendered on-plot.
@@ -1885,17 +1884,19 @@ plots.autoMargin = function(gd, id, o) {
var width = fullLayout.width;
var height = fullLayout.height;
var margin = fullLayout.margin;
+ var minreducedwidth = fullLayout.minreducedwidth;
+ var minreducedheight = fullLayout.minreducedheight;
var minFinalWidth = Lib.constrain(
width - margin.l - margin.r,
MIN_SPECIFIED_WIDTH,
- MIN_REDUCED_WIDTH
+ minreducedwidth
);
var minFinalHeight = Lib.constrain(
height - margin.t - margin.b,
MIN_SPECIFIED_HEIGHT,
- MIN_REDUCED_HEIGHT
+ minreducedheight
);
var maxSpaceW = Math.max(0, width - minFinalWidth);
@@ -1974,6 +1975,8 @@ plots.doAutoMargin = function(gd) {
var mb = margin.b;
var pushMargin = fullLayout._pushmargin;
var pushMarginIds = fullLayout._pushmarginIds;
+ var minreducedwidth = fullLayout.minreducedwidth;
+ var minreducedheight = fullLayout.minreducedheight;
if(fullLayout.margin.autoexpand !== false) {
for(var k in pushMargin) {
@@ -2032,13 +2035,13 @@ plots.doAutoMargin = function(gd) {
var minFinalWidth = Lib.constrain(
width - margin.l - margin.r,
MIN_SPECIFIED_WIDTH,
- MIN_REDUCED_WIDTH
+ minreducedwidth
);
var minFinalHeight = Lib.constrain(
height - margin.t - margin.b,
MIN_SPECIFIED_HEIGHT,
- MIN_REDUCED_HEIGHT
+ minreducedheight
);
var maxSpaceW = Math.max(0, width - minFinalWidth);
diff --git a/test/image/baselines/z-automargin-minreducedheight.png b/test/image/baselines/z-automargin-minreducedheight.png
new file mode 100644
index 00000000000..af407e59e68
Binary files /dev/null and b/test/image/baselines/z-automargin-minreducedheight.png differ
diff --git a/test/image/baselines/z-automargin-minreducedwidth.png b/test/image/baselines/z-automargin-minreducedwidth.png
new file mode 100644
index 00000000000..a4ea346f052
Binary files /dev/null and b/test/image/baselines/z-automargin-minreducedwidth.png differ
diff --git a/test/image/mocks/z-automargin-minreducedheight.json b/test/image/mocks/z-automargin-minreducedheight.json
new file mode 100644
index 00000000000..7e48b8085f4
--- /dev/null
+++ b/test/image/mocks/z-automargin-minreducedheight.json
@@ -0,0 +1,55 @@
+{
+ "data": [{
+ "name": "< D E A T H >",
+ "marker": { "color": "red" },
+ "x": [
+ "Antonio Vivaldi",
+ "Johann Sebastian Bach",
+ "Wolfgang Amadeus Mozart",
+ "Ludwig van Beethoven"
+ ],
+ "y": [
+ "1741",
+ "1750",
+ "1791",
+ "1827"
+ ]
+ },
+ {
+ "name": "< B I R T H >",
+ "marker": { "color": "blue" },
+ "x": [
+ "Antonio Vivaldi",
+ "Johann Sebastian Bach",
+ "Wolfgang Amadeus Mozart",
+ "Ludwig van Beethoven"
+ ],
+ "y": [
+ "1678",
+ "1685",
+ "1756",
+ "1770"
+ ]
+ }],
+ "layout": {
+ "title": {
+ "text": "Longest and shortest
names and time periods"
+ },
+ "width": 240,
+ "height": 300,
+ "minreducedheight": 55,
+ "margin": {
+ "t": 80,
+ "b": 20,
+ "l": 20,
+ "r": 20
+ },
+ "yaxis": {
+ "type": "date",
+ "automargin": true
+ },
+ "xaxis": {
+ "automargin": true
+ }
+ }
+}
diff --git a/test/image/mocks/z-automargin-minreducedwidth.json b/test/image/mocks/z-automargin-minreducedwidth.json
new file mode 100644
index 00000000000..56ce67a9de4
--- /dev/null
+++ b/test/image/mocks/z-automargin-minreducedwidth.json
@@ -0,0 +1,56 @@
+{
+ "data": [{
+ "name": "< D E A T H >",
+ "marker": { "color": "red" },
+ "y": [
+ "A n t o n i o V i v a l d i",
+ "J o h a n n S e b a s t i a n B a c h",
+ "W o l f g a n g A m a d e u s M o z a r t",
+ "L u d w i g v a n B e e t h o v e n"
+ ],
+ "x": [
+ "1741",
+ "1750",
+ "1791",
+ "1827"
+ ]
+ },
+ {
+ "name": "< B I R T H >",
+ "marker": { "color": "blue" },
+ "y": [
+ "A n t o n i o V i v a l d i",
+ "J o h a n n S e b a s t i a n B a c h",
+ "W o l f g a n g A m a d e u s M o z a r t",
+ "L u d w i g v a n B e e t h o v e n"
+ ],
+ "x": [
+ "1678",
+ "1685",
+ "1756",
+ "1770"
+ ]
+ }],
+ "layout": {
+ "showlegend": false,
+ "title": {
+ "text": "Longest and shortest
names and time periods"
+ },
+ "width": 240,
+ "height": 200,
+ "minreducedwidth": 55,
+ "margin": {
+ "t": 80,
+ "b": 20,
+ "l": 20,
+ "r": 20
+ },
+ "xaxis": {
+ "type": "date",
+ "automargin": true
+ },
+ "yaxis": {
+ "automargin": true
+ }
+ }
+}
diff --git a/test/jasmine/tests/plots_test.js b/test/jasmine/tests/plots_test.js
index 3191ff11d2c..13c5fa6b941 100644
--- a/test/jasmine/tests/plots_test.js
+++ b/test/jasmine/tests/plots_test.js
@@ -1326,3 +1326,46 @@ describe('grids', function() {
.then(done, done.fail);
});
});
+
+describe('Test Plots with automargin and minreducedwidth/height', function() {
+ var gd;
+
+ beforeEach(function() {
+ gd = createGraphDiv();
+ });
+
+ afterEach(destroyGraphDiv);
+
+ it('should resize the plot area when tweaking min-reduced width & height', function(done) {
+ function assert(attr, exp) {
+ var xy = d3Select('rect.nsewdrag')[0][0];
+ expect(xy.getAttribute(attr)).toEqual(exp);
+ }
+
+ function assertClose(attr, exp) {
+ var xy = d3Select('rect.nsewdrag')[0][0];
+ expect(xy.getAttribute(attr)).toBeCloseTo(exp, -1);
+ }
+
+ var fig = require('@mocks/z-automargin-minreducedheight.json');
+
+ Plotly.newPlot(gd, fig)
+ .then(function() {
+ assertClose('height', '55');
+ })
+ .then(function() {
+ return Plotly.relayout(gd, 'minreducedheight', 100);
+ })
+ .then(function() {
+ assert('height', '100');
+ })
+ .then(function() {
+ return Plotly.relayout(gd, 'minreducedwidth', 100);
+ })
+ .then(function() {
+ assert('width', '100');
+ assert('height', '100');
+ })
+ .then(done, done.fail);
+ });
+});
diff --git a/test/plot-schema.json b/test/plot-schema.json
index 7b882a3ea25..29bcfafc16e 100644
--- a/test/plot-schema.json
+++ b/test/plot-schema.json
@@ -3386,6 +3386,20 @@
"editType": "none",
"valType": "string"
},
+ "minreducedheight": {
+ "description": "Minimum height of the plot with margin.automargin applied (in px)",
+ "dflt": 64,
+ "editType": "plot",
+ "min": 2,
+ "valType": "number"
+ },
+ "minreducedwidth": {
+ "description": "Minimum width of the plot with margin.automargin applied (in px)",
+ "dflt": 64,
+ "editType": "plot",
+ "min": 2,
+ "valType": "number"
+ },
"modebar": {
"activecolor": {
"description": "Sets the color of the active or hovered on icons in the modebar.",