Skip to content

Commit a6cf612

Browse files
committed
[poc] legend split pushMargin from draw
1 parent 007dbd5 commit a6cf612

File tree

3 files changed

+67
-37
lines changed

3 files changed

+67
-37
lines changed

src/components/legend/draw.js

Lines changed: 58 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ var getLegendData = require('./get_legend_data');
3030
var style = require('./style');
3131
var helpers = require('./helpers');
3232

33-
module.exports = function draw(gd) {
33+
function draw(gd) {
3434
var fullLayout = gd._fullLayout;
3535
var clipId = 'legend' + fullLayout._uid;
3636

@@ -39,13 +39,13 @@ module.exports = function draw(gd) {
3939
if(!gd._legendMouseDownTime) gd._legendMouseDownTime = 0;
4040

4141
var opts = fullLayout.legend;
42-
var legendData = fullLayout.showlegend && getLegendData(gd.calcdata, opts);
42+
var legendData = getLegendData(gd);
4343
var hiddenSlices = fullLayout.hiddenlabels || [];
4444

45-
if(!fullLayout.showlegend || !legendData.length) {
45+
if(!legendData.length) {
4646
fullLayout._infolayer.selectAll('.legend').remove();
4747
fullLayout._topdefs.select('#' + clipId).remove();
48-
return Plots.autoMargin(gd, 'legend');
48+
return;
4949
}
5050

5151
var legend = Lib.ensureSingle(fullLayout._infolayer, 'g', 'legend', function(s) {
@@ -94,11 +94,7 @@ module.exports = function draw(gd) {
9494
Plots.previousPromises,
9595
function() { return computeLegendDimensions(gd, groups, traces); },
9696
function() {
97-
// IF expandMargin return a Promise (which is truthy),
98-
// we're under a doAutoMargin redraw, so we don't have to
99-
// draw the remaining pieces below
100-
if(expandMargin(gd)) return;
101-
97+
var edits = gd._context.edits;
10298
var gs = fullLayout._size;
10399
var bw = opts.borderwidth;
104100

@@ -124,6 +120,15 @@ module.exports = function draw(gd) {
124120
// legend, background and border, scroll box and scroll bar
125121
Drawing.setTranslate(legend, lx, ly);
126122

123+
var isEditable = edits.legendText || edits.legendPosition;
124+
traces.each(function(d) {
125+
var h = d[0].height;
126+
var w = isEditable ? constants.textGap :
127+
(opts.toggleRectWidth || (constants.textGap + d[0].width));
128+
if(!helpers.isVertical(opts)) w += constants.itemGap / 2;
129+
Drawing.setRect(d3.select(this).select('.legendtoggle'), 0, -h / 2, w, h);
130+
});
131+
127132
// to be safe, remove previous listeners
128133
scrollBar.on('.drag', null);
129134
legend.on('wheel', null);
@@ -232,7 +237,7 @@ module.exports = function draw(gd) {
232237
clipPath.select('rect').attr('y', bw + scrollBoxY);
233238
}
234239

235-
if(gd._context.edits.legendPosition) {
240+
if(edits.legendPosition) {
236241
var xf, yf, x0, y0;
237242

238243
legend.classed('cursor-move', true);
@@ -274,7 +279,7 @@ module.exports = function draw(gd) {
274279
});
275280
}
276281
}], gd);
277-
};
282+
}
278283

279284
function clickOrDoubleClick(gd, legend, legendItem, numClicks, evt) {
280285
var trace = legendItem.data()[0][0].trace;
@@ -472,6 +477,8 @@ function computeTextDimensions(g, gd) {
472477
*
473478
* - _width: legend width
474479
* - _maxWidth (for orientation:h only): maximum width before starting new row
480+
*
481+
* - toggleRectWidth: ...
475482
*/
476483
function computeLegendDimensions(gd, groups, traces) {
477484
var fullLayout = gd._fullLayout;
@@ -497,9 +504,9 @@ function computeLegendDimensions(gd, groups, traces) {
497504
30
498505
);
499506

500-
var toggleRectWidth = 0;
501507
opts._width = 0;
502508
opts._height = 0;
509+
opts._toggleRectWidth = 0;
503510

504511
if(isVertical) {
505512
traces.each(function(d) {
@@ -509,7 +516,7 @@ function computeLegendDimensions(gd, groups, traces) {
509516
opts._width = Math.max(opts._width, d[0].width);
510517
});
511518

512-
toggleRectWidth = textGap + opts._width;
519+
opts._toggleRectWidth = textGap + opts._width;
513520
opts._width += itemGap + textGap + bw2;
514521
opts._height += endPad;
515522

@@ -542,7 +549,7 @@ function computeLegendDimensions(gd, groups, traces) {
542549
combinedItemWidth += w;
543550
});
544551

545-
toggleRectWidth = null;
552+
opts._toggleRectWidth = null;
546553
var maxRowWidth = 0;
547554

548555
if(isGrouped) {
@@ -618,30 +625,46 @@ function computeLegendDimensions(gd, groups, traces) {
618625
opts._height = Math.ceil(opts._height);
619626

620627
opts._effHeight = Math.min(opts._height, opts._maxHeight);
621-
622-
var edits = gd._context.edits;
623-
var isEditable = edits.legendText || edits.legendPosition;
624-
traces.each(function(d) {
625-
var traceToggle = d3.select(this).select('.legendtoggle');
626-
var h = d[0].height;
627-
var w = isEditable ? textGap : (toggleRectWidth || (textGap + d[0].width));
628-
if(!isVertical) w += itemGap / 2;
629-
Drawing.setRect(traceToggle, 0, -h / 2, w, h);
630-
});
631628
}
632629

633-
function expandMargin(gd) {
630+
function pushMargin(gd) {
634631
var fullLayout = gd._fullLayout;
635632
var opts = fullLayout.legend;
636-
var xanchor = Lib.getXanchor(opts);
637-
var yanchor = Lib.getYanchor(opts);
638633

639-
return Plots.autoMargin(gd, 'legend', {
640-
x: opts.x,
641-
y: opts.y,
642-
l: opts._width * (FROM_TL[xanchor]),
643-
r: opts._width * (FROM_BR[xanchor]),
644-
b: opts._effHeight * (FROM_BR[yanchor]),
645-
t: opts._effHeight * (FROM_TL[yanchor])
646-
});
634+
var legendData = getLegendData(gd);
635+
if(!legendData.length) return;
636+
637+
var fakeLegend = Lib.ensureSingle(Drawing.tester, 'g', 'legend');
638+
639+
var groups = fakeLegend.selectAll('g.groups').data(legendData);
640+
groups.enter().append('g').attr('class', 'groups');
641+
642+
var traces = groups.selectAll('g.traces').data(Lib.identity);
643+
traces.enter().append('g').attr('class', 'traces');
644+
traces.each(function() { d3.select(this).call(drawTexts, gd); });
645+
646+
return Lib.syncOrAsync([
647+
Plots.previousPromises,
648+
function() {
649+
computeLegendDimensions(gd, groups, traces);
650+
fakeLegend.remove();
651+
652+
var xanchor = Lib.getXanchor(opts);
653+
var yanchor = Lib.getYanchor(opts);
654+
655+
Plots.autoMargin(gd, 'legend', {
656+
x: opts.x,
657+
y: opts.y,
658+
l: opts._width * (FROM_TL[xanchor]),
659+
r: opts._width * (FROM_BR[xanchor]),
660+
b: opts._effHeight * (FROM_BR[yanchor]),
661+
t: opts._effHeight * (FROM_TL[yanchor])
662+
});
663+
}
664+
], gd);
647665
}
666+
667+
module.exports = {
668+
pushMargin: pushMargin,
669+
draw: draw
670+
};

src/components/legend/get_legend_data.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,13 @@
1111
var Registry = require('../../registry');
1212
var helpers = require('./helpers');
1313

14-
module.exports = function getLegendData(calcdata, opts) {
14+
module.exports = function getLegendData(gd) {
15+
var fullLayout = gd._fullLayout;
16+
var opts = fullLayout.legend;
17+
var calcdata = gd.calcdata;
18+
19+
if(!fullLayout.showlegend) return [];
20+
1521
var lgroupToTraces = {};
1622
var lgroups = [];
1723
var hasOneNonBlankGroup = false;

src/components/legend/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ module.exports = {
1717
layoutAttributes: require('./attributes'),
1818
supplyLayoutDefaults: require('./defaults'),
1919

20-
draw: require('./draw'),
20+
pushMargin: require('./draw').pushMargin,
21+
draw: require('./draw').draw,
2122
style: require('./style')
2223
};

0 commit comments

Comments
 (0)