diff --git a/src/components/legend/attributes.js b/src/components/legend/attributes.js index 60eb1f8bc22..f72791bb463 100644 --- a/src/components/legend/attributes.js +++ b/src/components/legend/attributes.js @@ -267,7 +267,7 @@ module.exports = { }), side: { valType: 'enumerated', - values: ['top', 'left', 'top left'], + values: ['top', 'left', 'top left', 'top center', 'top right'], editType: 'legend', description: [ 'Determines the location of legend\'s title', @@ -275,6 +275,7 @@ module.exports = { 'Defaulted to *top* with `orientation` is *h*.', 'Defaulted to *left* with `orientation` is *v*.', 'The *top left* options could be used to expand', + 'top center and top right are for horizontal alignment', 'legend area in both x and y sides.' ].join(' ') }, diff --git a/src/components/legend/draw.js b/src/components/legend/draw.js index 629b30cad2d..741bb089895 100644 --- a/src/components/legend/draw.js +++ b/src/components/legend/draw.js @@ -661,13 +661,18 @@ function computeTextDimensions(g, gd, legendObj, aTitle) { // approximation to height offset to center the font // to avoid getBoundingClientRect if(aTitle === MAIN_TITLE) { + var titleOffset = 0; if(legendObj.title.side === 'left') { // add extra space between legend title and itmes width += constants.itemGap * 2; + } else if(legendObj.title.side === 'top center') { + if(legendObj._width) titleOffset = 0.5 * (legendObj._width - 2 * bw - 2 * constants.titlePad - width); + } else if(legendObj.title.side === 'top right') { + if(legendObj._width) titleOffset = legendObj._width - 2 * bw - 2 * constants.titlePad - width; } svgTextUtils.positionText(textEl, - bw + constants.titlePad, + bw + constants.titlePad + titleOffset, bw + lineHeight ); } else { // legend item diff --git a/test/image/baselines/legend_horizontal_autowrap.png b/test/image/baselines/legend_horizontal_autowrap.png index c7f92fb58e1..f1b757ac783 100644 Binary files a/test/image/baselines/legend_horizontal_autowrap.png and b/test/image/baselines/legend_horizontal_autowrap.png differ diff --git a/test/image/baselines/legend_horizontal_one_row.png b/test/image/baselines/legend_horizontal_one_row.png index 10c802d75e7..7883a047c51 100644 Binary files a/test/image/baselines/legend_horizontal_one_row.png and b/test/image/baselines/legend_horizontal_one_row.png differ diff --git a/test/image/baselines/legend_itemwidth_dashline.png b/test/image/baselines/legend_itemwidth_dashline.png index 88f6abc3cd2..47b679ee59c 100644 Binary files a/test/image/baselines/legend_itemwidth_dashline.png and b/test/image/baselines/legend_itemwidth_dashline.png differ diff --git a/test/image/mocks/legend_horizontal_autowrap.json b/test/image/mocks/legend_horizontal_autowrap.json index 3b2db63cf65..7f7d91de050 100644 --- a/test/image/mocks/legend_horizontal_autowrap.json +++ b/test/image/mocks/legend_horizontal_autowrap.json @@ -547,7 +547,8 @@ "size": 11.9552 }, "y": -0.4, - "orientation": "h" + "orientation": "h", + "title": { "text": "Legend Title", "side": "top right" } }, "hovermode": "closest", "width": 680, diff --git a/test/image/mocks/legend_horizontal_one_row.json b/test/image/mocks/legend_horizontal_one_row.json index 4540d1d2922..50888583bdb 100644 --- a/test/image/mocks/legend_horizontal_one_row.json +++ b/test/image/mocks/legend_horizontal_one_row.json @@ -21,6 +21,6 @@ ], "layout": { "title": {"text": "Average Distribution per Month"}, - "legend": { "orientation": "h" } + "legend": { "orientation": "h", "title": { "text": "Legend Title", "side": "top center" }} } } diff --git a/test/image/mocks/legend_itemwidth_dashline.json b/test/image/mocks/legend_itemwidth_dashline.json index 000cd459e15..cd7148fc8e7 100644 --- a/test/image/mocks/legend_itemwidth_dashline.json +++ b/test/image/mocks/legend_itemwidth_dashline.json @@ -39,7 +39,8 @@ ], "layout": { "legend": { - "itemwidth": 60 + "itemwidth": 60, + "title": { "text": "Title", "side": "top center" } } } } diff --git a/test/plot-schema.json b/test/plot-schema.json index 6a1f962255c..e83e2591818 100644 --- a/test/plot-schema.json +++ b/test/plot-schema.json @@ -2923,13 +2923,15 @@ }, "role": "object", "side": { - "description": "Determines the location of legend's title with respect to the legend items. Defaulted to *top* with `orientation` is *h*. Defaulted to *left* with `orientation` is *v*. The *top left* options could be used to expand legend area in both x and y sides.", + "description": "Determines the location of legend's title with respect to the legend items. Defaulted to *top* with `orientation` is *h*. Defaulted to *left* with `orientation` is *v*. The *top left* options could be used to expand top center and top right are for horizontal alignment legend area in both x and y sides.", "editType": "legend", "valType": "enumerated", "values": [ "top", "left", - "top left" + "top left", + "top center", + "top right" ] }, "text": {