Skip to content

Commit 2139f28

Browse files
committed
fix #4132 - fix grouped horizontal legend dimension computations
- which gives better margin pushes, fixes legendgroup_horizontal_wrapping mock
1 parent 38e94ea commit 2139f28

File tree

4 files changed

+28
-40
lines changed

4 files changed

+28
-40
lines changed

src/components/legend/draw.js

Lines changed: 25 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -542,55 +542,43 @@ function computeLegendDimensions(gd, groups, traces) {
542542
combinedItemWidth += w;
543543
});
544544

545+
var maxRowWidth = 0;
546+
545547
if(isGrouped) {
546-
var groupData = groups.data();
547-
var i;
548+
var maxGroupHeightInRow = 0;
549+
var groupOffsetX = 0;
550+
var groupOffsetY = 0;
551+
groups.each(function() {
552+
var maxWidthInGroup = 0;
553+
var offsetY = 0;
554+
d3.select(this).selectAll('g.traces').each(function(d) {
555+
var h = d[0].height;
556+
Drawing.setTranslate(this, 0, itemGap + bw + h / 2 + offsetY);
557+
offsetY += h;
558+
maxWidthInGroup = Math.max(maxWidthInGroup, textGap + d[0].width);
559+
});
560+
maxGroupHeightInRow = Math.max(maxGroupHeightInRow, offsetY);
548561

549-
var maxGroupHeight = 0;
550-
for(i = 0; i < groupData.length; i++) {
551-
var groupHeight = groupData[i].reduce(function(a, b) { return a + b[0].height; }, 0);
552-
maxGroupHeight = Math.max(maxGroupHeight, groupHeight);
553-
}
562+
var next = maxWidthInGroup + itemGap;
554563

555-
var groupXOffsets = [opts._width];
556-
var groupYOffsets = [];
557-
var rowNum = 0;
558-
for(i = 0; i < groupData.length; i++) {
559-
if((opts._width + itemGap + maxItemWidth + bw) > opts._maxWidth) {
560-
groupXOffsets[groupXOffsets.length - 1] = groupXOffsets[0];
561-
opts._width = maxItemWidth + itemGap;
562-
rowNum++;
563-
} else {
564-
opts._width += maxItemWidth + itemGap;
564+
if((next + bw + groupOffsetX) > opts._maxWidth) {
565+
maxRowWidth = Math.max(maxRowWidth, groupOffsetX);
566+
groupOffsetX = 0;
567+
groupOffsetY += maxGroupHeightInRow + opts.tracegroupgap;
568+
maxGroupHeightInRow = offsetY;
565569
}
566570

567-
groupXOffsets.push(opts._width);
568-
groupYOffsets.push(rowNum * maxGroupHeight + (rowNum > 0 ? opts.tracegroupgap : 0));
569-
}
570-
571-
groups.each(function(d, i) {
572-
Drawing.setTranslate(this, groupXOffsets[i], groupYOffsets[i]);
573-
});
571+
Drawing.setTranslate(this, groupOffsetX, groupOffsetY);
574572

575-
groups.each(function() {
576-
var group = d3.select(this);
577-
var groupTraces = group.selectAll('g.traces');
578-
var groupHeight = 0;
579-
580-
groupTraces.each(function(d) {
581-
var h = d[0].height;
582-
Drawing.setTranslate(this, 0, itemGap + bw + groupHeight + h / 2);
583-
groupHeight += h;
584-
});
573+
groupOffsetX += next;
585574
});
586575

587-
opts._height = groupYOffsets[groupYOffsets.length - 1] + maxGroupHeight + endPad;
588-
opts._width = Math.max.apply(null, groupXOffsets) + maxItemWidth + textGap + bw2;
589576
toggleRectWidth = maxItemWidth;
577+
opts._width = Math.max(maxRowWidth, groupOffsetX) + bw;
578+
opts._height = groupOffsetY + maxGroupHeightInRow + endPad;
590579
} else {
591580
var oneRowLegend = (combinedItemWidth + bw2 + (traces.size() - 1) * itemGap) < opts._maxWidth;
592581

593-
var maxRowWidth = 0;
594582
var maxItemHeightInRow = 0;
595583
var offsetX = 0;
596584
var offsetY = 0;
Loading
Loading

test/jasmine/tests/legend_test.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -719,15 +719,15 @@ describe('legend relayout update', function() {
719719
var mockCopy = Lib.extendDeep({}, mock);
720720
Plotly.newPlot(gd, mockCopy)
721721
.then(function() {
722-
expect(gd._fullLayout._size.b).toBe(130);
722+
expect(gd._fullLayout._size.b).toBe(113);
723723
return Plotly.relayout(gd, 'legend.tracegroupgap', 70);
724724
})
725725
.then(function() {
726-
expect(gd._fullLayout._size.b).toBe(185);
726+
expect(gd._fullLayout._size.b).toBe(167);
727727
return Plotly.relayout(gd, 'legend.tracegroupgap', 10);
728728
})
729729
.then(function() {
730-
expect(gd._fullLayout._size.b).toBe(130);
730+
expect(gd._fullLayout._size.b).toBe(113);
731731
})
732732
.catch(failTest)
733733
.then(done);

0 commit comments

Comments
 (0)