diff --git a/src/plots/plots.js b/src/plots/plots.js
index c28b8f3df72..34646cb5668 100644
--- a/src/plots/plots.js
+++ b/src/plots/plots.js
@@ -1864,6 +1864,9 @@ function initMargins(fullLayout) {
if(!fullLayout._pushmarginIds) fullLayout._pushmarginIds = {};
}
+var minFinalWidth = 64; // could possibly be exposed as layout.margin.minfinalwidth
+var minFinalHeight = 64; // could possibly be exposed as layout.margin.minfinalheight
+
/**
* autoMargin: called by components that may need to expand the margins to
* be rendered on-plot.
@@ -1881,6 +1884,10 @@ function initMargins(fullLayout) {
*/
plots.autoMargin = function(gd, id, o) {
var fullLayout = gd._fullLayout;
+ var width = fullLayout.width;
+ var height = fullLayout.height;
+ var maxSpaceW = Math.max(0, width - minFinalWidth);
+ var maxSpaceH = Math.max(0, height - minFinalHeight);
var pushMargin = fullLayout._pushmargin;
var pushMarginIds = fullLayout._pushmarginIds;
@@ -1900,13 +1907,15 @@ plots.autoMargin = function(gd, id, o) {
// if the item is too big, just give it enough automargin to
// make sure you can still grab it and bring it back
- if(o.l + o.r > fullLayout.width * 0.5) {
- Lib.log('Margin push', id, 'is too big in x, dropping');
- o.l = o.r = 0;
+ var rW = (o.l + o.r) / maxSpaceW;
+ if(rW > 1) {
+ o.l /= rW;
+ o.r /= rW;
}
- if(o.b + o.t > fullLayout.height * 0.5) {
- Lib.log('Margin push', id, 'is too big in y, dropping');
- o.b = o.t = 0;
+ var rH = (o.t + o.b) / maxSpaceH;
+ if(rH > 1) {
+ o.t /= rH;
+ o.b /= rH;
}
var xl = o.xl !== undefined ? o.xl : o.x;
@@ -1931,6 +1940,11 @@ plots.autoMargin = function(gd, id, o) {
plots.doAutoMargin = function(gd) {
var fullLayout = gd._fullLayout;
+ var width = fullLayout.width;
+ var height = fullLayout.height;
+ var maxSpaceW = Math.max(0, width - minFinalWidth);
+ var maxSpaceH = Math.max(0, height - minFinalHeight);
+
if(!fullLayout._size) fullLayout._size = {};
initMargins(fullLayout);
@@ -1945,8 +1959,6 @@ plots.doAutoMargin = function(gd) {
var mr = margin.r;
var mt = margin.t;
var mb = margin.b;
- var width = fullLayout.width;
- var height = fullLayout.height;
var pushMargin = fullLayout._pushmargin;
var pushMarginIds = fullLayout._pushmarginIds;
@@ -1978,11 +1990,10 @@ plots.doAutoMargin = function(gd) {
if(isNumeric(pl) && pushMargin[k2].r) {
var fr = pushMargin[k2].r.val;
var pr = pushMargin[k2].r.size;
-
if(fr > fl) {
var newL = (pl * fr + (pr - width) * fl) / (fr - fl);
var newR = (pr * (1 - fl) + (pl - width) * (1 - fr)) / (fr - fl);
- if(newL >= 0 && newR >= 0 && width - (newL + newR) > 0 && newL + newR > ml + mr) {
+ if(newL + newR > ml + mr) {
ml = newL;
mr = newR;
}
@@ -1992,11 +2003,10 @@ plots.doAutoMargin = function(gd) {
if(isNumeric(pb) && pushMargin[k2].t) {
var ft = pushMargin[k2].t.val;
var pt = pushMargin[k2].t.size;
-
if(ft > fb) {
var newB = (pb * ft + (pt - height) * fb) / (ft - fb);
var newT = (pt * (1 - fb) + (pb - height) * (1 - ft)) / (ft - fb);
- if(newB >= 0 && newT >= 0 && height - (newT + newB) > 0 && newB + newT > mb + mt) {
+ if(newB + newT > mb + mt) {
mb = newB;
mt = newT;
}
@@ -2006,6 +2016,18 @@ plots.doAutoMargin = function(gd) {
}
}
+ var rW = (ml + mr) / maxSpaceW;
+ if(rW > 1) {
+ ml /= rW;
+ mr /= rW;
+ }
+
+ var rH = (mb + mt) / maxSpaceH;
+ if(rH > 1) {
+ mb /= rH;
+ mt /= rH;
+ }
+
gs.l = Math.round(ml);
gs.r = Math.round(mr);
gs.t = Math.round(mt);
diff --git a/test/image/baselines/automargin-large-margins-both-sides.png b/test/image/baselines/automargin-large-margins-both-sides.png
new file mode 100644
index 00000000000..fc17d8fe808
Binary files /dev/null and b/test/image/baselines/automargin-large-margins-both-sides.png differ
diff --git a/test/image/baselines/automargin-large-margins-horizontal.png b/test/image/baselines/automargin-large-margins-horizontal.png
new file mode 100644
index 00000000000..2641dd8d97e
Binary files /dev/null and b/test/image/baselines/automargin-large-margins-horizontal.png differ
diff --git a/test/image/baselines/automargin-large-margins.png b/test/image/baselines/automargin-large-margins.png
new file mode 100644
index 00000000000..dad69bba747
Binary files /dev/null and b/test/image/baselines/automargin-large-margins.png differ
diff --git a/test/image/baselines/legend_small_horizontal.png b/test/image/baselines/legend_small_horizontal.png
index 97445e02ebe..925f8396be2 100644
Binary files a/test/image/baselines/legend_small_horizontal.png and b/test/image/baselines/legend_small_horizontal.png differ
diff --git a/test/image/mocks/automargin-large-margins-both-sides.json b/test/image/mocks/automargin-large-margins-both-sides.json
new file mode 100644
index 00000000000..66c741b0bea
--- /dev/null
+++ b/test/image/mocks/automargin-large-margins-both-sides.json
@@ -0,0 +1,54 @@
+{
+ "data": [{
+ "name": "< D E A T H >",
+ "marker": { "color": "red" },
+ "y": [
+ "Antonio Vivaldi",
+ "Johann Sebastian Bach",
+ "Wolfgang Amadeus Mozart",
+ "Ludwig van Beethoven"
+ ],
+ "x": [
+ "1741",
+ "1750",
+ "1791",
+ "1827"
+ ]
+ },
+ {
+ "name": "< B I R T H >",
+ "marker": { "color": "blue" },
+ "y": [
+ "Antonio Vivaldi",
+ "Johann Sebastian Bach",
+ "Wolfgang Amadeus Mozart",
+ "Ludwig van Beethoven"
+ ],
+ "x": [
+ "1678",
+ "1685",
+ "1756",
+ "1770"
+ ]
+ }],
+ "layout": {
+ "title": {
+ "text": "Longest and shortest
names and time periods"
+ },
+ "width": 200,
+ "height": 200,
+ "margin": {
+ "t": 80,
+ "b": 20,
+ "l": 20,
+ "r": 20
+ },
+ "xaxis": {
+ "type": "date",
+ "automargin": true
+ },
+ "yaxis": {
+ "automargin": true
+ }
+ }
+}
diff --git a/test/image/mocks/automargin-large-margins-horizontal.json b/test/image/mocks/automargin-large-margins-horizontal.json
new file mode 100644
index 00000000000..931e87a4731
--- /dev/null
+++ b/test/image/mocks/automargin-large-margins-horizontal.json
@@ -0,0 +1,55 @@
+{
+ "data": [{
+ "name": "< D E A T H >",
+ "marker": { "color": "red" },
+ "y": [
+ "Antonio Vivaldi",
+ "Johann Sebastian Bach",
+ "Wolfgang Amadeus Mozart",
+ "Ludwig van Beethoven"
+ ],
+ "x": [
+ "1741",
+ "1750",
+ "1791",
+ "1827"
+ ]
+ },
+ {
+ "name": "< B I R T H >",
+ "marker": { "color": "blue" },
+ "y": [
+ "Antonio Vivaldi",
+ "Johann Sebastian Bach",
+ "Wolfgang Amadeus Mozart",
+ "Ludwig van Beethoven"
+ ],
+ "x": [
+ "1678",
+ "1685",
+ "1756",
+ "1770"
+ ]
+ }],
+ "layout": {
+ "showlegend": false,
+ "title": {
+ "text": "Longest and shortest
names and time periods"
+ },
+ "width": 240,
+ "height": 200,
+ "margin": {
+ "t": 80,
+ "b": 20,
+ "l": 20,
+ "r": 20
+ },
+ "xaxis": {
+ "type": "date",
+ "automargin": true
+ },
+ "yaxis": {
+ "automargin": true
+ }
+ }
+}
diff --git a/test/image/mocks/automargin-large-margins.json b/test/image/mocks/automargin-large-margins.json
new file mode 100644
index 00000000000..589ba2a2213
--- /dev/null
+++ b/test/image/mocks/automargin-large-margins.json
@@ -0,0 +1,54 @@
+{
+ "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,
+ "margin": {
+ "t": 80,
+ "b": 20,
+ "l": 20,
+ "r": 20
+ },
+ "yaxis": {
+ "type": "date",
+ "automargin": true
+ },
+ "xaxis": {
+ "automargin": true
+ }
+ }
+}
diff --git a/test/jasmine/tests/axes_test.js b/test/jasmine/tests/axes_test.js
index 7a135ba11c0..c6f864dda9b 100644
--- a/test/jasmine/tests/axes_test.js
+++ b/test/jasmine/tests/axes_test.js
@@ -3856,7 +3856,7 @@ describe('Test axes', function() {
.then(function() { return Plotly.relayout(gd, 'height', 100); })
.then(function() {
_assert('after relayout to *small* height', {
- bottomLowerBound: 30,
+ bottomLowerBound: 15,
totalHeight: 100
});
})
@@ -3896,7 +3896,7 @@ describe('Test axes', function() {
.then(function() { return Plotly.relayout(gd, 'width', 100); })
.then(function() {
_assert('after relayout to *small* width', {
- leftLowerBound: 30,
+ leftLowerBound: 15,
totalWidth: 100
});
})
diff --git a/test/jasmine/tests/indicator_test.js b/test/jasmine/tests/indicator_test.js
index 4bc28714830..69f247d31b5 100644
--- a/test/jasmine/tests/indicator_test.js
+++ b/test/jasmine/tests/indicator_test.js
@@ -171,7 +171,7 @@ describe('Indicator plot', function() {
return Plotly.relayout(gd, {width: 200, height: 200});
})
.then(function() {
- checkNumbersScale(0.2, 'should scale down');
+ checkNumbersScale(0.4794007490636704, 'should scale down');
return Plotly.relayout(gd, {width: 400, height: 400});
})
.then(function() {
diff --git a/test/jasmine/tests/legend_scroll_test.js b/test/jasmine/tests/legend_scroll_test.js
index 3ae4942c6f0..e1e31f7c3e7 100644
--- a/test/jasmine/tests/legend_scroll_test.js
+++ b/test/jasmine/tests/legend_scroll_test.js
@@ -405,7 +405,7 @@ describe('The legend', function() {
expect(countLegendClipPaths(gd)).toBe(1);
// clippath resized to new height less than new plot height
- expect(+legendHeight).toBe(getPlotHeight(gd));
+ expect(+legendHeight).toBeGreaterThan(getPlotHeight(gd));
expect(+legendHeight).toBeLessThan(+origLegendHeight);
done();
diff --git a/test/jasmine/tests/mock_test.js b/test/jasmine/tests/mock_test.js
index 86825fc7e0d..833407c8596 100644
--- a/test/jasmine/tests/mock_test.js
+++ b/test/jasmine/tests/mock_test.js
@@ -39,6 +39,9 @@ var list = [
'annotations',
'annotations-autorange',
'arrow-markers',
+ 'automargin-large-margins',
+ 'automargin-large-margins-both-sides',
+ 'automargin-large-margins-horizontal',
'automargin-mirror-all',
'automargin-mirror-allticks',
'automargin-multiline-titles',
@@ -1103,6 +1106,9 @@ figs['animation_bar'] = require('@mocks/animation_bar');
// figs['annotations'] = require('@mocks/annotations');
// figs['annotations-autorange'] = require('@mocks/annotations-autorange');
figs['arrow-markers'] = require('@mocks/arrow-markers');
+figs['automargin-large-margins'] = require('@mocks/automargin-large-margins');
+figs['automargin-large-margins-both-sides'] = require('@mocks/automargin-large-margins-both-sides');
+figs['automargin-large-margins-horizontal'] = require('@mocks/automargin-large-margins-horizontal');
figs['automargin-mirror-all'] = require('@mocks/automargin-mirror-all');
figs['automargin-mirror-allticks'] = require('@mocks/automargin-mirror-allticks');
figs['automargin-multiline-titles'] = require('@mocks/automargin-multiline-titles');