Skip to content

Commit f92f786

Browse files
authored
Merge pull request #6193 from nickmelnikov82/additional-options-for-automargin-property
Add additional options for automargin property
2 parents 31e7086 + ae1b087 commit f92f786

File tree

6 files changed

+190
-7
lines changed

6 files changed

+190
-7
lines changed

draftlogs/6193_add.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Add flaglist options including "left", "right", "top", "bottom", "width" and "height" to control the direction of `automargin` on cartesian axes [[#6193](https://github.com/plotly/plotly.js/pull/6193)]

src/lib/coerce.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -215,14 +215,14 @@ exports.valObjectMeta = {
215215
requiredOpts: ['flags'],
216216
otherOpts: ['dflt', 'extras', 'arrayOk'],
217217
coerceFunction: function(v, propOut, dflt, opts) {
218-
if(typeof v !== 'string') {
219-
propOut.set(dflt);
220-
return;
221-
}
222218
if((opts.extras || []).indexOf(v) !== -1) {
223219
propOut.set(v);
224220
return;
225221
}
222+
if(typeof v !== 'string') {
223+
propOut.set(dflt);
224+
return;
225+
}
226226
var vParts = v.split('+');
227227
var i = 0;
228228
while(i < vParts.length) {

src/plots/cartesian/axes.js

+30
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ var GRID_PATH = { K: 'gridline', L: 'path' };
3939
var MINORGRID_PATH = { K: 'minor-gridline', L: 'path' };
4040
var TICK_PATH = { K: 'tick', L: 'path' };
4141
var TICK_TEXT = { K: 'tick', L: 'text' };
42+
var MARGIN_MAPPING = {
43+
width: ['x', 'r', 'l', 'xl', 'xr'],
44+
height: ['y', 't', 'b', 'yt', 'yb'],
45+
right: ['r', 'xr'],
46+
left: ['l', 'xl'],
47+
top: ['t', 'yt'],
48+
bottom: ['b', 'yb']
49+
};
4250

4351
var alignmentConstants = require('../../constants/alignment');
4452
var MID_SHIFT = alignmentConstants.MID_SHIFT;
@@ -2622,6 +2630,11 @@ axes.drawOne = function(gd, ax, opts) {
26222630
rangeSliderPush = Registry.getComponentMethod('rangeslider', 'autoMarginOpts')(gd, ax);
26232631
}
26242632

2633+
if(typeof ax.automargin === 'string') {
2634+
filterPush(push, ax.automargin);
2635+
filterPush(mirrorPush, ax.automargin);
2636+
}
2637+
26252638
Plots.autoMargin(gd, axAutoMarginID(ax), push);
26262639
Plots.autoMargin(gd, axMirrorAutoMarginID(ax), mirrorPush);
26272640
Plots.autoMargin(gd, rangeSliderAutoMarginID(ax), rangeSliderPush);
@@ -2636,6 +2649,23 @@ axes.drawOne = function(gd, ax, opts) {
26362649
return Lib.syncOrAsync(seq);
26372650
};
26382651

2652+
function filterPush(push, automargin) {
2653+
if(!push) return;
2654+
2655+
var keepMargin = Object.keys(MARGIN_MAPPING).reduce(function(data, nextKey) {
2656+
if(automargin.indexOf(nextKey) !== -1) {
2657+
MARGIN_MAPPING[nextKey].forEach(function(key) { data[key] = 1;});
2658+
}
2659+
return data;
2660+
}, {});
2661+
Object.keys(push).forEach(function(key) {
2662+
if(!keepMargin[key]) {
2663+
if(key.length === 1) push[key] = 0;
2664+
else delete push[key];
2665+
}
2666+
});
2667+
}
2668+
26392669
function getBoundaryVals(ax, vals) {
26402670
var out = [];
26412671
var i;

src/plots/cartesian/layout_attributes.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,9 @@ module.exports = {
625625
description: 'Determines whether or not the tick labels are drawn.'
626626
},
627627
automargin: {
628-
valType: 'boolean',
628+
valType: 'flaglist',
629+
flags: ['height', 'width', 'left', 'right', 'top', 'bottom'],
630+
extras: [true, false],
629631
dflt: false,
630632
editType: 'ticks',
631633
description: [

test/jasmine/tests/axes_test.js

+126
Original file line numberDiff line numberDiff line change
@@ -4225,6 +4225,132 @@ describe('Test axes', function() {
42254225
.then(done, done.fail);
42264226
});
42274227

4228+
it('should handle partial automargin', function(done) {
4229+
var initialSize;
4230+
4231+
function assertSize(msg, actual, exp) {
4232+
for(var k in exp) {
4233+
var parts = exp[k].split('|');
4234+
var op = parts[0];
4235+
4236+
var method = {
4237+
'=': 'toBe',
4238+
grew: 'toBeGreaterThan',
4239+
}[op];
4240+
4241+
var val = initialSize[k];
4242+
var msgk = msg + ' ' + k + (parts[1] ? ' |' + parts[1] : '');
4243+
var args = op === '~=' ? [val, 1.1, msgk] : [val, msgk, ''];
4244+
4245+
expect(actual[k])[method](args[0], args[1], args[2]);
4246+
}
4247+
}
4248+
4249+
function check(msg, relayoutObj, exp) {
4250+
return function() {
4251+
return Plotly.relayout(gd, relayoutObj).then(function() {
4252+
var gs = Lib.extendDeep({}, gd._fullLayout._size);
4253+
assertSize(msg, gs, exp);
4254+
});
4255+
};
4256+
}
4257+
4258+
Plotly.newPlot(gd, [{
4259+
x: [
4260+
'short label 1', 'loooooong label 1',
4261+
'short label 2', 'loooooong label 2',
4262+
'short label 3', 'loooooong label 3',
4263+
'short label 4', 'loooooongloooooongloooooong label 4',
4264+
'short label 5', 'loooooong label 5'
4265+
],
4266+
y: [
4267+
'short label 1', 'loooooong label 1',
4268+
'short label 2', 'loooooong label 2',
4269+
'short label 3', 'loooooong label 3',
4270+
'short label 4', 'loooooong label 4',
4271+
'short label 5', 'loooooong label 5'
4272+
]
4273+
}], {
4274+
margin: {l: 0, r: 0, b: 0, t: 0},
4275+
width: 600, height: 600
4276+
})
4277+
.then(function() {
4278+
expect(gd._fullLayout.xaxis._tickAngles.xtick).toBe(30);
4279+
4280+
var gs = gd._fullLayout._size;
4281+
initialSize = Lib.extendDeep({}, gs);
4282+
})
4283+
.then(check('automargin y', {'yaxis.automargin': true, 'yaxis.tickangle': 30, 'yaxis.ticklen': 30}, {
4284+
t: 'grew', l: 'grew',
4285+
b: '=', r: '='
4286+
}))
4287+
.then(check('automargin not left', {'yaxis.automargin': 'right+height'}, {
4288+
t: 'grew', l: '=',
4289+
b: '=', r: '='
4290+
}))
4291+
.then(check('automargin keep left height', {'yaxis.automargin': 'left+height'}, {
4292+
t: 'grew', l: 'grew',
4293+
b: '=', r: '='
4294+
}))
4295+
.then(check('automargin keep bottom right', {'yaxis.automargin': 'bottom+right'}, {
4296+
t: '=', l: '=',
4297+
b: '=', r: '='
4298+
}))
4299+
.then(check('automargin keep height', {'yaxis.automargin': 'height'}, {
4300+
t: 'grew', l: '=',
4301+
b: '=', r: '='
4302+
}))
4303+
.then(check('automargin keep top', {'yaxis.automargin': 'top'}, {
4304+
t: 'grew', l: '=',
4305+
b: '=', r: '='
4306+
}))
4307+
.then(check('automargin not top', {'yaxis.automargin': 'bottom+width'}, {
4308+
t: '=', l: 'grew',
4309+
b: '=', r: '='
4310+
}))
4311+
.then(check('automargin keep left', {'yaxis.automargin': 'left'}, {
4312+
t: '=', l: 'grew',
4313+
b: '=', r: '='
4314+
}))
4315+
.then(check('automargin keep width', {'yaxis.automargin': 'width'}, {
4316+
t: '=', l: 'grew',
4317+
b: '=', r: '='
4318+
}))
4319+
.then(check('automargin x', {'xaxis.automargin': true, 'yaxis.automargin': false}, {
4320+
t: '=', l: '=',
4321+
b: 'grew', r: 'grew'
4322+
}))
4323+
.then(check('automargin not bottom', {'xaxis.automargin': 'top+width'}, {
4324+
t: '=', l: '=',
4325+
b: '=', r: 'grew'
4326+
}))
4327+
.then(check('automargin keep right', {'xaxis.automargin': 'right'}, {
4328+
t: '=', l: '=',
4329+
b: '=', r: 'grew'
4330+
}))
4331+
.then(check('automargin keep bottom', {'xaxis.automargin': 'bottom'}, {
4332+
t: '=', l: '=',
4333+
b: 'grew', r: '='
4334+
}))
4335+
.then(check('automargin keep top right', {'xaxis.automargin': 'top+right'}, {
4336+
t: '=', l: '=',
4337+
b: '=', r: 'grew'
4338+
}))
4339+
.then(check('automargin keep top left', {'xaxis.automargin': 'top+left'}, {
4340+
t: '=', l: '=',
4341+
b: '=', r: '='
4342+
}))
4343+
.then(check('automargin keep bottom left', {'xaxis.automargin': 'bottom+left'}, {
4344+
t: '=', l: '=',
4345+
b: 'grew', r: '='
4346+
}))
4347+
.then(check('turn off automargin', {'xaxis.automargin': false, 'yaxis.automargin': false}, {
4348+
t: '=', l: '=',
4349+
b: '=', r: '='
4350+
}))
4351+
.then(done, done.fail);
4352+
});
4353+
42284354
it('should handle cases with free+mirror axes', function(done) {
42294355
Plotly.newPlot(gd, [{
42304356
y: [1, 2, 1]

test/plot-schema.json

+26-2
Original file line numberDiff line numberDiff line change
@@ -9717,7 +9717,19 @@
97179717
"description": "Determines whether long tick labels automatically grow the figure margins.",
97189718
"dflt": false,
97199719
"editType": "ticks",
9720-
"valType": "boolean"
9720+
"extras": [
9721+
true,
9722+
false
9723+
],
9724+
"flags": [
9725+
"height",
9726+
"width",
9727+
"left",
9728+
"right",
9729+
"top",
9730+
"bottom"
9731+
],
9732+
"valType": "flaglist"
97219733
},
97229734
"autorange": {
97239735
"description": "Determines whether or not the range of this axis is computed in relation to the input data. See `rangemode` for more info. If `range` is provided, then `autorange` is set to *false*.",
@@ -10956,7 +10968,19 @@
1095610968
"description": "Determines whether long tick labels automatically grow the figure margins.",
1095710969
"dflt": false,
1095810970
"editType": "ticks",
10959-
"valType": "boolean"
10971+
"extras": [
10972+
true,
10973+
false
10974+
],
10975+
"flags": [
10976+
"height",
10977+
"width",
10978+
"left",
10979+
"right",
10980+
"top",
10981+
"bottom"
10982+
],
10983+
"valType": "flaglist"
1096010984
},
1096110985
"autorange": {
1096210986
"description": "Determines whether or not the range of this axis is computed in relation to the input data. See `rangemode` for more info. If `range` is provided, then `autorange` is set to *false*.",

0 commit comments

Comments
 (0)