Skip to content

Commit 98097ea

Browse files
authored
Merge pull request #5121 from ignamv/engineering_exponentformat
Add `minexponent` attribute to control usage of SI prefixes in axis ticks
2 parents abbabe4 + 99b2769 commit 98097ea

File tree

12 files changed

+85
-1
lines changed

12 files changed

+85
-1
lines changed

src/components/colorbar/attributes.js

+1
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ module.exports = overrideAll({
173173
showticksuffix: axesAttrs.showticksuffix,
174174
separatethousands: axesAttrs.separatethousands,
175175
exponentformat: axesAttrs.exponentformat,
176+
minexponent: axesAttrs.minexponent,
176177
showexponent: axesAttrs.showexponent,
177178
title: {
178179
text: {

src/components/colorbar/draw.js

+1
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,7 @@ function mockColorBarAxis(gd, opts, zrange) {
683683
tickangle: opts.tickangle,
684684
tickformat: opts.tickformat,
685685
exponentformat: opts.exponentformat,
686+
minexponent: opts.minexponent,
686687
separatethousands: opts.separatethousands,
687688
showexponent: opts.showexponent,
688689
showtickprefix: opts.showtickprefix,

src/plots/cartesian/axes.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -1103,7 +1103,8 @@ function autoTickRound(ax) {
11031103

11041104
var maxend = Math.max(Math.abs(rng[0]), Math.abs(rng[1]));
11051105
var rangeexp = Math.floor(Math.log(maxend) / Math.LN10 + 0.01);
1106-
if(Math.abs(rangeexp) > 3) {
1106+
var minexponent = ax.minexponent === undefined ? 3 : ax.minexponent;
1107+
if(Math.abs(rangeexp) > minexponent) {
11071108
if(isSIFormat(ax.exponentformat) && !beyondSI(rangeexp)) {
11081109
ax._tickexponent = 3 * Math.round((rangeexp - 1) / 3);
11091110
} else ax._tickexponent = rangeexp;
@@ -1586,6 +1587,7 @@ function numFormat(v, ax, fmtoverride, hover) {
15861587
// make a dummy axis obj to get the auto rounding and exponent
15871588
var ah = {
15881589
exponentformat: exponentFormat,
1590+
minexponent: ax.minexponent,
15891591
dtick: ax.showexponent === 'none' ? ax.dtick :
15901592
(isNumeric(v) ? Math.abs(v) || 1 : 1),
15911593
// if not showing any exponents, don't change the exponent

src/plots/cartesian/layout_attributes.js

+11
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,17 @@ module.exports = {
680680
'If *B*, 1B.'
681681
].join(' ')
682682
},
683+
minexponent: {
684+
valType: 'number',
685+
dflt: 3,
686+
min: 0,
687+
role: 'style',
688+
editType: 'ticks',
689+
description: [
690+
'Hide SI prefix for 10^n if |n| is below this number.',
691+
'This only has an effect when `tickformat` is *SI* or *B*.'
692+
].join(' ')
693+
},
683694
separatethousands: {
684695
valType: 'boolean',
685696
dflt: false,

src/plots/cartesian/tick_label_defaults.js

+1
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ function handleOtherDefaults(containerIn, containerOut, coerce, axType, options)
7272
if(!tickFormat && axType !== 'date') {
7373
coerce('showexponent', showAttrDflt);
7474
coerce('exponentformat');
75+
coerce('minexponent');
7576
coerce('separatethousands');
7677
}
7778
}

src/plots/gl3d/layout/axis_attributes.js

+1
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ module.exports = overrideAll({
108108
showticksuffix: axesAttrs.showticksuffix,
109109
showexponent: axesAttrs.showexponent,
110110
exponentformat: axesAttrs.exponentformat,
111+
minexponent: axesAttrs.minexponent,
111112
separatethousands: axesAttrs.separatethousands,
112113
tickformat: axesAttrs.tickformat,
113114
tickformatstops: axesAttrs.tickformatstops,

src/plots/polar/layout_attributes.js

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ var axisTickAttrs = overrideAll({
4747
ticksuffix: axesAttrs.ticksuffix,
4848
showexponent: axesAttrs.showexponent,
4949
exponentformat: axesAttrs.exponentformat,
50+
minexponent: axesAttrs.minexponent,
5051
separatethousands: axesAttrs.separatethousands,
5152
tickfont: axesAttrs.tickfont,
5253
tickangle: axesAttrs.tickangle,

src/plots/ternary/layout_attributes.js

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ var ternaryAxesAttrs = {
4040
ticksuffix: axesAttrs.ticksuffix,
4141
showexponent: axesAttrs.showexponent,
4242
exponentformat: axesAttrs.exponentformat,
43+
minexponent: axesAttrs.minexponent,
4344
separatethousands: axesAttrs.separatethousands,
4445
tickfont: axesAttrs.tickfont,
4546
tickangle: axesAttrs.tickangle,

src/traces/carpet/axis_attributes.js

+10
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,16 @@ module.exports = {
284284
'If *B*, 1B.'
285285
].join(' ')
286286
},
287+
minexponent: {
288+
valType: 'number',
289+
dflt: 3,
290+
min: 0,
291+
role: 'style',
292+
editType: 'calc',
293+
description: [
294+
'Hide SI prefix for 10^n if |n| is below this number'
295+
].join(' ')
296+
},
287297
separatethousands: {
288298
valType: 'boolean',
289299
dflt: false,

src/traces/carpet/axis_defaults.js

+2
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ module.exports = function handleAxisDefaults(containerIn, containerOut, options)
7878
coerce('separatethousands');
7979
coerce('tickformat');
8080
coerce('exponentformat');
81+
coerce('minexponent');
8182
coerce('showexponent');
8283
coerce('categoryorder');
8384

@@ -186,6 +187,7 @@ module.exports = function handleAxisDefaults(containerIn, containerOut, options)
186187
delete containerOut.tickangle;
187188
delete containerOut.showexponent;
188189
delete containerOut.exponentformat;
190+
delete containerOut.minexponent;
189191
delete containerOut.tickformat;
190192
delete containerOut.showticksuffix;
191193
delete containerOut.showtickprefix;

src/traces/indicator/attributes.js

+1
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,7 @@ module.exports = {
355355
showticksuffix: axesAttrs.showticksuffix,
356356
separatethousands: axesAttrs.separatethousands,
357357
exponentformat: axesAttrs.exponentformat,
358+
minexponent: axesAttrs.minexponent,
358359
showexponent: axesAttrs.showexponent,
359360
editType: 'plot'
360361
}, 'plot'),

test/jasmine/tests/axes_test.js

+52
Original file line numberDiff line numberDiff line change
@@ -2851,6 +2851,58 @@ describe('Test axes', function() {
28512851
]);
28522852
});
28532853

2854+
it('Does not use SI prefixes for 10^n with |n| < minexponent', function() {
2855+
var textOut = mockCalc({
2856+
type: 'log',
2857+
tickmode: 'linear',
2858+
exponentformat: 'SI',
2859+
minexponent: 5,
2860+
showexponent: 'all',
2861+
tick0: 0,
2862+
dtick: 1,
2863+
range: [-18.5, 18.5]
2864+
});
2865+
2866+
expect(textOut).toEqual([
2867+
'10<sup>\u221218</sup>',
2868+
'10<sup>\u221217</sup>',
2869+
'10<sup>\u221216</sup>',
2870+
'1f', '10f', '100f', '1p', '10p', '100p', '1n', '10n', '100n',
2871+
'1μ', '0.00001', '0.0001', '0.001', '0.01', '0.1', '1', '10', '100',
2872+
'1000', '10,000', '100,000', '1M', '10M', '100M', '1G', '10G', '100G',
2873+
'1T', '10T', '100T',
2874+
'10<sup>15</sup>',
2875+
'10<sup>16</sup>',
2876+
'10<sup>17</sup>',
2877+
'10<sup>18</sup>'
2878+
]);
2879+
2880+
textOut = mockCalc({
2881+
type: 'log',
2882+
tickmode: 'linear',
2883+
exponentformat: 'SI',
2884+
minexponent: 0,
2885+
showexponent: 'all',
2886+
tick0: 0,
2887+
dtick: 1,
2888+
range: [-18.5, 18.5]
2889+
});
2890+
2891+
expect(textOut).toEqual([
2892+
'10<sup>\u221218</sup>',
2893+
'10<sup>\u221217</sup>',
2894+
'10<sup>\u221216</sup>',
2895+
'1f', '10f', '100f', '1p', '10p', '100p', '1n', '10n', '100n',
2896+
'1μ', '10μ', '100μ', '1m', '10m', '100m', '1', '10', '100',
2897+
'1k', '10k', '100k', '1M', '10M', '100M', '1G', '10G', '100G',
2898+
'1T', '10T', '100T',
2899+
'10<sup>15</sup>',
2900+
'10<sup>16</sup>',
2901+
'10<sup>17</sup>',
2902+
'10<sup>18</sup>'
2903+
]);
2904+
});
2905+
28542906
it('supports e/E format on log axes', function() {
28552907
['e', 'E'].forEach(function(e) {
28562908
var textOut = mockCalc({

0 commit comments

Comments
 (0)