@@ -184,27 +184,42 @@ module.exports = function draw(gd) {
184
184
if(anchorUtils.isRightAnchor(opts)) {
185
185
lx -= opts.width;
186
186
}
187
- if(anchorUtils.isCenterAnchor(opts)) {
187
+ else if(anchorUtils.isCenterAnchor(opts)) {
188
188
lx -= opts.width / 2;
189
189
}
190
190
191
191
if(anchorUtils.isBottomAnchor(opts)) {
192
192
ly -= opts.height;
193
193
}
194
- if(anchorUtils.isMiddleAnchor(opts)) {
194
+ else if(anchorUtils.isMiddleAnchor(opts)) {
195
195
ly -= opts.height / 2;
196
196
}
197
197
198
+ lx = Math.round(lx);
199
+ ly = Math.round(ly);
200
+
201
+ // Make sure the legend top is below the top margin
202
+ if(ly < fullLayout.margin.t) ly = fullLayout.margin.t;
203
+
204
+ var scrollHeightMax = fullLayout.height - fullLayout.margin.b - ly;
205
+ var scrollHeight = Math.min(scrollHeightMax, opts.height);
206
+
207
+ if(scrollHeight <= 2 * opts.borderwidth) {
208
+ console.error('Legend.draw: insufficient space to draw legend');
209
+ legend.remove();
210
+ return;
211
+ }
212
+
198
213
// Deal with scrolling
199
- var plotHeight = fullLayout.height - fullLayout.margin.b,
200
- scrollheight = Math.min(plotHeight - ly, opts.height),
201
- scrollPosition = scrollBox.attr('data-scroll') ? scrollBox.attr('data-scroll') : 0;
214
+ var scrollPosition = scrollBox.attr('data-scroll') ?
215
+ scrollBox.attr('data-scroll') :
216
+ 0;
202
217
203
218
scrollBox.attr('transform', 'translate(0, ' + scrollPosition + ')');
204
219
205
220
bg.attr({
206
221
width: opts.width - 2 * opts.borderwidth,
207
- height: scrollheight - 2 * opts.borderwidth,
222
+ height: scrollHeight - 2 * opts.borderwidth,
208
223
x: opts.borderwidth,
209
224
y: opts.borderwidth
210
225
});
@@ -213,15 +228,15 @@ module.exports = function draw(gd) {
213
228
214
229
clipPath.select('rect').attr({
215
230
width: opts.width,
216
- height: scrollheight ,
231
+ height: scrollHeight ,
217
232
x: 0,
218
233
y: 0
219
234
});
220
235
221
236
legend.call(Drawing.setClipUrl, clipId);
222
237
223
238
// If scrollbar should be shown.
224
- if(opts.height - scrollheight > 0 && !gd._context.staticPlot) {
239
+ if(opts.height - scrollHeight > 0 && !gd._context.staticPlot) {
225
240
226
241
bg.attr({
227
242
width: opts.width - 2 * opts.borderwidth + constants.scrollBarWidth
@@ -243,21 +258,21 @@ module.exports = function draw(gd) {
243
258
scrollBox.attr('data-scroll',0);
244
259
}
245
260
246
- scrollHandler(0,scrollheight );
261
+ scrollHandler(0,scrollHeight );
247
262
248
263
legend.on('wheel',null);
249
264
250
265
legend.on('wheel', function() {
251
266
var e = d3.event;
252
267
e.preventDefault();
253
- scrollHandler(e.deltaY / 20, scrollheight );
268
+ scrollHandler(e.deltaY / 20, scrollHeight );
254
269
});
255
270
256
271
scrollBar.on('.drag',null);
257
272
scrollBox.on('.drag',null);
258
273
var drag = d3.behavior.drag()
259
274
.on('drag', function() {
260
- scrollHandler(d3.event.dy, scrollheight );
275
+ scrollHandler(d3.event.dy, scrollHeight );
261
276
});
262
277
263
278
scrollBar.call(drag);
@@ -266,12 +281,12 @@ module.exports = function draw(gd) {
266
281
}
267
282
268
283
269
- function scrollHandler(delta, scrollheight ) {
284
+ function scrollHandler(delta, scrollHeight ) {
270
285
271
- var scrollBarTrack = scrollheight - constants.scrollBarHeight - 2 * constants.scrollBarMargin,
286
+ var scrollBarTrack = scrollHeight - constants.scrollBarHeight - 2 * constants.scrollBarMargin,
272
287
translateY = scrollBox.attr('data-scroll'),
273
- scrollBoxY = Lib.constrain(translateY - delta, scrollheight -opts.height, 0),
274
- scrollBarY = -scrollBoxY / (opts.height - scrollheight ) * scrollBarTrack + constants.scrollBarMargin;
288
+ scrollBoxY = Lib.constrain(translateY - delta, scrollHeight -opts.height, 0),
289
+ scrollBarY = -scrollBoxY / (opts.height - scrollHeight ) * scrollBarTrack + constants.scrollBarMargin;
275
290
276
291
scrollBox.attr('data-scroll', scrollBoxY);
277
292
scrollBox.attr('transform', 'translate(0, ' + scrollBoxY + ')');
@@ -454,7 +469,10 @@ function repositionLegend(gd, traces) {
454
469
opts.height = Math.ceil(opts.height);
455
470
456
471
// lastly check if the margin auto-expand has changed
457
- Plots.autoMargin(gd, 'legend', {
472
+ // (using Plots.autoMarginVertical to ensure the requested margins are
473
+ // padded with the layout vertical margins to ensure the legend doesn't
474
+ // exceed the plot area)
475
+ Plots.autoMarginVertical(gd, 'legend', {
458
476
x: opts.x,
459
477
y: opts.y,
460
478
l: opts.width * ({right: 1, center: 0.5}[xanchor] || 0),
0 commit comments