Skip to content

Commit e2fd2bb

Browse files
authored
Merge pull request #7420 from my-tien/ticklabelposition-category-axes
Add support for `ticklabelposition` "inside"/"outside" for category axes with `tickson` set to "boundaries"
2 parents d745a1b + 8ff47c2 commit e2fd2bb

File tree

7 files changed

+173
-15
lines changed

7 files changed

+173
-15
lines changed

draftlogs/7420_add.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- Add support for ticklabelposition "inside"/"outside" for category axes with `tickson` set to "boundaries" [[#7420](https://github.com/plotly/plotly.js/pull/7420)],
2+
with thanks to @my-tien for the contribution!

src/plots/cartesian/axes.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3073,6 +3073,7 @@ function getPosX(d) {
30733073
// v is a shift perpendicular to the axis
30743074
function getTickLabelUV(ax) {
30753075
var ticklabelposition = ax.ticklabelposition || '';
3076+
var tickson = ax.tickson || '';
30763077
var has = function(str) {
30773078
return ticklabelposition.indexOf(str) !== -1;
30783079
};
@@ -3083,7 +3084,7 @@ function getTickLabelUV(ax) {
30833084
var isBottom = has('bottom');
30843085
var isInside = has('inside');
30853086

3086-
var isAligned = isBottom || isLeft || isTop || isRight;
3087+
var isAligned = (tickson !== 'boundaries') && (isBottom || isLeft || isTop || isRight);
30873088

30883089
// early return
30893090
if(!isAligned && !isInside) return [0, 0];
@@ -3167,6 +3168,8 @@ axes.makeTickPath = function(ax, shift, sgn, opts) {
31673168
*/
31683169
axes.makeLabelFns = function(ax, shift, angle) {
31693170
var ticklabelposition = ax.ticklabelposition || '';
3171+
var tickson = ax.tickson || '';
3172+
31703173
var has = function(str) {
31713174
return ticklabelposition.indexOf(str) !== -1;
31723175
};
@@ -3175,12 +3178,12 @@ axes.makeLabelFns = function(ax, shift, angle) {
31753178
var isLeft = has('left');
31763179
var isRight = has('right');
31773180
var isBottom = has('bottom');
3178-
var isAligned = isBottom || isLeft || isTop || isRight;
3181+
var isAligned = (tickson !== 'boundaries') && (isBottom || isLeft || isTop || isRight);
31793182

31803183
var insideTickLabels = has('inside');
31813184
var labelsOverTicks =
31823185
(ticklabelposition === 'inside' && ax.ticks === 'inside') ||
3183-
(!insideTickLabels && ax.ticks === 'outside' && ax.tickson !== 'boundaries');
3186+
(!insideTickLabels && ax.ticks === 'outside' && tickson !== 'boundaries');
31843187

31853188
var labelStandoff = 0;
31863189
var labelShift = 0;
@@ -3895,14 +3898,16 @@ axes.drawLabels = function(gd, ax, opts) {
38953898
}
38963899
} else {
38973900
var ticklabelposition = ax.ticklabelposition || '';
3901+
var tickson = ax.tickson ||'';
3902+
38983903
var has = function(str) {
38993904
return ticklabelposition.indexOf(str) !== -1;
39003905
};
39013906
var isTop = has('top');
39023907
var isLeft = has('left');
39033908
var isRight = has('right');
39043909
var isBottom = has('bottom');
3905-
var isAligned = isBottom || isLeft || isTop || isRight;
3910+
var isAligned = (tickson !== 'boundaries') && (isBottom || isLeft || isTop || isRight);
39063911
var pad = !isAligned ? 0 :
39073912
(ax.tickwidth || 0) + 2 * TEXTPAD;
39083913

src/plots/cartesian/axis_defaults.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -167,11 +167,11 @@ module.exports = function handleAxisDefaults(containerIn, containerOut, coerce,
167167
(axType === 'category' || isMultiCategory) &&
168168
(containerOut.ticks || containerOut.showgrid)
169169
) {
170-
var ticksonDflt;
171-
if(isMultiCategory) ticksonDflt = 'boundaries';
172-
var tickson = coerce('tickson', ticksonDflt);
173-
if(tickson === 'boundaries') {
170+
if (isMultiCategory) {
171+
coerce('tickson', 'boundaries');
174172
delete containerOut.ticklabelposition;
173+
} else { // category axis
174+
coerce('tickson');
175175
}
176176
}
177177

src/plots/cartesian/layout_attributes.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -663,12 +663,13 @@ module.exports = {
663663
dflt: 'outside',
664664
editType: 'calc',
665665
description: [
666-
'Determines where tick labels are drawn with respect to the axis',
666+
'Determines where tick labels are drawn with respect to the axis.',
667667
'Please note that',
668-
'top or bottom has no effect on x axes or when `ticklabelmode` is set to *period*.',
669-
'Similarly',
670-
'left or right has no effect on y axes or when `ticklabelmode` is set to *period*.',
671-
'Has no effect on *multicategory* axes or when `tickson` is set to *boundaries*.',
668+
'top or bottom has no effect on x axes or when `ticklabelmode` is set to *period*',
669+
'or when `tickson` is set to *boundaries*. Similarly,',
670+
'left or right has no effect on y axes or when `ticklabelmode` is set to *period*',
671+
'or when `tickson` is set to *boundaries*.',
672+
'Has no effect on *multicategory* axes.',
672673
'When used on axes linked by `matches` or `scaleanchor`,',
673674
'no extra padding for inside labels would be added by autorange,',
674675
'so that the scales could match.'
Loading
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
{
2+
"data": [
3+
{
4+
"type": "box",
5+
"x": [
6+
"day 1",
7+
"day 1",
8+
"day 1",
9+
"day 1",
10+
"day 1",
11+
"day 1",
12+
"day 2",
13+
"day 2",
14+
"day 2",
15+
"day 2",
16+
"day 2",
17+
"day 2"
18+
],
19+
"y": [0.2, 0.2, 0.6, 1, 0.5, 0.4, 0.2, 0.7, 0.9, 0.1, 0.5, 0.3]
20+
},
21+
{
22+
"type": "box",
23+
"x": [
24+
"day 1",
25+
"day 1",
26+
"day 1",
27+
"day 1",
28+
"day 1",
29+
"day 1",
30+
"day 2",
31+
"day 2",
32+
"day 2",
33+
"day 2",
34+
"day 2",
35+
"day 2"
36+
],
37+
"y": [0.1, 0.3, 0.1, 0.9, 0.6, 0.6, 0.9, 1, 0.3, 0.6, 0.8, 0.5]
38+
},
39+
{
40+
"type": "box",
41+
"x": [
42+
"day 1",
43+
"day 1",
44+
"day 1",
45+
"day 1",
46+
"day 1",
47+
"day 1",
48+
"day 2",
49+
"day 2",
50+
"day 2",
51+
"day 2",
52+
"day 2",
53+
"day 2"
54+
],
55+
"y": [0.6, 0.7, 0.3, 0.6, 0, 0.5, 0.7, 0.9, 0.5, 0.8, 0.7, 0.2]
56+
},
57+
58+
{
59+
"type": "bar",
60+
"x": [1, 2, 1],
61+
"y": ["apples", "bananas", "clementines"],
62+
"orientation": "h",
63+
"xaxis": "x2",
64+
"yaxis": "y2"
65+
},
66+
{
67+
"type": "bar",
68+
"x": [1.3, 2.2, 0.8],
69+
"y": ["apples", "bananas", "clementines"],
70+
"orientation": "h",
71+
"xaxis": "x2",
72+
"yaxis": "y2"
73+
},
74+
{
75+
"type": "bar",
76+
"x": [3, 3.2, 1.8],
77+
"y": ["apples", "bananas", "clementines"],
78+
"orientation": "h",
79+
"xaxis": "x2",
80+
"yaxis": "y2"
81+
},
82+
83+
{
84+
"type": "bar",
85+
"name": "with dtick !== 1",
86+
"x": ["a", "b", "c", "d", "e", "f", "g", "h"],
87+
"y": [1, 2, 1, 2, 1, 3, 4, 1],
88+
"xaxis": "x3",
89+
"yaxis": "y3"
90+
},
91+
92+
{
93+
"mode": "markers",
94+
"marker": { "symbol": "square" },
95+
"name": "with overlapping tick labels",
96+
"x": ["A very long title", "short", "Another very long title"],
97+
"y": [0, 10, 2],
98+
"xaxis": "x4",
99+
"yaxis": "y4"
100+
}
101+
],
102+
"layout": {
103+
"title": {
104+
"text": "Although some ticklabelpositions have a side specified,<br>all category labels are expected to be centered."
105+
},
106+
"boxmode": "group",
107+
"grid": {
108+
"rows": 4,
109+
"columns": 1,
110+
"pattern": "independent",
111+
"ygap": 0.2
112+
},
113+
"xaxis": {
114+
"ticklabelposition": "inside right",
115+
"ticks": "outside",
116+
"tickson": "boundaries",
117+
"gridcolor": "white",
118+
"gridwidth": 4
119+
},
120+
"yaxis2": {
121+
"ticks": "inside",
122+
"ticklabelposition": "inside top",
123+
"tickson": "boundaries",
124+
"gridcolor": "white",
125+
"gridwidth": 4
126+
},
127+
"xaxis3": {
128+
"ticks": "inside",
129+
"ticklabelposition": "inside left",
130+
"tickson": "boundaries",
131+
"gridcolor": "white",
132+
"gridwidth": 4,
133+
"dtick": 2
134+
},
135+
"xaxis4": {
136+
"domain": [0.22, 0.78],
137+
"ticks": "outside",
138+
"ticklabelposition": "inside",
139+
"ticklen": 20,
140+
"tickson": "boundaries",
141+
"gridcolor": "white",
142+
"gridwidth": 4
143+
},
144+
"plot_bgcolor": "lightgrey",
145+
"showlegend": false,
146+
"width": 500,
147+
"height": 800,
148+
"margin": { "b": 140 }
149+
}
150+
}

test/plot-schema.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14711,7 +14711,7 @@
1471114711
]
1471214712
},
1471314713
"ticklabelposition": {
14714-
"description": "Determines where tick labels are drawn with respect to the axis Please note that top or bottom has no effect on x axes or when `ticklabelmode` is set to *period*. Similarly left or right has no effect on y axes or when `ticklabelmode` is set to *period*. Has no effect on *multicategory* axes or when `tickson` is set to *boundaries*. When used on axes linked by `matches` or `scaleanchor`, no extra padding for inside labels would be added by autorange, so that the scales could match.",
14714+
"description": "Determines where tick labels are drawn with respect to the axis. Please note that top or bottom has no effect on x axes or when `ticklabelmode` is set to *period* or when `tickson` is set to *boundaries*. Similarly, left or right has no effect on y axes or when `ticklabelmode` is set to *period* or when `tickson` is set to *boundaries*. Has no effect on *multicategory* axes. When used on axes linked by `matches` or `scaleanchor`, no extra padding for inside labels would be added by autorange, so that the scales could match.",
1471514715
"dflt": "outside",
1471614716
"editType": "calc",
1471714717
"valType": "enumerated",
@@ -15955,7 +15955,7 @@
1595515955
]
1595615956
},
1595715957
"ticklabelposition": {
15958-
"description": "Determines where tick labels are drawn with respect to the axis Please note that top or bottom has no effect on x axes or when `ticklabelmode` is set to *period*. Similarly left or right has no effect on y axes or when `ticklabelmode` is set to *period*. Has no effect on *multicategory* axes or when `tickson` is set to *boundaries*. When used on axes linked by `matches` or `scaleanchor`, no extra padding for inside labels would be added by autorange, so that the scales could match.",
15958+
"description": "Determines where tick labels are drawn with respect to the axis. Please note that top or bottom has no effect on x axes or when `ticklabelmode` is set to *period* or when `tickson` is set to *boundaries*. Similarly, left or right has no effect on y axes or when `ticklabelmode` is set to *period* or when `tickson` is set to *boundaries*. Has no effect on *multicategory* axes. When used on axes linked by `matches` or `scaleanchor`, no extra padding for inside labels would be added by autorange, so that the scales could match.",
1595915959
"dflt": "outside",
1596015960
"editType": "calc",
1596115961
"valType": "enumerated",

0 commit comments

Comments
 (0)