Skip to content

Commit 8f06d8a

Browse files
committed
Adjust default setting and compute position based on xref and yref
1 parent 5c94e46 commit 8f06d8a

File tree

5 files changed

+67
-22
lines changed

5 files changed

+67
-22
lines changed

src/components/legend/attributes.js

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -163,14 +163,17 @@ module.exports = {
163163
max: 3,
164164
editType: 'legend',
165165
description: [
166-
'Sets the x position (in normalized coordinates) of the legend.',
167-
'Defaults to *1.02* for vertical legends and',
168-
'defaults to *0* for horizontal legends.'
166+
'Sets the x position with respect to `xref` (in normalized coordinates) of the legend.',
167+
'When `xref` is *paper*, defaults to *1.02* for vertical legends and',
168+
'defaults to *0* for horizontal legends.',
169+
'When `xref` is *container*, defaults to *1* for vertical legends and',
170+
'defaults to *0* for horizontal legends.',
171+
'Must be between *0* and *1* if `xref` is *container*.'
169172
].join(' ')
170173
},
171174
xref: {
172175
valType: 'enumerated',
173-
dflt: 'container',
176+
dflt: 'paper',
174177
values: ['container', 'paper'],
175178
editType: 'layoutstyle',
176179
description: [
@@ -199,15 +202,17 @@ module.exports = {
199202
max: 3,
200203
editType: 'legend',
201204
description: [
202-
'Sets the y position (in normalized coordinates) of the legend.',
203-
'Defaults to *1* for vertical legends,',
205+
'Sets the y position with respect to `yref` (in normalized coordinates) of the legend.',
206+
'When `yref` is *paper*, defaults to *1* for vertical legends,',
204207
'defaults to *-0.1* for horizontal legends on graphs w/o range sliders and',
205-
'defaults to *1.1* for horizontal legends on graph with one or multiple range sliders.'
208+
'defaults to *1.1* for horizontal legends on graph with one or multiple range sliders.',
209+
'When `yref` is *container*, defaults to *1*.',
210+
'Must be between *0* and *1* if `yref` is *container*.'
206211
].join(' ')
207212
},
208213
yref: {
209214
valType: 'enumerated',
210-
dflt: 'container',
215+
dflt: 'paper',
211216
values: ['container', 'paper'],
212217
editType: 'layoutstyle',
213218
description: [

src/components/legend/defaults.js

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,26 +101,48 @@ function groupDefaults(legendId, layoutIn, layoutOut, fullData) {
101101
coerce('borderwidth');
102102

103103
var orientation = coerce('orientation');
104+
105+
var yref = coerce('yref');
106+
var xref = coerce('xref');
107+
104108
var isHorizontal = orientation === 'h';
109+
var isPaperY = yref === 'paper';
110+
var isPaperX = xref === 'paper';
105111
var defaultX, defaultY, defaultYAnchor;
106112

113+
// TODO: Adjust default xanchor if needed for container ref?
114+
// TODO: Constrain x or y if container ref to be within 0-1
107115
if(isHorizontal) {
108116
defaultX = 0;
109117

110118
if(Registry.getComponentMethod('rangeslider', 'isVisible')(layoutIn.xaxis)) {
111-
defaultY = 1.1;
112-
defaultYAnchor = 'bottom';
119+
if(isPaperY) {
120+
defaultY = 1.1;
121+
defaultYAnchor = 'bottom';
122+
} else {
123+
defaultY = 1;
124+
defaultYAnchor = 'top';
125+
}
113126
} else {
114127
// maybe use y=1.1 / yanchor=bottom as above
115128
// to avoid https://github.com/plotly/plotly.js/issues/1199
116129
// in v3
117-
defaultY = -0.1;
118-
defaultYAnchor = 'top';
130+
if(isPaperY) {
131+
defaultY = -0.1;
132+
defaultYAnchor = 'top';
133+
} else {
134+
defaultY = 0;
135+
defaultYAnchor = 'bottom';
136+
}
119137
}
120138
} else {
121-
defaultX = 1.02;
122139
defaultY = 1;
123140
defaultYAnchor = 'auto';
141+
if(isPaperX) {
142+
defaultX = 1.02;
143+
} else {
144+
defaultX = 1;
145+
}
124146
}
125147

126148
coerce('traceorder', defaultOrder);

src/components/legend/draw.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,21 @@ function drawOne(gd, opts) {
163163
// draw the remaining pieces below
164164
if(expMargin) return;
165165

166-
var lx = gs.l + gs.w * legendObj.x - FROM_TL[getXanchor(legendObj)] * legendObj._width;
167-
var ly = gs.t + gs.h * (1 - legendObj.y) - FROM_TL[getYanchor(legendObj)] * legendObj._effHeight;
166+
if(legendObj.xref === 'paper') {
167+
var lx = gs.l + gs.w * legendObj.x - FROM_TL[getXanchor(legendObj)] * legendObj._width;
168+
} else {
169+
legendObj.x = Lib.constrain(legendObj.x, 0, 1); // TODO: Move this to defaults setting?
170+
var lx = fullLayout.width * legendObj.x - FROM_TL[getXanchor(legendObj)] * legendObj._width;
171+
}
172+
173+
if(legendObj.yref === 'paper') {
174+
var ly = gs.t + gs.h * (1 - legendObj.y) - FROM_TL[getYanchor(legendObj)] * legendObj._effHeight;
175+
} else {
176+
legendObj.y = Lib.constrain(legendObj.y, 0, 1); // TODO: Move this to defaults setting?
177+
var ly = fullLayout.height * (1 - legendObj.y) - FROM_TL[getYanchor(legendObj)] * legendObj._effHeight;
178+
}
168179

180+
// TODO: Does this also apply if y/xref=container?
169181
if(fullLayout.margin.autoexpand) {
170182
var lx0 = lx;
171183
var ly0 = ly;

test/image/mocks/legend_outside.json

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,15 @@
5454
"layout":{
5555
"showlegend":true,
5656
"legend":{
57-
"x":1,
58-
"y":1,
59-
"xanchor":"left"
57+
"x": 0,
58+
"y": 0,
59+
"xref": "container",
60+
"yref": "container",
61+
"orientation": "h"
62+
},
63+
"margin": {
64+
"t": 75,
65+
"r": 115
6066
}
6167
}
6268
}

test/plot-schema.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2964,7 +2964,7 @@
29642964
"valType": "boolean"
29652965
},
29662966
"x": {
2967-
"description": "Sets the x position (in normalized coordinates) of the legend. Defaults to *1.02* for vertical legends and defaults to *0* for horizontal legends.",
2967+
"description": "Sets the x position with respect to `xref` (in normalized coordinates) of the legend. When `xref` is *paper*, defaults to *1.02* for vertical legends and defaults to *0* for horizontal legends. When `xref` is *container*, defaults to *1* for vertical legends and defaults to *0* for horizontal legends. Must be between *0* and *1* if `xref` is *container*.",
29682968
"editType": "legend",
29692969
"max": 3,
29702970
"min": -2,
@@ -2984,7 +2984,7 @@
29842984
},
29852985
"xref": {
29862986
"description": "Sets the container `x` refers to. *container* spans the entire `width` of the plot. *paper* refers to the width of the plotting area only.",
2987-
"dflt": "container",
2987+
"dflt": "paper",
29882988
"editType": "layoutstyle",
29892989
"valType": "enumerated",
29902990
"values": [
@@ -2993,7 +2993,7 @@
29932993
]
29942994
},
29952995
"y": {
2996-
"description": "Sets the y position (in normalized coordinates) of the legend. Defaults to *1* for vertical legends, defaults to *-0.1* for horizontal legends on graphs w/o range sliders and defaults to *1.1* for horizontal legends on graph with one or multiple range sliders.",
2996+
"description": "Sets the y position with respect to `yref` (in normalized coordinates) of the legend. When `yref` is *paper*, defaults to *1* for vertical legends, defaults to *-0.1* for horizontal legends on graphs w/o range sliders and defaults to *1.1* for horizontal legends on graph with one or multiple range sliders. When `yref` is *container*, defaults to *1*. Must be between *0* and *1* if `yref` is *container*.",
29972997
"editType": "legend",
29982998
"max": 3,
29992999
"min": -2,
@@ -3012,7 +3012,7 @@
30123012
},
30133013
"yref": {
30143014
"description": "Sets the container `y` refers to. *container* spans the entire `height` of the plot. *paper* refers to the height of the plotting area only.",
3015-
"dflt": "container",
3015+
"dflt": "paper",
30163016
"editType": "layoutstyle",
30173017
"valType": "enumerated",
30183018
"values": [

0 commit comments

Comments
 (0)