Skip to content
This repository was archived by the owner on Apr 21, 2023. It is now read-only.

Horizontal legend spacing #1

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/components/legend/attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ module.exports = {
role: 'info',
description: 'Sets the orientation of the legend.'
},
horizontalspacing: {
valType: 'enumerated',
values: ['column', 'wrapped'],
dflt: ['column'],
role: 'info',
description: 'Sets whether a horizontal legend is broken into columns or wrapped horizontally.'
},
traceorder: {
valType: 'flaglist',
flags: ['reversed', 'grouped'],
Expand Down
2 changes: 2 additions & 0 deletions src/components/legend/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {

var visibleTraces = 0,
defaultOrder = 'normal',
defaultHorizontalSpacing = 'column',
defaultX,
defaultY,
defaultXAnchor,
Expand Down Expand Up @@ -87,5 +88,6 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
coerce('xanchor', defaultXAnchor);
coerce('y', defaultY);
coerce('yanchor', defaultYAnchor);
coerce('horizontalspacing', defaultHorizontalSpacing);
Lib.noneOrAll(containerIn, containerOut, ['x', 'y']);
};
7 changes: 4 additions & 3 deletions src/components/legend/draw.js
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,8 @@ function computeLegendDimensions(gd, groups, traces) {
var fullLayout = gd._fullLayout,
opts = fullLayout.legend,
borderwidth = opts.borderwidth,
isGrouped = helpers.isGrouped(opts);
isGrouped = helpers.isGrouped(opts),
isHorizontalColumn = helpers.isHorizontalColumn(opts);

if(helpers.isVertical(opts)) {
if(isGrouped) {
Expand Down Expand Up @@ -590,14 +591,14 @@ function computeLegendDimensions(gd, groups, traces) {
maxTraceWidth = 0,
offsetX = 0;

// calculate largest width for traces and use for width of all legend items
// calculate largest width for traces and use for width of all legend items (if horizontalspacing mode is 'column')
traces.each(function(d) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maxTraceWidth isn't used unless isHorizontalColumn is true, so don't compute it if not.

maxTraceWidth = Math.max(40 + d[0].width, maxTraceWidth);
});

traces.each(function(d) {
var legendItem = d[0],
traceWidth = maxTraceWidth,
traceWidth = isHorizontalColumn ? maxTraceWidth : 40 + d[0].width,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is the 40 coming from? Leave a comment.

traceGap = opts.tracegroupgap || 5;

if((borderwidth + offsetX + traceGap + traceWidth) > (fullLayout.width - (fullLayout.margin.r + fullLayout.margin.l))) {
Expand Down
4 changes: 4 additions & 0 deletions src/components/legend/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,7 @@ exports.isVertical = function isVertical(legendLayout) {
exports.isReversed = function isReversed(legendLayout) {
return (legendLayout.traceorder || '').indexOf('reversed') !== -1;
};

exports.isHorizontalColumn = function isHorizontalColumn(legendLayout) {
return legendLayout.horizontalspacing === 'column';
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing newline

60 changes: 60 additions & 0 deletions test/jasmine/tests/legend_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,15 @@ describe('legend helpers:', function() {
expect(isReversed({ traceorder: 'reversed' })).toBe(true);
});
});

describe('isHorizontalColumn', function() {
var isHorizontalColumn = helpers.isHorizontalColumn;

it('should return true when option horizontalspacing is "column"', function() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Break this into two tests: should return true when option horizontalspacing is "column", and should return false when option horizontalspacing is "wrapped"

expect(isHorizontalColumn({ horizontalspacing: 'column'})).toBe(true);
expect(isHorizontalColumn({ horizontalspacing: 'wrapped'})).toBe(false);
});
});
});

describe('legend anchor utils:', function() {
Expand Down Expand Up @@ -628,3 +637,54 @@ describe('legend restyle update', function() {
});
});
});

describe('legend horizontal spacing', function() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good tests!

'use strict';

beforeAll(function() {
jasmine.addMatchers(customMatchers);
});

afterEach(destroyGraphDiv);

it('should not space the items equally if horizontalspacing is wrapped', function(done) {
var mock = require('@mocks/0.json'),
mockCopy = Lib.extendDeep({}, mock),
traceTransforms = [
'translate(1, 15.5)',
'translate(120, 15.5)',
'translate(231.68333435058594, 15.5)',
],
gd = createGraphDiv();
mockCopy.layout.legend.horizontalspacing = 'wrapped';
mockCopy.layout.legend.orientation = 'h';
Plotly.plot(gd, mockCopy.data, mockCopy.layout);
var nodes = d3.select(gd).selectAll('g.traces');
nodes.each(function(n, i) {
var node = d3.select(this);
var transform = node.attr('transform');
expect(transform).toEqual(traceTransforms[i]);
});
done();
});

it('should space the items equally if horizontalspacing is column', function(done) {
var mock = require('@mocks/0.json'),
mockCopy = Lib.extendDeep({}, mock),
traceTransforms = [
'translate(1, 15.5)',
'translate(120, 15.5)',
'translate(239, 15.5)',
],
gd = createGraphDiv();
mockCopy.layout.legend.orientation = 'h';
Plotly.plot(gd, mockCopy.data, mockCopy.layout);
var nodes = d3.select(gd).selectAll('g.traces');
nodes.each(function(n, i) {
var node = d3.select(this);
var transform = node.attr('transform');
expect(transform).toEqual(traceTransforms[i]);
});
done();
});
});