diff --git a/src/components/legend/draw.js b/src/components/legend/draw.js index 58dfb61243d..f443e614339 100644 --- a/src/components/legend/draw.js +++ b/src/components/legend/draw.js @@ -169,10 +169,9 @@ module.exports = function draw(gd) { // Make sure the legend left and right sides are visible var legendWidth = opts._width; - var legendWidthMax = gs.w; + var legendWidthMax = gs.w * Math.max(1 - opts.x, 1); if(legendWidth > legendWidthMax) { - lx = gs.l; legendWidth = legendWidthMax; } else { @@ -185,11 +184,14 @@ module.exports = function draw(gd) { // (legends with a scroll bar are not allowed to stretch beyond the extended // margins) var legendHeight = opts._height; - var legendHeightMax = gs.h; + var legendHeightMax = gs.h * Math.max(opts.y, 1); + var padY = 12; if(legendHeight > legendHeightMax) { - ly = gs.t; legendHeight = legendHeightMax; + if(!helpers.isVertical(opts)) { + ly += padY; + } } else { if(ly + legendHeight > lyMax) ly = lyMax - legendHeight; @@ -638,13 +640,14 @@ function computeLegendDimensions(gd, groups, traces) { }); // check if legend fits in one row - var oneRowLegend = fullLayout._size.w > borderwidth + fullTracesWidth - traceGap; + var legendWidthMax = fullLayout._size.w * Math.max(1 - opts.x, 1); + var oneRowLegend = legendWidthMax > borderwidth + fullTracesWidth - traceGap; traces.each(function(d) { var legendItem = d[0]; var traceWidth = oneRowLegend ? 40 + d[0].width : maxTraceWidth; - if((borderwidth + offsetX + traceGap + traceWidth) > fullLayout._size.w) { + if((borderwidth + offsetX + traceGap + traceWidth) > legendWidthMax) { offsetX = 0; rowHeight += maxTraceHeight; opts._height += maxTraceHeight; diff --git a/src/plots/plots.js b/src/plots/plots.js index 9fa2616a69e..d0517210195 100644 --- a/src/plots/plots.js +++ b/src/plots/plots.js @@ -1802,8 +1802,17 @@ 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) o.l = o.r = 0; - if(o.b + o.t > fullLayout.height * 0.5) o.b = o.t = 0; + var rescaleFactor; + if(o.l + o.r > (fullLayout.width * 0.5)) { + rescaleFactor = (fullLayout.width * 0.5) / (o.l + o.r); + o.l *= rescaleFactor; + o.r *= rescaleFactor; + } + if(o.b + o.t > (fullLayout.height * 0.5)) { + rescaleFactor = (fullLayout.height * 0.5) / (o.b + o.t); + o.b *= rescaleFactor; + o.t *= rescaleFactor; + } var xl = o.xl !== undefined ? o.xl : o.x; var xr = o.xr !== undefined ? o.xr : o.x; diff --git a/test/image/baselines/legend_negative_x.png b/test/image/baselines/legend_negative_x.png new file mode 100644 index 00000000000..e137976024d Binary files /dev/null and b/test/image/baselines/legend_negative_x.png differ diff --git a/test/image/baselines/legend_small_horizontal.png b/test/image/baselines/legend_small_horizontal.png new file mode 100644 index 00000000000..941f03d6b6b Binary files /dev/null and b/test/image/baselines/legend_small_horizontal.png differ diff --git a/test/image/baselines/legend_small_vertical.png b/test/image/baselines/legend_small_vertical.png new file mode 100644 index 00000000000..4bfd0b9da91 Binary files /dev/null and b/test/image/baselines/legend_small_vertical.png differ diff --git a/test/image/mocks/legend_negative_x.json b/test/image/mocks/legend_negative_x.json new file mode 100644 index 00000000000..7109c7ee462 --- /dev/null +++ b/test/image/mocks/legend_negative_x.json @@ -0,0 +1,51 @@ +{ + "data": [{ + "x": [0, 1, 2, 3, 4, 5, 6, 7, 8], + "y": [0, 3, 6, 4, 5, 2, 3, 5, 4], + "type": "scatter" + }, + { + "x": [0, 1, 2, 3, 4, 5, 6, 7, 8], + "y": [0, 4, 7, 8, 3, 6, 3, 3, 4], + "type": "scatter" + }, + { + "x": [0, 1, 2, 3, 4, 5, 6, 7, 8], + "y": [0, 4, 7, 8, 3, 6, 3, 3, 4], + "type": "scatter" + }, + { + "x": [0, 1, 2, 3, 4, 5, 6, 7, 8], + "y": [0, 4, 7, 8, 3, 6, 3, 3, 4], + "type": "scatter" + }, + { + "x": [0, 1, 2, 3, 4, 5, 6, 7, 8], + "y": [0, 4, 7, 8, 3, 6, 3, 3, 4], + "type": "scatter" + }, + { + "x": [0, 1, 2, 3, 4, 5, 6, 7, 8], + "y": [0, 4, 7, 8, 3, 6, 3, 3, 4], + "type": "scatter" + } + ], + "layout": { + "showlegend": true, + "legend": { + "orientation": "h", + "traceorder": "reversed", + "x": -0.5, + "y": 1.2 + }, + "margin": { + "l": 125, + "r": 5, + "b": 30, + "t": 20, + "pad": 0 + }, + "height": 350, + "width": 700 + } +} diff --git a/test/image/mocks/legend_small_horizontal.json b/test/image/mocks/legend_small_horizontal.json new file mode 100644 index 00000000000..2480d5b553d --- /dev/null +++ b/test/image/mocks/legend_small_horizontal.json @@ -0,0 +1,104 @@ +{ +"layout": { + "legend": { + "orientation": "h", + "bordercolor": "#000000", + "borderwidth": 1, + "bgcolor": "#ffffff00" + }, + "margin": { + "t": 25, + "b": 25, + "r": 25, + "l": 25 + }, + "width":500, + "height":200 +}, +"data": [ + { + "x": [1, 2, 3, 4], + "y": [63.69, 62.55, 61.64, 61.39] + }, { + "x": [1, 2, 3, 4], + "y": [58.24, 54.93, 42.11, 50.75] + }, { + "x": [1, 2, 3, 4], + "y": [51.49, 49.59, 37.12, 31.45] + }, { + "x": [1, 2, 3, 4], + "y": [49.09, 58.54, 53.91, 43.12] + }, { + "x": [1, 2, 3, 4], + "y": [70.53, 72.51, 72.28, 78.65] + }, { + "x": [1, 2, 3, 4], + "y": [62.69, 59.09, 63.82, 62] + }, { + "x": [1, 2, 3, 4], + "y": [76.27, 71.43, 59.83, 64.34] + }, { + "x": [1, 2, 3, 4], + "y": [71.15, 81.82, 88.46, 74.29] + }, { + "x": [1, 2, 3, 4], + "y": [57.89, 57.38, 52.08, 63.83] + }, { + "x": [1, 2, 3, 4], + "y": [65.4, 63.27, 65.78, 64.03] + }, { + "x": [1, 2, 3, 4], + "y": [58.24, 54.93, 42.11, 50.75] + }, { + "x": [1, 2, 3, 4], + "y": [51.49, 49.59, 37.12, 31.45] + }, { + "x": [1, 2, 3, 4], + "y": [49.09, 58.54, 53.91, 43.12] + }, { + "x": [1, 2, 3, 4], + "y": [70.53, 72.51, 72.28, 78.65] + }, { + "x": [1, 2, 3, 4], + "y": [62.69, 59.09, 63.82, 62] + }, { + "x": [1, 2, 3, 4], + "y": [76.27, 71.43, 59.83, 64.34] + }, { + "x": [1, 2, 3, 4], + "y": [71.15, 81.82, 88.46, 74.29] + }, { + "x": [1, 2, 3, 4], + "y": [57.89, 57.38, 52.08, 63.83] + }, { + "x": [1, 2, 3, 4], + "y": [65.4, 63.27, 65.78, 64.03] + }, { + "x": [1, 2, 3, 4], + "y": [58.24, 54.93, 42.11, 50.75] + }, { + "x": [1, 2, 3, 4], + "y": [51.49, 49.59, 37.12, 31.45] + }, { + "x": [1, 2, 3, 4], + "y": [49.09, 58.54, 53.91, 43.12] + }, { + "x": [1, 2, 3, 4], + "y": [70.53, 72.51, 72.28, 78.65] + }, { + "x": [1, 2, 3, 4], + "y": [62.69, 59.09, 63.82, 62] + }, { + "x": [1, 2, 3, 4], + "y": [76.27, 71.43, 59.83, 64.34] + }, { + "x": [1, 2, 3, 4], + "y": [71.15, 81.82, 88.46, 74.29] + }, { + "x": [1, 2, 3, 4], + "y": [57.89, 57.38, 52.08, 63.83] + }, { + "x": [1, 2, 3, 4], + "y": [65.4, 63.27, 65.78, 64.03] + }] +} diff --git a/test/image/mocks/legend_small_vertical.json b/test/image/mocks/legend_small_vertical.json new file mode 100644 index 00000000000..78b5b1d6ed0 --- /dev/null +++ b/test/image/mocks/legend_small_vertical.json @@ -0,0 +1,104 @@ +{ +"layout": { + "legend": { + "orientation": "v", + "bordercolor": "#000000", + "borderwidth": 1, + "bgcolor": "#ffffff00" + }, + "margin": { + "t": 25, + "b": 25, + "r": 25, + "l": 25 + }, + "width":200, + "height":500 +}, +"data": [ + { + "x": [1, 2, 3, 4], + "y": [63.69, 62.55, 61.64, 61.39] + }, { + "x": [1, 2, 3, 4], + "y": [58.24, 54.93, 42.11, 50.75] + }, { + "x": [1, 2, 3, 4], + "y": [51.49, 49.59, 37.12, 31.45] + }, { + "x": [1, 2, 3, 4], + "y": [49.09, 58.54, 53.91, 43.12] + }, { + "x": [1, 2, 3, 4], + "y": [70.53, 72.51, 72.28, 78.65] + }, { + "x": [1, 2, 3, 4], + "y": [62.69, 59.09, 63.82, 62] + }, { + "x": [1, 2, 3, 4], + "y": [76.27, 71.43, 59.83, 64.34] + }, { + "x": [1, 2, 3, 4], + "y": [71.15, 81.82, 88.46, 74.29] + }, { + "x": [1, 2, 3, 4], + "y": [57.89, 57.38, 52.08, 63.83] + }, { + "x": [1, 2, 3, 4], + "y": [65.4, 63.27, 65.78, 64.03] + }, { + "x": [1, 2, 3, 4], + "y": [58.24, 54.93, 42.11, 50.75] + }, { + "x": [1, 2, 3, 4], + "y": [51.49, 49.59, 37.12, 31.45] + }, { + "x": [1, 2, 3, 4], + "y": [49.09, 58.54, 53.91, 43.12] + }, { + "x": [1, 2, 3, 4], + "y": [70.53, 72.51, 72.28, 78.65] + }, { + "x": [1, 2, 3, 4], + "y": [62.69, 59.09, 63.82, 62] + }, { + "x": [1, 2, 3, 4], + "y": [76.27, 71.43, 59.83, 64.34] + }, { + "x": [1, 2, 3, 4], + "y": [71.15, 81.82, 88.46, 74.29] + }, { + "x": [1, 2, 3, 4], + "y": [57.89, 57.38, 52.08, 63.83] + }, { + "x": [1, 2, 3, 4], + "y": [65.4, 63.27, 65.78, 64.03] + }, { + "x": [1, 2, 3, 4], + "y": [58.24, 54.93, 42.11, 50.75] + }, { + "x": [1, 2, 3, 4], + "y": [51.49, 49.59, 37.12, 31.45] + }, { + "x": [1, 2, 3, 4], + "y": [49.09, 58.54, 53.91, 43.12] + }, { + "x": [1, 2, 3, 4], + "y": [70.53, 72.51, 72.28, 78.65] + }, { + "x": [1, 2, 3, 4], + "y": [62.69, 59.09, 63.82, 62] + }, { + "x": [1, 2, 3, 4], + "y": [76.27, 71.43, 59.83, 64.34] + }, { + "x": [1, 2, 3, 4], + "y": [71.15, 81.82, 88.46, 74.29] + }, { + "x": [1, 2, 3, 4], + "y": [57.89, 57.38, 52.08, 63.83] + }, { + "x": [1, 2, 3, 4], + "y": [65.4, 63.27, 65.78, 64.03] + }] +}