Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add minexponent attribute to control usage of SI prefixes in axis ticks #5121

Merged
merged 15 commits into from
Sep 26, 2020
Merged
1 change: 1 addition & 0 deletions src/components/colorbar/attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ module.exports = overrideAll({
showticksuffix: axesAttrs.showticksuffix,
separatethousands: axesAttrs.separatethousands,
exponentformat: axesAttrs.exponentformat,
minexponent: axesAttrs.minexponent,
showexponent: axesAttrs.showexponent,
title: {
text: {
Expand Down
4 changes: 3 additions & 1 deletion src/plots/cartesian/axes.js
Original file line number Diff line number Diff line change
Expand Up @@ -1042,7 +1042,8 @@ function autoTickRound(ax) {

var maxend = Math.max(Math.abs(rng[0]), Math.abs(rng[1]));
var rangeexp = Math.floor(Math.log(maxend) / Math.LN10 + 0.01);
if(Math.abs(rangeexp) > 3) {
var minexponent = ax.minexponent === undefined ? 3 : ax.minexponent;
if(Math.abs(rangeexp) > minexponent) {
if(isSIFormat(ax.exponentformat) && !beyondSI(rangeexp)) {
ax._tickexponent = 3 * Math.round((rangeexp - 1) / 3);
} else ax._tickexponent = rangeexp;
Expand Down Expand Up @@ -1525,6 +1526,7 @@ function numFormat(v, ax, fmtoverride, hover) {
// make a dummy axis obj to get the auto rounding and exponent
var ah = {
exponentformat: exponentFormat,
minexponent: ax.minexponent,
dtick: ax.showexponent === 'none' ? ax.dtick :
(isNumeric(v) ? Math.abs(v) || 1 : 1),
// if not showing any exponents, don't change the exponent
Expand Down
10 changes: 10 additions & 0 deletions src/plots/cartesian/layout_attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,16 @@ module.exports = {
'If *B*, 1B.'
].join(' ')
},
minexponent: {
valType: 'number',
dflt: 3,
min: 0,
role: 'style',
editType: 'ticks',
description: [
'Hide SI prefix for 10^n if |n| is below this number'
].join(' ')
},
separatethousands: {
valType: 'boolean',
dflt: false,
Expand Down
1 change: 1 addition & 0 deletions src/plots/cartesian/tick_label_defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ function handleOtherDefaults(containerIn, containerOut, coerce, axType, options)
if(!tickFormat && axType !== 'date') {
coerce('showexponent', showAttrDflt);
coerce('exponentformat');
coerce('minexponent');
coerce('separatethousands');
}
}
Expand Down
1 change: 1 addition & 0 deletions src/plots/gl3d/layout/axis_attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ module.exports = overrideAll({
showticksuffix: axesAttrs.showticksuffix,
showexponent: axesAttrs.showexponent,
exponentformat: axesAttrs.exponentformat,
minexponent: axesAttrs.minexponent,
separatethousands: axesAttrs.separatethousands,
tickformat: axesAttrs.tickformat,
tickformatstops: axesAttrs.tickformatstops,
Expand Down
1 change: 1 addition & 0 deletions src/plots/polar/layout_attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ var axisTickAttrs = overrideAll({
ticksuffix: axesAttrs.ticksuffix,
showexponent: axesAttrs.showexponent,
exponentformat: axesAttrs.exponentformat,
minexponent: axesAttrs.minexponent,
separatethousands: axesAttrs.separatethousands,
tickfont: axesAttrs.tickfont,
tickangle: axesAttrs.tickangle,
Expand Down
1 change: 1 addition & 0 deletions src/plots/ternary/layout_attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ var ternaryAxesAttrs = {
ticksuffix: axesAttrs.ticksuffix,
showexponent: axesAttrs.showexponent,
exponentformat: axesAttrs.exponentformat,
minexponent: axesAttrs.minexponent,
separatethousands: axesAttrs.separatethousands,
tickfont: axesAttrs.tickfont,
tickangle: axesAttrs.tickangle,
Expand Down
10 changes: 10 additions & 0 deletions src/traces/carpet/axis_attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,16 @@ module.exports = {
'If *B*, 1B.'
].join(' ')
},
minexponent: {
valType: 'number',
dflt: 3,
min: 0,
role: 'style',
editType: 'calc',
description: [
'Hide SI prefix for 10^n if |n| is below this number'
].join(' ')
},
separatethousands: {
valType: 'boolean',
dflt: false,
Expand Down
2 changes: 2 additions & 0 deletions src/traces/carpet/axis_defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ module.exports = function handleAxisDefaults(containerIn, containerOut, options)
coerce('separatethousands');
coerce('tickformat');
coerce('exponentformat');
coerce('minexponent');
coerce('showexponent');
coerce('categoryorder');

Expand Down Expand Up @@ -186,6 +187,7 @@ module.exports = function handleAxisDefaults(containerIn, containerOut, options)
delete containerOut.tickangle;
delete containerOut.showexponent;
delete containerOut.exponentformat;
delete containerOut.minexponent;
delete containerOut.tickformat;
delete containerOut.showticksuffix;
delete containerOut.showtickprefix;
Expand Down
1 change: 1 addition & 0 deletions src/traces/indicator/attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ module.exports = {
showticksuffix: axesAttrs.showticksuffix,
separatethousands: axesAttrs.separatethousands,
exponentformat: axesAttrs.exponentformat,
minexponent: axesAttrs.minexponent,
showexponent: axesAttrs.showexponent,
editType: 'plot'
}, 'plot'),
Expand Down
55 changes: 55 additions & 0 deletions test/jasmine/tests/axes_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2722,6 +2722,9 @@ describe('Test axes', function() {

describe('calcTicks and tickText', function() {
function mockCalc(ax) {
if(ax.minexponent === undefined) {
ax.minexponent = 3;
}
ax.tickfont = {};
Axes.setConvert(ax, {separators: '.,', _extraFormat: {
year: '%Y',
Expand Down Expand Up @@ -2851,6 +2854,58 @@ describe('Test axes', function() {
]);
});

it('Does not use SI prefixes for 10^n with |n| < minexponent', function() {
var textOut = mockCalc({
type: 'log',
tickmode: 'linear',
exponentformat: 'SI',
minexponent: 5,
showexponent: 'all',
tick0: 0,
dtick: 1,
range: [-18.5, 18.5]
});

expect(textOut).toEqual([
'10<sup>\u221218</sup>',
'10<sup>\u221217</sup>',
'10<sup>\u221216</sup>',
'1f', '10f', '100f', '1p', '10p', '100p', '1n', '10n', '100n',
'1μ', '0.00001', '0.0001', '0.001', '0.01', '0.1', '1', '10', '100',
'1000', '10,000', '100,000', '1M', '10M', '100M', '1G', '10G', '100G',
'1T', '10T', '100T',
'10<sup>15</sup>',
'10<sup>16</sup>',
'10<sup>17</sup>',
'10<sup>18</sup>'
]);

textOut = mockCalc({
type: 'log',
tickmode: 'linear',
exponentformat: 'SI',
minexponent: 0,
showexponent: 'all',
tick0: 0,
dtick: 1,
range: [-18.5, 18.5]
});

expect(textOut).toEqual([
'10<sup>\u221218</sup>',
'10<sup>\u221217</sup>',
'10<sup>\u221216</sup>',
'1f', '10f', '100f', '1p', '10p', '100p', '1n', '10n', '100n',
'1μ', '10μ', '100μ', '1m', '10m', '100m', '1', '10', '100',
'1k', '10k', '100k', '1M', '10M', '100M', '1G', '10G', '100G',
'1T', '10T', '100T',
'10<sup>15</sup>',
'10<sup>16</sup>',
'10<sup>17</sup>',
'10<sup>18</sup>'
]);
});

it('supports e/E format on log axes', function() {
['e', 'E'].forEach(function(e) {
var textOut = mockCalc({
Expand Down