Skip to content

Commit 1df34bd

Browse files
add editType to clear automargins from pushmargins
1 parent 20bdefa commit 1df34bd

File tree

6 files changed

+102
-63
lines changed

6 files changed

+102
-63
lines changed

src/plot_api/edit_types.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ var layoutOpts = {
3535
valType: 'flaglist',
3636
extras: ['none'],
3737
flags: [
38-
'calc', 'calcIfAutorange', 'plot', 'legend', 'ticks',
38+
'calc', 'calcIfAutorange', 'plot', 'legend', 'ticks', 'margins',
3939
'layoutstyle', 'modebar', 'camera', 'arraydraw'
4040
],
4141
description: [
@@ -47,6 +47,7 @@ var layoutOpts = {
4747
'*plot* calls `Plotly.plot` but without first clearing `gd.calcdata`.',
4848
'*legend* only redraws the legend.',
4949
'*ticks* only redraws axis ticks, labels, and gridlines.',
50+
'*margins* recomputes ticklabel automargins.',
5051
'*layoutstyle* reapplies global and SVG cartesian axis styles.',
5152
'*modebar* just updates the modebar.',
5253
'*camera* just updates the camera settings for gl3d scenes.',

src/plot_api/helpers.js

+9
Original file line numberDiff line numberDiff line change
@@ -561,3 +561,12 @@ exports.clearAxisTypes = function(gd, traces, layoutUpdate) {
561561
}
562562
}
563563
};
564+
565+
exports.clearAxisAutomargins = function(gd) {
566+
var keys = Object.keys(gd._fullLayout._pushmargin);
567+
for(var i = 0; i < keys.length; i++) {
568+
if(keys[i].indexOf('automargin') !== -1) {
569+
delete gd._fullLayout._pushmargin[keys[i]];
570+
}
571+
}
572+
};

src/plot_api/plot_api.js

+3
Original file line numberDiff line numberDiff line change
@@ -1742,6 +1742,7 @@ Plotly.relayout = function relayout(gd, astr, val) {
17421742

17431743
// clear calcdata if required
17441744
if(flags.calc) gd.calcdata = undefined;
1745+
if(flags.margins) helpers.clearAxisAutomargins(gd);
17451746

17461747
// fill in redraw sequence
17471748

@@ -2182,6 +2183,7 @@ Plotly.update = function update(gd, traceUpdate, layoutUpdate, _traces) {
21822183
// clear calcdata and/or axis types if required
21832184
if(restyleFlags.clearCalc || relayoutFlags.calc) gd.calcdata = undefined;
21842185
if(restyleFlags.clearAxisTypes) helpers.clearAxisTypes(gd, traces, layoutUpdate);
2186+
if(relayoutFlags.margins) helpers.clearAxisAutomargins(gd);
21852187

21862188
// fill in redraw sequence
21872189
var seq = [];
@@ -2309,6 +2311,7 @@ Plotly.react = function(gd, data, layout, config) {
23092311

23102312
// clear calcdata if required
23112313
if(restyleFlags.calc || relayoutFlags.calc) gd.calcdata = undefined;
2314+
if(relayoutFlags.margins) helpers.clearAxisAutomargins(gd);
23122315

23132316
// Note: what restyle/relayout use impliedEdits and clearAxisTypes for
23142317
// must be handled by the user when using Plotly.react.

src/plots/cartesian/axes.js

+19-26
Original file line numberDiff line numberDiff line change
@@ -2219,38 +2219,31 @@ axes.doTicks = function(gd, axid, skipTitle) {
22192219
}
22202220

22212221
function doAutoMargins() {
2222+
if(!ax.automargin) { return; }
22222223
if(axLetter !== 'x' && axLetter !== 'y') { return; }
2223-
var pushKey = ax._name + '.automargin';
2224-
var sideLetter = ax.side[0];
2225-
var existingPush = fullLayout._pushmargin[pushKey];
2226-
var pushParams = {x: 0, y: 0, r: 0, l: 0, t: 0, b: 0};
2227-
2228-
if(!ax.automargin || ax.anchor === 'free' || !ax._anchorAxis) {
2229-
if(existingPush && !(
2230-
existingPush.r.size === 0 && existingPush.l.size === 0 &&
2231-
existingPush.b.size === 0 && existingPush.t.size === 0)) {
2232-
Plots.autoMargin(gd, pushKey, pushParams);
2233-
}
2234-
return;
2235-
}
22362224

2237-
var axisDim;
2225+
var s = ax.side[0];
2226+
var push = {x: 0, y: 0, r: 0, l: 0, t: 0, b: 0};
2227+
22382228
if(axLetter === 'x') {
2239-
pushParams.y = ax._anchorAxis.domain[sideLetter === 't' ? 1 : 0];
2240-
axisDim = ax._boundingBox.height;
2229+
push.y = (ax.anchor === 'free' ? ax.position :
2230+
ax._anchorAxis.domain[s === 't' ? 1 : 0]);
2231+
push[s] += ax._boundingBox.height;
22412232
}
22422233
else {
2243-
pushParams.x = ax._anchorAxis.domain[sideLetter === 'r' ? 1 : 0];
2244-
axisDim = ax._boundingBox.width;
2234+
push.x = (ax.anchor === 'free' ? ax.position :
2235+
ax._anchorAxis.domain[s === 'r' ? 1 : 0]);
2236+
push[s] += ax._boundingBox.width;
22452237
}
2246-
var axisTitleDim = (ax.title !== fullLayout._dfltTitle[axLetter] ?
2247-
ax.titlefont.size : 0);
2248-
var marginPush = axisTitleDim + axisDim;
2249-
2250-
if(!fullLayout._replotting ||
2251-
!existingPush || existingPush[sideLetter].size < marginPush) {
2252-
pushParams[sideLetter] = marginPush;
2253-
Plots.autoMargin(gd, pushKey, pushParams);
2238+
2239+
if(ax.title !== fullLayout._dfltTitle[axLetter]) {
2240+
push[s] += ax.titlefont.size;
2241+
}
2242+
2243+
var pushKey = ax._name + '.automargin';
2244+
var prevPush = fullLayout._pushmargin[pushKey];
2245+
if(!prevPush || prevPush[s].size < push[s]) {
2246+
Plots.autoMargin(gd, pushKey, push);
22542247
}
22552248
}
22562249

src/plots/cartesian/layout_attributes.js

+36-36
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,11 @@ module.exports = {
4242
title: {
4343
valType: 'string',
4444
role: 'info',
45-
editType: 'ticks',
45+
editType: 'ticks+margins',
4646
description: 'Sets the title of this axis.'
4747
},
4848
titlefont: fontAttrs({
49-
editType: 'ticks',
49+
editType: 'ticks+margins',
5050
description: [
5151
'Sets this axis\' title font.'
5252
].join(' ')
@@ -100,10 +100,10 @@ module.exports = {
100100
valType: 'info_array',
101101
role: 'info',
102102
items: [
103-
{valType: 'any', editType: 'plot', impliedEdits: {'^autorange': false}},
104-
{valType: 'any', editType: 'plot', impliedEdits: {'^autorange': false}}
103+
{valType: 'any', editType: 'plot+margins', impliedEdits: {'^autorange': false}},
104+
{valType: 'any', editType: 'plot+margins', impliedEdits: {'^autorange': false}}
105105
],
106-
editType: 'plot',
106+
editType: 'plot+margins',
107107
impliedEdits: {'autorange': false},
108108
description: [
109109
'Sets the range of this axis.',
@@ -198,7 +198,7 @@ module.exports = {
198198
valType: 'enumerated',
199199
values: ['auto', 'linear', 'array'],
200200
role: 'info',
201-
editType: 'ticks',
201+
editType: 'ticks+margins',
202202
impliedEdits: {tick0: undefined, dtick: undefined},
203203
description: [
204204
'Sets the tick mode for this axis.',
@@ -216,7 +216,7 @@ module.exports = {
216216
min: 0,
217217
dflt: 0,
218218
role: 'style',
219-
editType: 'ticks',
219+
editType: 'ticks+margins',
220220
description: [
221221
'Specifies the maximum number of ticks for the particular axis.',
222222
'The actual number of ticks will be chosen automatically to be',
@@ -227,7 +227,7 @@ module.exports = {
227227
tick0: {
228228
valType: 'any',
229229
role: 'style',
230-
editType: 'ticks',
230+
editType: 'ticks+margins',
231231
impliedEdits: {tickmode: 'linear'},
232232
description: [
233233
'Sets the placement of the first tick on this axis.',
@@ -243,7 +243,7 @@ module.exports = {
243243
dtick: {
244244
valType: 'any',
245245
role: 'style',
246-
editType: 'ticks',
246+
editType: 'ticks+margins',
247247
impliedEdits: {tickmode: 'linear'},
248248
description: [
249249
'Sets the step in-between ticks on this axis. Use with `tick0`.',
@@ -269,7 +269,7 @@ module.exports = {
269269
},
270270
tickvals: {
271271
valType: 'data_array',
272-
editType: 'ticks',
272+
editType: 'ticks+margins',
273273
description: [
274274
'Sets the values at which ticks on this axis appear.',
275275
'Only has an effect if `tickmode` is set to *array*.',
@@ -278,7 +278,7 @@ module.exports = {
278278
},
279279
ticktext: {
280280
valType: 'data_array',
281-
editType: 'ticks',
281+
editType: 'ticks+margins',
282282
description: [
283283
'Sets the text displayed at the ticks position via `tickvals`.',
284284
'Only has an effect if `tickmode` is set to *array*.',
@@ -289,7 +289,7 @@ module.exports = {
289289
valType: 'enumerated',
290290
values: ['outside', 'inside', ''],
291291
role: 'style',
292-
editType: 'ticks',
292+
editType: 'ticks+margins',
293293
description: [
294294
'Determines whether ticks are drawn or not.',
295295
'If **, this axis\' ticks are not drawn.',
@@ -341,14 +341,14 @@ module.exports = {
341341
valType: 'boolean',
342342
dflt: true,
343343
role: 'style',
344-
editType: 'ticks',
344+
editType: 'ticks+margins',
345345
description: 'Determines whether or not the tick labels are drawn.'
346346
},
347347
automargin: {
348348
valType: 'boolean',
349349
dflt: false,
350350
role: 'style',
351-
editType: 'ticks',
351+
editType: 'ticks+margins',
352352
description: [
353353
'Determines whether long tick labels automatically grow the figure',
354354
'margins.'
@@ -406,14 +406,14 @@ module.exports = {
406406
description: 'Determines whether spikelines are stuck to the cursor or to the closest datapoints.'
407407
},
408408
tickfont: fontAttrs({
409-
editType: 'ticks',
409+
editType: 'ticks+margins',
410410
description: 'Sets the tick font.'
411411
}),
412412
tickangle: {
413413
valType: 'angle',
414414
dflt: 'auto',
415415
role: 'style',
416-
editType: 'ticks',
416+
editType: 'ticks+margins',
417417
description: [
418418
'Sets the angle of the tick labels with respect to the horizontal.',
419419
'For example, a `tickangle` of -90 draws the tick labels',
@@ -424,15 +424,15 @@ module.exports = {
424424
valType: 'string',
425425
dflt: '',
426426
role: 'style',
427-
editType: 'ticks',
427+
editType: 'ticks+margins',
428428
description: 'Sets a tick label prefix.'
429429
},
430430
showtickprefix: {
431431
valType: 'enumerated',
432432
values: ['all', 'first', 'last', 'none'],
433433
dflt: 'all',
434434
role: 'style',
435-
editType: 'ticks',
435+
editType: 'ticks+margins',
436436
description: [
437437
'If *all*, all tick labels are displayed with a prefix.',
438438
'If *first*, only the first tick is displayed with a prefix.',
@@ -444,23 +444,23 @@ module.exports = {
444444
valType: 'string',
445445
dflt: '',
446446
role: 'style',
447-
editType: 'ticks',
447+
editType: 'ticks+margins',
448448
description: 'Sets a tick label suffix.'
449449
},
450450
showticksuffix: {
451451
valType: 'enumerated',
452452
values: ['all', 'first', 'last', 'none'],
453453
dflt: 'all',
454454
role: 'style',
455-
editType: 'ticks',
455+
editType: 'ticks+margins',
456456
description: 'Same as `showtickprefix` but for tick suffixes.'
457457
},
458458
showexponent: {
459459
valType: 'enumerated',
460460
values: ['all', 'first', 'last', 'none'],
461461
dflt: 'all',
462462
role: 'style',
463-
editType: 'ticks',
463+
editType: 'ticks+margins',
464464
description: [
465465
'If *all*, all exponents are shown besides their significands.',
466466
'If *first*, only the exponent of the first tick is shown.',
@@ -473,7 +473,7 @@ module.exports = {
473473
values: ['none', 'e', 'E', 'power', 'SI', 'B'],
474474
dflt: 'B',
475475
role: 'style',
476-
editType: 'ticks',
476+
editType: 'ticks+margins',
477477
description: [
478478
'Determines a formatting rule for the tick exponents.',
479479
'For example, consider the number 1,000,000,000.',
@@ -489,7 +489,7 @@ module.exports = {
489489
valType: 'boolean',
490490
dflt: false,
491491
role: 'style',
492-
editType: 'ticks',
492+
editType: 'ticks+margins',
493493
description: [
494494
'If "true", even 4-digit integers are separated'
495495
].join(' ')
@@ -498,7 +498,7 @@ module.exports = {
498498
valType: 'string',
499499
dflt: '',
500500
role: 'style',
501-
editType: 'ticks',
501+
editType: 'ticks+margins',
502502
description: [
503503
'Sets the tick label formatting rule using d3 formatting mini-languages',
504504
'which are very similar to those in Python. For numbers, see:',
@@ -517,10 +517,10 @@ module.exports = {
517517
valType: 'info_array',
518518
role: 'info',
519519
items: [
520-
{valType: 'any', editType: 'ticks'},
521-
{valType: 'any', editType: 'ticks'}
520+
{valType: 'any', editType: 'ticks+margins'},
521+
{valType: 'any', editType: 'ticks+margins'}
522522
],
523-
editType: 'ticks',
523+
editType: 'ticks+margins',
524524
description: [
525525
'range [*min*, *max*], where *min*, *max* - dtick values',
526526
'which describe some zoom level, it is possible to omit *min*',
@@ -531,12 +531,12 @@ module.exports = {
531531
valType: 'string',
532532
dflt: '',
533533
role: 'style',
534-
editType: 'ticks',
534+
editType: 'ticks+margins',
535535
description: [
536536
'string - dtickformat for described zoom level, the same as *tickformat*'
537537
].join(' ')
538538
},
539-
editType: 'ticks'
539+
editType: 'ticks+margins'
540540
},
541541
hoverformat: {
542542
valType: 'string',
@@ -638,7 +638,7 @@ module.exports = {
638638
constants.idRegex.y.toString()
639639
],
640640
role: 'info',
641-
editType: 'plot',
641+
editType: 'plot+margins',
642642
description: [
643643
'If set to an opposite-letter axis id (e.g. `x2`, `y`), this axis is bound to',
644644
'the corresponding opposite-letter axis.',
@@ -651,7 +651,7 @@ module.exports = {
651651
valType: 'enumerated',
652652
values: ['top', 'bottom', 'left', 'right'],
653653
role: 'info',
654-
editType: 'plot',
654+
editType: 'plot+margins',
655655
description: [
656656
'Determines whether a x (y) axis is positioned',
657657
'at the *bottom* (*left*) or *top* (*right*)',
@@ -695,11 +695,11 @@ module.exports = {
695695
valType: 'info_array',
696696
role: 'info',
697697
items: [
698-
{valType: 'number', min: 0, max: 1, editType: 'plot'},
699-
{valType: 'number', min: 0, max: 1, editType: 'plot'}
698+
{valType: 'number', min: 0, max: 1, editType: 'plot+margins'},
699+
{valType: 'number', min: 0, max: 1, editType: 'plot+margins'}
700700
],
701701
dflt: [0, 1],
702-
editType: 'plot',
702+
editType: 'plot+margins',
703703
description: [
704704
'Sets the domain of this axis (in plot fraction).'
705705
].join(' ')
@@ -710,7 +710,7 @@ module.exports = {
710710
max: 1,
711711
dflt: 0,
712712
role: 'style',
713-
editType: 'plot',
713+
editType: 'plot+margins',
714714
description: [
715715
'Sets the position of this axis in the plotting space',
716716
'(in normalized coordinates).',
@@ -754,7 +754,7 @@ module.exports = {
754754
autotick: {
755755
valType: 'boolean',
756756
role: 'info',
757-
editType: 'ticks',
757+
editType: 'ticks+margins',
758758
description: [
759759
'Obsolete.',
760760
'Set `tickmode` to *auto* for old `autotick` *true* behavior.',

0 commit comments

Comments
 (0)