Skip to content

Commit 296dbfb

Browse files
authored
Merge pull request plotly#5584 from plotly/ticklabeloverflow
Implement ticklabeloverflow to improve control over display of tick labels
2 parents 963f362 + 0deec98 commit 296dbfb

23 files changed

+293
-56
lines changed

src/components/colorbar/attributes.js

+7
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,13 @@ module.exports = overrideAll({
136136
tickvals: axesAttrs.tickvals,
137137
ticktext: axesAttrs.ticktext,
138138
ticks: extendFlat({}, axesAttrs.ticks, {dflt: ''}),
139+
ticklabeloverflow: extendFlat({}, axesAttrs.ticklabeloverflow, {
140+
description: [
141+
'Determines how we handle tick labels that would overflow either the graph div or the domain of the axis.',
142+
'The default value for inside tick labels is *hide past domain*.',
143+
'In other cases the default is *hide past div*.'
144+
].join(' ')
145+
}),
139146
ticklabelposition: {
140147
valType: 'enumerated',
141148
values: [

src/components/colorbar/defaults.js

+2
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ module.exports = function colorbarDefaults(containerIn, containerOut, layout) {
4242
coerce('bordercolor');
4343
coerce('borderwidth');
4444
coerce('bgcolor');
45+
4546
var ticklabelposition = coerce('ticklabelposition');
47+
coerce('ticklabeloverflow', ticklabelposition.indexOf('inside') !== -1 ? 'hide past domain' : 'hide past div');
4648

4749
handleTickValueDefaults(colorbarIn, colorbarOut, coerce, 'linear');
4850

src/components/colorbar/draw.js

+1
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,7 @@ function mockColorBarAxis(gd, opts, zrange) {
677677
tickcolor: opts.tickcolor,
678678
showticklabels: opts.showticklabels,
679679
ticklabelposition: opts.ticklabelposition,
680+
ticklabeloverflow: opts.ticklabeloverflow,
680681
tickfont: opts.tickfont,
681682
tickangle: opts.tickangle,
682683
tickformat: opts.tickformat,

src/plots/cartesian/axes.js

+58-52
Original file line numberDiff line numberDiff line change
@@ -3020,8 +3020,6 @@ axes.drawLabels = function(gd, ax, opts) {
30203020
}
30213021

30223022
function positionLabels(s, angle) {
3023-
var isInside = insideTicklabelposition(ax);
3024-
30253023
s.each(function(d) {
30263024
var thisLabel = d3.select(this);
30273025
var mathjaxGroup = thisLabel.select('.text-math-group');
@@ -3049,12 +3047,10 @@ axes.drawLabels = function(gd, ax, opts) {
30493047
'text-anchor': anchor
30503048
});
30513049

3052-
if(isInside) {
3053-
thisText.style('opacity', 1); // visible
3050+
thisText.style('opacity', 1); // visible
30543051

3055-
if(ax._hideOutOfRangeInsideTickLabels) {
3056-
ax._hideOutOfRangeInsideTickLabels();
3057-
}
3052+
if(ax._adjustTickLabelsOverflow) {
3053+
ax._adjustTickLabelsOverflow();
30583054
}
30593055
} else {
30603056
var mjWidth = Drawing.bBox(mathjaxGroup.node()).width;
@@ -3064,63 +3060,73 @@ axes.drawLabels = function(gd, ax, opts) {
30643060
});
30653061
}
30663062

3067-
ax._hideOutOfRangeInsideTickLabels = function() {
3068-
if(insideTicklabelposition(ax)) {
3063+
ax._adjustTickLabelsOverflow = function() {
3064+
var ticklabeloverflow = ax.ticklabeloverflow;
3065+
if(!ticklabeloverflow || ticklabeloverflow === 'allow') return;
3066+
3067+
var hideOverflow = ticklabeloverflow.indexOf('hide') !== -1;
3068+
3069+
var isX = ax._id.charAt(0) === 'x';
3070+
// div positions
3071+
var p0 = 0;
3072+
var p1 = isX ?
3073+
gd._fullLayout.width :
3074+
gd._fullLayout.height;
3075+
3076+
if(ticklabeloverflow.indexOf('domain') !== -1) {
3077+
// domain positions
30693078
var rl = Lib.simpleMap(ax.range, ax.r2l);
3079+
p0 = ax.l2p(rl[0]) + ax._offset;
3080+
p1 = ax.l2p(rl[1]) + ax._offset;
3081+
}
30703082

3071-
// hide inside tick labels that go outside axis end points
3072-
var p0 = ax.l2p(rl[0]);
3073-
var p1 = ax.l2p(rl[1]);
3083+
var min = Math.min(p0, p1);
3084+
var max = Math.max(p0, p1);
30743085

3075-
var min = Math.min(p0, p1) + ax._offset;
3076-
var max = Math.max(p0, p1) + ax._offset;
3086+
var side = ax.side;
30773087

3078-
var side = ax.side;
3079-
var isX = ax._id.charAt(0) === 'x';
3088+
var visibleLabelMin = Infinity;
3089+
var visibleLabelMax = -Infinity;
30803090

3081-
var visibleLabelMin = Infinity;
3082-
var visibleLabelMax = -Infinity;
3091+
tickLabels.each(function(d) {
3092+
var thisLabel = d3.select(this);
3093+
var mathjaxGroup = thisLabel.select('.text-math-group');
30833094

3084-
tickLabels.each(function(d) {
3085-
var thisLabel = d3.select(this);
3086-
var mathjaxGroup = thisLabel.select('.text-math-group');
3087-
3088-
if(mathjaxGroup.empty()) {
3089-
var bb = Drawing.bBox(thisLabel.node());
3090-
var hide = false;
3091-
if(isX) {
3092-
if(bb.right > max) hide = true;
3093-
else if(bb.left < min) hide = true;
3095+
if(mathjaxGroup.empty()) {
3096+
var bb = Drawing.bBox(thisLabel.node());
3097+
var adjust = 0;
3098+
if(isX) {
3099+
if(bb.right > max) adjust = 1;
3100+
else if(bb.left < min) adjust = 1;
3101+
} else {
3102+
if(bb.bottom > max) adjust = 1;
3103+
else if(bb.top + (ax.tickangle ? 0 : d.fontSize / 4) < min) adjust = 1;
3104+
}
3105+
3106+
var t = thisLabel.select('text');
3107+
if(adjust) {
3108+
if(hideOverflow) t.style('opacity', 0); // hidden
3109+
} else {
3110+
t.style('opacity', 1); // visible
3111+
3112+
if(side === 'bottom' || side === 'right') {
3113+
visibleLabelMin = Math.min(visibleLabelMin, isX ? bb.top : bb.left);
30943114
} else {
3095-
if(bb.bottom > max) hide = true;
3096-
else if(bb.top + (ax.tickangle ? 0 : d.fontSize / 4) < min) hide = true;
3115+
visibleLabelMin = -Infinity;
30973116
}
30983117

3099-
var t = thisLabel.select('text');
3100-
if(hide) {
3101-
t.style('opacity', 0); // hidden
3118+
if(side === 'top' || side === 'left') {
3119+
visibleLabelMax = Math.max(visibleLabelMax, isX ? bb.bottom : bb.right);
31023120
} else {
3103-
t.style('opacity', 1); // visible
3104-
3105-
if(side === 'bottom' || side === 'right') {
3106-
visibleLabelMin = Math.min(visibleLabelMin, isX ? bb.top : bb.left);
3107-
} else {
3108-
visibleLabelMin = -Infinity;
3109-
}
3110-
3111-
if(side === 'top' || side === 'left') {
3112-
visibleLabelMax = Math.max(visibleLabelMax, isX ? bb.bottom : bb.right);
3113-
} else {
3114-
visibleLabelMax = Infinity;
3115-
}
3121+
visibleLabelMax = Infinity;
31163122
}
3117-
} // TODO: hide mathjax?
3118-
});
3123+
}
3124+
} // TODO: hide mathjax?
3125+
});
31193126

3120-
if(ax._anchorAxis) {
3121-
ax._anchorAxis._visibleLabelMin = visibleLabelMin;
3122-
ax._anchorAxis._visibleLabelMax = visibleLabelMax;
3123-
}
3127+
if(ax._anchorAxis) {
3128+
ax._anchorAxis._visibleLabelMin = visibleLabelMin;
3129+
ax._anchorAxis._visibleLabelMax = visibleLabelMax;
31243130
}
31253131
};
31263132

src/plots/cartesian/axis_defaults.js

+13-1
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,9 @@ module.exports = function handleAxisDefaults(containerIn, containerOut, coerce,
5656
}
5757
}
5858

59+
var ticklabelposition = '';
5960
if(!options.noTicklabelposition || axType === 'multicategory') {
60-
Lib.coerce(containerIn, containerOut, {
61+
ticklabelposition = Lib.coerce(containerIn, containerOut, {
6162
ticklabelposition: {
6263
valType: 'enumerated',
6364
dflt: 'outside',
@@ -75,6 +76,17 @@ module.exports = function handleAxisDefaults(containerIn, containerOut, coerce,
7576
}, 'ticklabelposition');
7677
}
7778

79+
if(!options.noTicklabeloverflow) {
80+
coerce('ticklabeloverflow',
81+
ticklabelposition.indexOf('inside') !== -1 ?
82+
'hide past domain' :
83+
axType === 'category' ||
84+
axType === 'multicategory' ?
85+
'allow' :
86+
'hide past div'
87+
);
88+
}
89+
7890
setConvert(containerOut, layoutOut);
7991

8092
var autorangeDflt = !containerOut.isValidRange(containerIn.range);

src/plots/cartesian/layout_attributes.js

+15
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,21 @@ module.exports = {
495495
'so that the scales could match.'
496496
].join(' ')
497497
},
498+
ticklabeloverflow: {
499+
valType: 'enumerated',
500+
values: [
501+
'allow',
502+
'hide past div',
503+
'hide past domain'
504+
],
505+
editType: 'calc',
506+
description: [
507+
'Determines how we handle tick labels that would overflow either the graph div or the domain of the axis.',
508+
'The default value for inside tick labels is *hide past domain*.',
509+
'Otherwise on *category* and *multicategory* axes the default is *allow*.',
510+
'In other cases the default is *hide past div*.'
511+
].join(' ')
512+
},
498513
mirror: {
499514
valType: 'enumerated',
500515
values: [true, 'ticks', false, 'all', 'allticks'],

src/plots/gl3d/layout/axis_defaults.js

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, options) {
4444
noTickson: true,
4545
noTicklabelmode: true,
4646
noTicklabelposition: true,
47+
noTicklabeloverflow: true,
4748
bgColor: options.bgColor,
4849
calendar: options.calendar
4950
},

src/plots/plots.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -2076,14 +2076,14 @@ plots.doAutoMargin = function(gd) {
20762076
}
20772077
}
20782078

2079-
hideInsideTickLabels(gd);
2079+
refineTicks(gd);
20802080
};
20812081

2082-
function hideInsideTickLabels(gd) {
2082+
function refineTicks(gd) {
20832083
var axList = axisIDs.list(gd, '', true);
20842084

20852085
[
2086-
'_hideOutOfRangeInsideTickLabels',
2086+
'_adjustTickLabelsOverflow',
20872087
'_hideCounterAxisInsideTickLabels'
20882088
].forEach(function(k) {
20892089
for(var i = 0; i < axList.length; i++) {

src/traces/indicator/plot.js

+1
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@ function drawAngularGauge(gd, plotGroup, cd, opts) {
394394
ax.type = 'linear';
395395
ax.range = trace.gauge.axis.range;
396396
ax._id = 'xangularaxis'; // or 'y', but I don't think this makes a difference here
397+
ax.ticklabeloverflow = 'allow';
397398
ax.setScale();
398399

399400
// 't'ick to 'g'eometric radians is used all over the place here
-274 Bytes
Loading
10.6 KB
Loading
9.93 KB
Loading
9.2 KB
Loading
13.3 KB
Loading
12.3 KB
Loading
11.7 KB
Loading
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"data": [{
3+
"x": [-100, 0, 100],
4+
"y": [-100, 0, 100]
5+
}],
6+
"layout": {
7+
"xaxis": {
8+
"range": [-115, 105],
9+
"tickformat": ".3f",
10+
"ticklabeloverflow": "allow"
11+
},
12+
"yaxis": {
13+
"range": [-115, 105],
14+
"tickangle": 90,
15+
"tickformat": ".3f",
16+
"ticklabeloverflow": "allow"
17+
},
18+
"plot_bgcolor": "lightblue",
19+
"showlegend": false,
20+
"width": 300,
21+
"height": 300,
22+
"margin": {
23+
"t": 15,
24+
"b": 15,
25+
"l": 15,
26+
"r": 15
27+
}
28+
}
29+
}
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"data": [{
3+
"x": [-100, 0, 100],
4+
"y": [-100, 0, 100]
5+
}],
6+
"layout": {
7+
"xaxis": {
8+
"range": [-115, 105],
9+
"tickformat": ".3f",
10+
"ticklabeloverflow": "hide past div"
11+
},
12+
"yaxis": {
13+
"range": [-115, 105],
14+
"tickangle": 90,
15+
"tickformat": ".3f",
16+
"ticklabeloverflow": "hide past div"
17+
},
18+
"plot_bgcolor": "lightblue",
19+
"showlegend": false,
20+
"width": 300,
21+
"height": 300,
22+
"margin": {
23+
"t": 15,
24+
"b": 15,
25+
"l": 15,
26+
"r": 15
27+
}
28+
}
29+
}
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"data": [{
3+
"x": [-100, 0, 100],
4+
"y": [-100, 0, 100]
5+
}],
6+
"layout": {
7+
"xaxis": {
8+
"range": [-115, 105],
9+
"tickformat": ".3f",
10+
"ticklabeloverflow": "hide past domain"
11+
},
12+
"yaxis": {
13+
"range": [-115, 105],
14+
"tickangle": 90,
15+
"tickformat": ".3f",
16+
"ticklabeloverflow": "hide past domain"
17+
},
18+
"plot_bgcolor": "lightblue",
19+
"showlegend": false,
20+
"width": 300,
21+
"height": 300,
22+
"margin": {
23+
"t": 30,
24+
"b": 30,
25+
"l": 30,
26+
"r": 30
27+
}
28+
}
29+
}
+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"data": [{
3+
"colorbar": {
4+
"dtick": 2,
5+
"ticklen": 4,
6+
"tickangle": 90,
7+
"tickformat": ".4f",
8+
"ticklabeloverflow": "allow"
9+
},
10+
"type": "heatmap",
11+
"x": [-100, 0, 100],
12+
"y": [-100, 0, 100],
13+
"z": [
14+
[0, 5, 10],
15+
[5, 10, 0],
16+
[10, 5, 0]
17+
]
18+
}],
19+
"layout": {
20+
"plot_bgcolor": "lightblue",
21+
"showlegend": false,
22+
"width": 200,
23+
"height": 300,
24+
"margin": {
25+
"t": 5,
26+
"b": 5,
27+
"l": 45,
28+
"r": 45
29+
}
30+
}
31+
}

0 commit comments

Comments
 (0)