Skip to content

Commit 8b1f5bd

Browse files
authored
Merge pull request #7006 from my-tien/shift_axis_label
Add `ticklabelstandoff` and `ticklabelshift` to cartesian axes
2 parents 8c47c16 + 26315dc commit 8b1f5bd

14 files changed

+254
-7
lines changed

Diff for: draftlogs/7006_add.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Add property `ticklabelstandoff` and `ticklabelshift` to cartesian axes to adjust positioning of tick labels [[#7006](https://github.com/plotly/plotly.js/pull/7006)]

Diff for: src/components/colorbar/defaults.js

+2
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ module.exports = function colorbarDefaults(containerIn, containerOut, layout) {
111111
var font = layout.font;
112112
var opts = {
113113
noAutotickangles: true,
114+
noTicklabelshift: true,
115+
noTicklabelstandoff: true,
114116
outerTicks: false,
115117
font: font
116118
};

Diff for: src/plots/cartesian/axes.js

+23-4
Original file line numberDiff line numberDiff line change
@@ -2968,20 +2968,39 @@ axes.makeTransTickFn = function(ax) {
29682968

29692969
axes.makeTransTickLabelFn = function(ax) {
29702970
var uv = getTickLabelUV(ax);
2971+
var shift = ax.ticklabelshift || 0;
2972+
var standoff = ax.ticklabelstandoff || 0;
2973+
29712974
var u = uv[0];
29722975
var v = uv[1];
29732976

2977+
var isReversed = ax.range[0] > ax.range[1];
2978+
var labelsInside = ax.ticklabelposition && ax.ticklabelposition.indexOf('inside') !== -1;
2979+
var labelsOutside = !labelsInside;
2980+
2981+
if(shift) {
2982+
var shiftSign = isReversed ? -1 : 1;
2983+
shift = shift * shiftSign;
2984+
}
2985+
if(standoff) {
2986+
var side = ax.side;
2987+
var standoffSign = (
2988+
(labelsInside && (side === 'top' || side === 'left')) ||
2989+
(labelsOutside && (side === 'bottom' || side === 'right'))
2990+
) ? 1 : -1;
2991+
standoff = standoff * standoffSign;
2992+
}
29742993
return ax._id.charAt(0) === 'x' ?
29752994
function(d) {
29762995
return strTranslate(
2977-
u + ax._offset + ax.l2p(getPosX(d)),
2978-
v
2996+
u + ax._offset + ax.l2p(getPosX(d)) + shift,
2997+
v + standoff
29792998
);
29802999
} :
29813000
function(d) {
29823001
return strTranslate(
2983-
v,
2984-
u + ax._offset + ax.l2p(getPosX(d))
3002+
v + standoff,
3003+
u + ax._offset + ax.l2p(getPosX(d)) + shift
29853004
);
29863005
};
29873006
};

Diff for: src/plots/cartesian/layout_attributes.js

+23
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,29 @@ module.exports = {
698698
'In other cases the default is *hide past div*.'
699699
].join(' ')
700700
},
701+
ticklabelshift: {
702+
valType: 'integer',
703+
dflt: 0,
704+
editType: 'ticks',
705+
description: [
706+
'Shifts the tick labels by the specified number of pixels in parallel to the axis.',
707+
'Positive values move the labels in the positive direction of the axis.'
708+
].join(' ')
709+
},
710+
ticklabelstandoff: {
711+
valType: 'integer',
712+
dflt: 0,
713+
editType: 'ticks',
714+
description: [
715+
'Sets the standoff distance (in px) between the axis tick labels and their default position.',
716+
'A positive `ticklabelstandoff` moves the labels farther away from the plot area',
717+
'if `ticklabelposition` is *outside*, and deeper into the plot area if',
718+
'`ticklabelposition` is *inside*. A negative `ticklabelstandoff` works in the opposite',
719+
'direction, moving outside ticks towards the plot area and inside ticks towards',
720+
'the outside. If the negative value is large enough, inside ticks can even end up',
721+
'outside and vice versa.'
722+
].join(' ')
723+
},
701724
mirror: {
702725
valType: 'enumerated',
703726
values: [true, 'ticks', false, 'all', 'allticks'],

Diff for: src/plots/cartesian/tick_label_defaults.js

+6
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ module.exports = function handleTickLabelDefaults(containerIn, containerOut, coe
1616

1717
var showTickLabels = coerce('showticklabels');
1818
if(showTickLabels) {
19+
if(!options.noTicklabelshift) {
20+
coerce('ticklabelshift');
21+
}
22+
if(!options.noTicklabelstandoff) {
23+
coerce('ticklabelstandoff');
24+
}
1925
var font = options.font || {};
2026
var contColor = containerOut.color;
2127
var position = containerOut.ticklabelposition || '';

Diff for: src/plots/gl3d/layout/axis_defaults.js

+2
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, options) {
4444
noAutotickangles: true,
4545
noTickson: true,
4646
noTicklabelmode: true,
47+
noTicklabelshift: true,
48+
noTicklabelstandoff: true,
4749
noTicklabelstep: true,
4850
noTicklabelposition: true,
4951
noTicklabeloverflow: true,

Diff for: src/plots/polar/layout_defaults.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,9 @@ function handleDefaults(contIn, contOut, coerce, opts) {
186186
size: dfltFontSize,
187187
family: dfltFontFamily
188188
},
189-
noAutotickangles: axName === 'angularaxis'
189+
noAutotickangles: axName === 'angularaxis',
190+
noTicklabelshift: true,
191+
noTicklabelstandoff: true
190192
});
191193

192194
handleTickMarkDefaults(axIn, axOut, coerceAxis, {outerTicks: true});

Diff for: src/plots/smith/layout_defaults.js

+2
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ function handleDefaults(contIn, contOut, coerce, opts) {
9090

9191
handleTickLabelDefaults(axIn, axOut, coerceAxis, axOut.type, {
9292
noAutotickangles: true,
93+
noTicklabelshift: true,
94+
noTicklabelstandoff: true,
9395
noTicklabelstep: true,
9496
noAng: !isRealAxis,
9597
noExp: true,

Diff for: src/plots/ternary/layout_defaults.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,11 @@ function handleAxisDefaults(containerIn, containerOut, options, ternaryLayoutOut
9191

9292
handleTickValueDefaults(containerIn, containerOut, coerce, 'linear');
9393
handlePrefixSuffixDefaults(containerIn, containerOut, coerce, 'linear');
94-
handleTickLabelDefaults(containerIn, containerOut, coerce, 'linear', { noAutotickangles: true });
94+
handleTickLabelDefaults(containerIn, containerOut, coerce, 'linear', {
95+
noAutotickangles: true,
96+
noTicklabelshift: true,
97+
noTicklabelstandoff: true
98+
});
9599
handleTickMarkDefaults(containerIn, containerOut, coerce,
96100
{ outerTicks: true });
97101

Diff for: src/traces/carpet/ab_defaults.js

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ function mimickAxisDefaults(traceIn, traceOut, fullLayout, dfltColor) {
3131

3232
var defaultOptions = {
3333
noAutotickangles: true,
34+
noTicklabelshift: true,
35+
noTicklabelstandoff: true,
3436
noTicklabelstep: true,
3537
tickfont: 'x',
3638
id: axLetter + 'axis',

Diff for: src/traces/indicator/defaults.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,9 @@ function supplyDefaults(traceIn, traceOut, defaultColor, layout) {
132132
var opts = {
133133
font: layout.font,
134134
noAutotickangles: true,
135-
outerTicks: true
135+
outerTicks: true,
136+
noTicklabelshift: true,
137+
noTicklabelstandoff: true
136138
};
137139
handleTickValueDefaults(axisIn, axisOut, coerceGaugeAxis, 'linear');
138140
handlePrefixSuffixDefaults(axisIn, axisOut, coerceGaugeAxis, 'linear', opts);
54.5 KB
Loading
+158
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
{
2+
"data": [{
3+
"xaxis": "x",
4+
"yaxis": "y",
5+
"x": ["20-12-20", "21-01-20"],
6+
"y": [1e-1, 1e+6]
7+
}, {
8+
"xaxis": "x2",
9+
"yaxis": "y2",
10+
"x": ["20-10", "21-05-15"],
11+
"y": [1e-1, 1e+6]
12+
}, {
13+
"xaxis": "x3",
14+
"yaxis": "y3",
15+
"x": ["20", "23"],
16+
"y": [1e-1, 1e+6]
17+
}, {
18+
"xaxis": "x4",
19+
"yaxis": "y4",
20+
"x": ["20-12-20", "21-01-20"],
21+
"y": [1e-1, 1e+6]
22+
}],
23+
"layout": {
24+
"xaxis": {
25+
"minor": { "showgrid": true },
26+
"anchor": "y",
27+
"domain": [0, 0.475],
28+
"type": "date",
29+
"ticklabelmode": "period",
30+
"ticklabelstandoff": 20,
31+
"ticklabelshift": 20,
32+
"side": "bottom",
33+
"ticks": "inside",
34+
"tickfont": { "size": 16 },
35+
"ticklen": 16,
36+
"tickwidth": 8,
37+
"linewidth": 1,
38+
"gridcolor": "white"
39+
},
40+
"yaxis": {
41+
"minor": { "showgrid": true },
42+
"anchor": "x",
43+
"domain": [0, 0.475],
44+
"autorange": "reversed",
45+
"type": "log",
46+
"side": "left",
47+
"ticks": "inside",
48+
"ticklabelposition": "outside top",
49+
"ticklabelstandoff": 20,
50+
"tickfont": { "size": 20 },
51+
"ticklen": 8,
52+
"tickwidth": 4,
53+
"linewidth": 4,
54+
"gridcolor": "white"
55+
},
56+
"xaxis2": {
57+
"minor": { "showgrid": true },
58+
"anchor": "y2",
59+
"domain": [0.525, 1],
60+
"autorange": "reversed",
61+
"type": "date",
62+
"side": "bottom",
63+
"ticks": "inside",
64+
"ticklabelposition": "inside left",
65+
"ticklabelstandoff": 20,
66+
"tickfont": { "size": 20 },
67+
"ticklen": 8,
68+
"tickwidth": 4,
69+
"linewidth": 4,
70+
"gridcolor": "white"
71+
},
72+
"yaxis2": {
73+
"minor": { "showgrid": true },
74+
"anchor": "x2",
75+
"domain": [0, 0.475],
76+
"type": "log",
77+
"side": "right",
78+
"ticks": "inside",
79+
"ticklabelposition": "inside",
80+
"ticklabelstandoff": 20,
81+
"ticklen": 16,
82+
"tickwidth": 8,
83+
"linewidth": 1,
84+
"gridcolor": "white"
85+
},
86+
"xaxis3": {
87+
"minor": { "showgrid": true },
88+
"anchor": "y3",
89+
"domain": [0.525, 1],
90+
"type": "date",
91+
"side": "top",
92+
"ticks": "inside",
93+
"ticklabelposition": "inside right",
94+
"ticklabelstandoff": 20,
95+
"ticklabelshift": 40,
96+
"tickfont": { "size": 20 },
97+
"ticklen": 16,
98+
"tickwidth": 8,
99+
"linewidth": 1,
100+
"gridcolor": "white"
101+
},
102+
"yaxis3": {
103+
"minor": { "showgrid": true },
104+
"anchor": "x3",
105+
"domain": [0.525, 1],
106+
"autorange": "reversed",
107+
"type": "log",
108+
"side": "right",
109+
"ticks": "inside",
110+
"ticklabelposition": "inside bottom",
111+
"ticklabelstandoff": 10,
112+
"ticklabelshift": -10,
113+
"tickfont": { "size": 16 },
114+
"ticklen": 8,
115+
"tickwidth": 4,
116+
"linewidth": 4,
117+
"gridcolor": "white"
118+
},
119+
"xaxis4": {
120+
"minor": { "showgrid": true },
121+
"anchor": "y4",
122+
"domain": [0, 0.475],
123+
"autorange": "reversed",
124+
"type": "date",
125+
"ticklabelmode": "period",
126+
"side": "top",
127+
"ticks": "outside",
128+
"ticklabelposition": "outside",
129+
"ticklabelstandoff": -10,
130+
"ticklabelshift": 15,
131+
"tickfont": { "size": 16 },
132+
"ticklen": 8,
133+
"tickwidth": 4,
134+
"linewidth": 4,
135+
"gridcolor": "white"
136+
},
137+
"yaxis4": {
138+
"minor": { "showgrid": true },
139+
"anchor": "x4",
140+
"domain": [0.525, 1],
141+
"type": "log",
142+
"side": "left",
143+
"ticks": "outside",
144+
"ticklabelposition": "outside bottom",
145+
"tickangle": 30,
146+
"tickfont": { "size": 16 },
147+
"ticklen": 16,
148+
"tickwidth": 8,
149+
"linewidth": 1,
150+
"gridcolor": "white"
151+
},
152+
"font": {
153+
"family": "Raleway"
154+
},
155+
"plot_bgcolor": "lightblue",
156+
"showlegend": false
157+
}
158+
}

Diff for: test/plot-schema.json

+24
Original file line numberDiff line numberDiff line change
@@ -15154,6 +15154,18 @@
1515415154
"inside bottom"
1515515155
]
1515615156
},
15157+
"ticklabelshift": {
15158+
"description": "Shifts the tick labels by the specified number of pixels in parallel to the axis. Positive values move the labels in the positive direction of the axis.",
15159+
"dflt": 0,
15160+
"editType": "ticks",
15161+
"valType": "integer"
15162+
},
15163+
"ticklabelstandoff": {
15164+
"description": "Sets the standoff distance (in px) between the axis tick labels and their default position. A positive `ticklabelstandoff` moves the labels farther away from the plot area if `ticklabelposition` is *outside*, and deeper into the plot area if `ticklabelposition` is *inside*. A negative `ticklabelstandoff` works in the opposite direction, moving outside ticks towards the plot area and inside ticks towards the outside. If the negative value is large enough, inside ticks can even end up outside and vice versa.",
15165+
"dflt": 0,
15166+
"editType": "ticks",
15167+
"valType": "integer"
15168+
},
1515715169
"ticklabelstep": {
1515815170
"description": "Sets the spacing between tick labels as compared to the spacing between ticks. A value of 1 (default) means each tick gets a label. A value of 2 means shows every 2nd label. A larger value n means only every nth tick is labeled. `tick0` determines which labels are shown. Not implemented for axes with `type` *log* or *multicategory*, or when `tickmode` is *array*.",
1515915171
"dflt": 1,
@@ -16463,6 +16475,18 @@
1646316475
"inside bottom"
1646416476
]
1646516477
},
16478+
"ticklabelshift": {
16479+
"description": "Shifts the tick labels by the specified number of pixels in parallel to the axis. Positive values move the labels in the positive direction of the axis.",
16480+
"dflt": 0,
16481+
"editType": "ticks",
16482+
"valType": "integer"
16483+
},
16484+
"ticklabelstandoff": {
16485+
"description": "Sets the standoff distance (in px) between the axis tick labels and their default position. A positive `ticklabelstandoff` moves the labels farther away from the plot area if `ticklabelposition` is *outside*, and deeper into the plot area if `ticklabelposition` is *inside*. A negative `ticklabelstandoff` works in the opposite direction, moving outside ticks towards the plot area and inside ticks towards the outside. If the negative value is large enough, inside ticks can even end up outside and vice versa.",
16486+
"dflt": 0,
16487+
"editType": "ticks",
16488+
"valType": "integer"
16489+
},
1646616490
"ticklabelstep": {
1646716491
"description": "Sets the spacing between tick labels as compared to the spacing between ticks. A value of 1 (default) means each tick gets a label. A value of 2 means shows every 2nd label. A larger value n means only every nth tick is labeled. `tick0` determines which labels are shown. Not implemented for axes with `type` *log* or *multicategory*, or when `tickmode` is *array*.",
1646816492
"dflt": 1,

0 commit comments

Comments
 (0)