Skip to content

Commit 350a01c

Browse files
committed
Add insiderange to cartesian axes
1 parent 915a52b commit 350a01c

File tree

14 files changed

+484
-26
lines changed

14 files changed

+484
-26
lines changed

src/components/colorbar/draw.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,6 +1004,7 @@ function mockColorBarAxis(gd, opts, zrange) {
10041004
noHover: true,
10051005
noTickson: true,
10061006
noTicklabelmode: true,
1007+
noInsideRange: true,
10071008
calendar: fullLayout.calendar // not really necessary (yet?)
10081009
};
10091010

src/plot_api/plot_api.js

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -354,9 +354,11 @@ function _doPlot(gd, data, layout, config) {
354354
seq.push(
355355
drawAxes,
356356
function insideTickLabelsAutorange(gd) {
357-
if(gd._fullLayout._insideTickLabelsAutorange) {
358-
relayout(gd, gd._fullLayout._insideTickLabelsAutorange).then(function() {
359-
gd._fullLayout._insideTickLabelsAutorange = undefined;
357+
if(gd._fullLayout._insideTickLabelsUpdaterange) {
358+
relayout(gd, gd._fullLayout._insideTickLabelsUpdaterange).then(function() {
359+
Axes.saveRangeInitial(gd, true);
360+
361+
gd._fullLayout._insideTickLabelsUpdaterange = undefined;
360362
});
361363
}
362364
}
@@ -376,16 +378,9 @@ function _doPlot(gd, data, layout, config) {
376378
// calculated. Would be much better to separate margin calculations from
377379
// component drawing - see https://github.com/plotly/plotly.js/issues/2704
378380
Plots.doAutoMargin,
379-
saveRangeInitialForInsideTickLabels,
380381
Plots.previousPromises
381382
);
382383

383-
function saveRangeInitialForInsideTickLabels(gd) {
384-
if(gd._fullLayout._insideTickLabelsAutorange) {
385-
if(graphWasEmpty) Axes.saveRangeInitial(gd, true);
386-
}
387-
}
388-
389384
// even if everything we did was synchronous, return a promise
390385
// so that the caller doesn't care which route we took
391386
var plotDone = Lib.syncOrAsync(seq, gd);

src/plots/cartesian/axes.js

Lines changed: 79 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3821,28 +3821,92 @@ axes.drawLabels = function(gd, ax, opts) {
38213821
});
38223822
}
38233823

3824+
var computeTickLabelBoundingBoxes = function() {
3825+
var labelsMaxW = 0;
3826+
var labelsMaxH = 0;
3827+
tickLabels.each(function(d, i) {
3828+
var thisLabel = selectTickLabel(this);
3829+
var mathjaxGroup = thisLabel.select('.text-math-group');
3830+
3831+
if(mathjaxGroup.empty()) {
3832+
var bb;
3833+
3834+
if(ax._vals[i]) {
3835+
bb = ax._vals[i].bb || Drawing.bBox(thisLabel.node());
3836+
ax._vals[i].bb = bb;
3837+
}
3838+
3839+
labelsMaxW = Math.max(labelsMaxW, bb.width);
3840+
labelsMaxH = Math.max(labelsMaxW, bb.height);
3841+
}
3842+
});
3843+
3844+
return {
3845+
labelsMaxW: labelsMaxW,
3846+
labelsMaxH: labelsMaxH
3847+
};
3848+
};
3849+
38243850
var anchorAx = ax._anchorAxis;
38253851
if(
3826-
anchorAx && anchorAx.autorange &&
3852+
anchorAx && (anchorAx.autorange || anchorAx.insiderange) &&
38273853
insideTicklabelposition(ax) &&
38283854
!isLinked(fullLayout, ax._id)
38293855
) {
3830-
if(!fullLayout._insideTickLabelsAutorange) {
3831-
fullLayout._insideTickLabelsAutorange = {};
3856+
if(!fullLayout._insideTickLabelsUpdaterange) {
3857+
fullLayout._insideTickLabelsUpdaterange = {};
38323858
}
3833-
fullLayout._insideTickLabelsAutorange[anchorAx._name + '.autorange'] = anchorAx.autorange;
3834-
3835-
seq.push(
3836-
function computeFinalTickLabelBoundingBoxes() {
3837-
tickLabels.each(function(d, i) {
3838-
var thisLabel = selectTickLabel(this);
3839-
var mathjaxGroup = thisLabel.select('.text-math-group');
3840-
if(mathjaxGroup.empty()) {
3841-
ax._vals[i].bb = Drawing.bBox(thisLabel.node());
3842-
}
3843-
});
3859+
3860+
if(anchorAx.autorange) {
3861+
fullLayout._insideTickLabelsUpdaterange[anchorAx._name + '.autorange'] = anchorAx.autorange;
3862+
3863+
seq.push(computeTickLabelBoundingBoxes);
3864+
}
3865+
3866+
if(anchorAx.insiderange) {
3867+
var BBs = computeTickLabelBoundingBoxes();
3868+
var move = ax._id.charAt(0) === 'y' ?
3869+
BBs.labelsMaxW + 4 * TEXTPAD :
3870+
BBs.labelsMaxH;
3871+
3872+
if(ax.ticklabelposition === 'inside') {
3873+
move += ax.ticklen || 0;
38443874
}
3845-
);
3875+
3876+
if(ax._id.charAt(0) !== 'y') move = -move;
3877+
3878+
var sgn = (ax.side === 'right' || ax.side === 'top') ? 1 : -1;
3879+
var index = sgn === 1 ? 1 : 0;
3880+
var otherIndex = sgn === 1 ? 0 : 1;
3881+
3882+
var newRange = [];
3883+
newRange[otherIndex] = anchorAx.range[otherIndex];
3884+
newRange[index] = anchorAx.p2d(
3885+
anchorAx.d2p(anchorAx.range[index]) +
3886+
sgn * move
3887+
);
3888+
3889+
// handle partial ranges in insiderange
3890+
if(
3891+
anchorAx.autorange === 'min' ||
3892+
anchorAx.autorange === 'max reversed'
3893+
) {
3894+
newRange[0] = null;
3895+
3896+
anchorAx._rangeInitial0 = undefined;
3897+
anchorAx._rangeInitial1 = undefined;
3898+
} else if(
3899+
anchorAx.autorange === 'max' ||
3900+
anchorAx.autorange === 'min reversed'
3901+
) {
3902+
newRange[1] = null;
3903+
3904+
anchorAx._rangeInitial0 = undefined;
3905+
anchorAx._rangeInitial1 = undefined;
3906+
}
3907+
3908+
fullLayout._insideTickLabelsUpdaterange[anchorAx._name + '.range'] = newRange;
3909+
}
38463910
}
38473911

38483912
var done = Lib.syncOrAsync(seq);

src/plots/cartesian/axis_defaults.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,14 @@ module.exports = function handleAxisDefaults(containerIn, containerOut, coerce,
9292

9393
setConvert(containerOut, layoutOut);
9494

95+
var insiderange;
96+
if(!options.noInsiderange && axType !== 'log') {
97+
insiderange = coerce('insiderange');
98+
}
99+
95100
coerce('minallowed');
96101
coerce('maxallowed');
97-
var range = coerce('range');
102+
var range = coerce('range', insiderange);
98103
var autorangeDflt = containerOut.getAutorangeDflt(range, options);
99104
var autorange = coerce('autorange', autorangeDflt);
100105

src/plots/cartesian/layout_attributes.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,21 @@ module.exports = {
398398
'If true, then zoom is disabled.'
399399
].join(' ')
400400
},
401+
insiderange: {
402+
valType: 'info_array',
403+
items: [
404+
{valType: 'any', editType: 'axrange'},
405+
{valType: 'any', editType: 'axrange'}
406+
],
407+
editType: 'axrange',
408+
description: [
409+
'Could be used to set the desired inside range of this axis',
410+
'(excluding the labels) when `ticklabelposition` of',
411+
'the anchored axis has *inside*.',
412+
'Not implemented for axes with `type` *log*',
413+
'This would be ignored when `range` is provided.'
414+
].join(' ')
415+
},
401416
// scaleanchor: not used directly, just put here for reference
402417
// values are any opposite-letter axis id, or `false`.
403418
scaleanchor: {

src/plots/gl3d/layout/axis_defaults.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, options) {
4646
noTicklabelstep: true,
4747
noTicklabelposition: true,
4848
noTicklabeloverflow: true,
49+
noInsiderange: true,
4950
bgColor: options.bgColor,
5051
calendar: options.calendar
5152
},
Loading
56.1 KB
Loading
74.2 KB
Loading
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
{
2+
"data": [{
3+
"xaxis": "x",
4+
"yaxis": "y",
5+
"y": [1000, 10, 100, 1]
6+
}, {
7+
"xaxis": "x2",
8+
"yaxis": "y2",
9+
"y": [1000, 10, 100, 1]
10+
}, {
11+
"xaxis": "x3",
12+
"yaxis": "y3",
13+
"y": [1000, 10, 100, 1]
14+
}, {
15+
"xaxis": "x4",
16+
"yaxis": "y4",
17+
"y": [1000, 10, 100, 1]
18+
}],
19+
"layout": {
20+
"xaxis": {
21+
"insiderange": [-1, null],
22+
"anchor": "y",
23+
"domain": [0, 0.45],
24+
"gridcolor": "white"
25+
},
26+
"yaxis": {
27+
"anchor": "x",
28+
"domain": [0, 0.45],
29+
"side": "right",
30+
"ticks": "inside",
31+
"ticklabelposition": "inside",
32+
"ticklen": 8,
33+
"tickwidth": 3,
34+
"gridcolor": "white"
35+
},
36+
"xaxis2": {
37+
"insiderange": [null, 4],
38+
"anchor": "y2",
39+
"domain": [0, 0.45],
40+
"gridcolor": "white"
41+
},
42+
"yaxis2": {
43+
"anchor": "x2",
44+
"domain": [0.55, 1],
45+
"side": "left",
46+
"ticks": "inside",
47+
"ticklabelposition": "inside",
48+
"ticklen": 8,
49+
"tickwidth": 3,
50+
"gridcolor": "white"
51+
},
52+
"xaxis3": {
53+
"insiderange": [null, -1],
54+
"autorange": "max reversed",
55+
"anchor": "y3",
56+
"domain": [0.55, 1],
57+
"gridcolor": "white"
58+
},
59+
"yaxis3": {
60+
"anchor": "x3",
61+
"domain": [0, 0.45],
62+
"side": "left",
63+
"ticks": "inside",
64+
"ticklabelposition": "inside",
65+
"ticklen": 8,
66+
"tickwidth": 3,
67+
"gridcolor": "white"
68+
},
69+
"xaxis4": {
70+
"insiderange": [4, null],
71+
"autorange": "min reversed",
72+
"anchor": "y4",
73+
"domain": [0.55, 1],
74+
"gridcolor": "white"
75+
},
76+
"yaxis4": {
77+
"anchor": "x4",
78+
"domain": [0.55, 1],
79+
"side": "right",
80+
"ticks": "inside",
81+
"ticklabelposition": "inside",
82+
"ticklen": 8,
83+
"tickwidth": 3,
84+
"gridcolor": "white"
85+
},
86+
"plot_bgcolor": "lightblue",
87+
"showlegend": false,
88+
"width": 900,
89+
"height": 900,
90+
"margin": {
91+
"t": 60,
92+
"b": 60,
93+
"l": 60,
94+
"r": 60
95+
}
96+
}
97+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
{
2+
"data": [{
3+
"xaxis": "x",
4+
"yaxis": "y",
5+
"y": [1000, 10, 100, 1]
6+
}, {
7+
"xaxis": "x2",
8+
"yaxis": "y2",
9+
"y": [1000, 10, 100, 1]
10+
}, {
11+
"xaxis": "x3",
12+
"yaxis": "y3",
13+
"x": [2000, 2001, 2002, 2003],
14+
"y": [1000, 10, 100, 1]
15+
}, {
16+
"xaxis": "x4",
17+
"yaxis": "y4",
18+
"x": [2000, 2001, 2002, 2003],
19+
"y": [1000, 10, 100, 1]
20+
}],
21+
"layout": {
22+
"xaxis": {
23+
"insiderange": [1, 2],
24+
"anchor": "y",
25+
"domain": [0, 0.45],
26+
"gridcolor": "white"
27+
},
28+
"yaxis": {
29+
"anchor": "x",
30+
"domain": [0, 0.45],
31+
"side": "right",
32+
"ticks": "inside",
33+
"ticklabelposition": "inside",
34+
"ticklen": 8,
35+
"tickwidth": 3,
36+
"gridcolor": "white"
37+
},
38+
"xaxis2": {
39+
"insiderange": [2, 1],
40+
"anchor": "y2",
41+
"domain": [0, 0.45],
42+
"gridcolor": "white"
43+
},
44+
"yaxis2": {
45+
"anchor": "x2",
46+
"domain": [0.55, 1],
47+
"side": "left",
48+
"ticks": "inside",
49+
"ticklabelposition": "inside",
50+
"ticklen": 8,
51+
"tickwidth": 3,
52+
"gridcolor": "white"
53+
},
54+
"xaxis3": {
55+
"type": "date",
56+
"insiderange": ["2001-01", "2002-01"],
57+
"anchor": "y3",
58+
"domain": [0.55, 1],
59+
"gridcolor": "white"
60+
},
61+
"yaxis3": {
62+
"anchor": "x3",
63+
"domain": [0, 0.45],
64+
"side": "right",
65+
"ticks": "inside",
66+
"ticklabelposition": "inside",
67+
"ticklen": 8,
68+
"tickwidth": 3,
69+
"gridcolor": "white"
70+
},
71+
"xaxis4": {
72+
"type": "date",
73+
"insiderange": ["2002-01", "2001-01"],
74+
"anchor": "y4",
75+
"domain": [0.55, 1],
76+
"gridcolor": "white"
77+
},
78+
"yaxis4": {
79+
"anchor": "x4",
80+
"domain": [0.55, 1],
81+
"side": "left",
82+
"ticks": "inside",
83+
"ticklabelposition": "inside",
84+
"ticklen": 8,
85+
"tickwidth": 3,
86+
"gridcolor": "white"
87+
},
88+
"plot_bgcolor": "lightblue",
89+
"showlegend": false,
90+
"width": 900,
91+
"height": 900,
92+
"margin": {
93+
"t": 60,
94+
"b": 60,
95+
"l": 60,
96+
"r": 60
97+
}
98+
}
99+
}

0 commit comments

Comments
 (0)