diff --git a/draftlogs/7468_add.md b/draftlogs/7468_add.md new file mode 100644 index 00000000000..bd0e23a8599 --- /dev/null +++ b/draftlogs/7468_add.md @@ -0,0 +1 @@ + - Add `minorloglabels` to cartesian axes [#7468](https://github.com/plotly/plotly.js/pull/7468) diff --git a/src/plots/cartesian/axes.js b/src/plots/cartesian/axes.js index 18fff21cb40..a5cf18162df 100644 --- a/src/plots/cartesian/axes.js +++ b/src/plots/cartesian/axes.js @@ -1899,18 +1899,30 @@ function formatLog(ax, out, hover, extraPrecision, hideexp) { if(tickformat || (dtChar0 === 'L')) { out.text = numFormat(Math.pow(10, x), ax, hideexp, extraPrecision); - } else if(isNumeric(dtick) || ((dtChar0 === 'D') && (Lib.mod(x + 0.01, 1) < 0.1))) { - var p = Math.round(x); + } else if(isNumeric(dtick) || ((dtChar0 === 'D') && + (ax.minorloglabels === 'complete' || Lib.mod(x + 0.01, 1) < 0.1))) { + + var isMinor; + if(ax.minorloglabels === 'complete' && !(Lib.mod(x + 0.01, 1) < 0.1)) { + isMinor = true; + out.fontSize *= 0.75; + } + + var exponentialString = Math.pow(10, x).toExponential(0); + var parts = exponentialString.split('e'); + + var p = +parts[1]; var absP = Math.abs(p); var exponentFormat = ax.exponentformat; if(exponentFormat === 'power' || (isSIFormat(exponentFormat) && beyondSI(p))) { - if(p === 0) out.text = 1; - else if(p === 1) out.text = '10'; - else out.text = '10' + (p > 1 ? '' : MINUS_SIGN) + absP + ''; + out.text = parts[0]; + if(absP > 0) out.text += 'x10'; + if(out.text === '1x10') out.text = '10'; + if(p !== 0 && p !== 1) out.text += '' + (p > 0 ? '' : MINUS_SIGN) + absP + ''; out.fontSize *= 1.25; } else if((exponentFormat === 'e' || exponentFormat === 'E') && absP > 2) { - out.text = '1' + exponentFormat + (p > 0 ? '+' : MINUS_SIGN) + absP; + out.text = parts[0] + exponentFormat + (p > 0 ? '+' : MINUS_SIGN) + absP; } else { out.text = numFormat(Math.pow(10, x), ax, '', 'fakehover'); if(dtick === 'D1' && ax._id.charAt(0) === 'y') { @@ -1918,7 +1930,10 @@ function formatLog(ax, out, hover, extraPrecision, hideexp) { } } } else if(dtChar0 === 'D') { - out.text = String(Math.round(Math.pow(10, Lib.mod(x, 1)))); + out.text = + ax.minorloglabels === 'none' ? '' : + /* ax.minorloglabels === 'small digits' */ String(Math.round(Math.pow(10, Lib.mod(x, 1)))); + out.fontSize *= 0.75; } else throw 'unrecognized dtick ' + String(dtick); @@ -3770,7 +3785,7 @@ axes.drawLabels = function(gd, ax, opts) { var sel; if(e.K === ZERO_PATH.K) { - var zerolineLayer = zerolineIsAbove ? mainPlotinfo.zerolinelayerAbove : mainPlotinfo.zerolinelayer; + var zerolineLayer = zerolineIsAbove ? mainPlotinfo.zerolinelayerAbove : mainPlotinfo.zerolinelayer; sel = zerolineLayer.selectAll('.' + ax._id + 'zl'); } else if(e.K === MINORGRID_PATH.K) sel = mainPlotinfo.minorGridlayer.selectAll('.' + ax._id); else if(e.K === GRID_PATH.K) sel = mainPlotinfo.gridlayer.selectAll('.' + ax._id); diff --git a/src/plots/cartesian/layout_attributes.js b/src/plots/cartesian/layout_attributes.js index f1b7bbbe5d6..c8c950b5318 100644 --- a/src/plots/cartesian/layout_attributes.js +++ b/src/plots/cartesian/layout_attributes.js @@ -1136,6 +1136,19 @@ module.exports = { editType: 'ticks' }, + minorloglabels: { + valType: 'enumerated', + values: ['small digits', 'complete', 'none'], + dflt: 'small digits', + editType: 'calc', + description: [ + 'Determines how minor log labels are displayed.', + 'If *small digits*, small digits i.e. 2 or 5 are displayed.', + 'If *complete*, complete digits are displayed.', + 'If *none*, no labels are displayed.', + ].join(' ') + }, + layer: { valType: 'enumerated', values: ['above traces', 'below traces'], diff --git a/src/plots/cartesian/tick_label_defaults.js b/src/plots/cartesian/tick_label_defaults.js index e1d2bc93874..0f78d06338b 100644 --- a/src/plots/cartesian/tick_label_defaults.js +++ b/src/plots/cartesian/tick_label_defaults.js @@ -70,6 +70,10 @@ module.exports = function handleTickLabelDefaults(containerIn, containerOut, coe coerce('separatethousands'); } } + + if(!options.noMinorloglabels && axType === 'log') { + coerce('minorloglabels'); + } } }; diff --git a/src/plots/gl3d/layout/axis_defaults.js b/src/plots/gl3d/layout/axis_defaults.js index e3d71be24cb..bb001b2f6a0 100644 --- a/src/plots/gl3d/layout/axis_defaults.js +++ b/src/plots/gl3d/layout/axis_defaults.js @@ -42,6 +42,7 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, options) { data: options.data, showGrid: true, noAutotickangles: true, + noMinorloglabels: true, noTicklabelindex: true, noTickson: true, noTicklabelmode: true, diff --git a/src/plots/polar/layout_attributes.js b/src/plots/polar/layout_attributes.js index 052749af701..c4455fda691 100644 --- a/src/plots/polar/layout_attributes.js +++ b/src/plots/polar/layout_attributes.js @@ -36,6 +36,7 @@ var axisTickAttrs = overrideAll({ ticklabelstep: axesAttrs.ticklabelstep, showticklabels: axesAttrs.showticklabels, labelalias: axesAttrs.labelalias, + minorloglabels: axesAttrs.minorloglabels, showtickprefix: axesAttrs.showtickprefix, tickprefix: axesAttrs.tickprefix, showticksuffix: axesAttrs.showticksuffix, diff --git a/test/image/baselines/zz-minorloglabels.png b/test/image/baselines/zz-minorloglabels.png new file mode 100644 index 00000000000..ee6676ce45c Binary files /dev/null and b/test/image/baselines/zz-minorloglabels.png differ diff --git a/test/image/mocks/zz-minorloglabels.json b/test/image/mocks/zz-minorloglabels.json new file mode 100644 index 00000000000..bccd8eb4f64 --- /dev/null +++ b/test/image/mocks/zz-minorloglabels.json @@ -0,0 +1,86 @@ +{ + "data": [{ + "x": [0.001, 0.01, 0.1, 1, 10, 100, 1000], + "y": [0, 1, 2, 3, 4, 5, 6] + }, { + "xaxis": "x2", + "yaxis": "y2", + "x": [0.001, 0.01, 0.1, 1, 10, 100, 1000], + "y": [0, 1, 2, 3, 4, 5, 6] + }, { + "xaxis": "x3", + "yaxis": "y3", + "x": [0.001, 0.01, 0.1, 1, 10, 100, 1000], + "y": [0, 1, 2, 3, 4, 5, 6] + }, { + "xaxis": "x4", + "yaxis": "y4", + "x": [0.00001, 0.0001, 0.001, 0.01, 0.1, 1, 10, 100, 1000, 10000, 10000, 100000], + "y": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + }, { + "xaxis": "x5", + "yaxis": "y5", + "x": [0.00001, 0.0001, 0.001, 0.01, 0.1, 1, 10, 100, 1000, 10000, 10000, 100000], + "y": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + }, { + "xaxis": "x6", + "yaxis": "y6", + "x": [0.00001, 0.0001, 0.001, 0.01, 0.1, 1, 10, 100, 1000, 10000, 10000, 100000], + "y": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + }], + "layout": { + "grid": { + "rows": 7, + "columns": 1, + "ygap": 0.8, + "pattern": "independent" + }, + "xaxis": { + "title": { "text": "none" }, + "type": "log", + "minorloglabels": "none", + "minor": { "showgrid": true } + }, + "xaxis2": { + "title": { "text": "small digits" }, + "dtick": "D1", + "type": "log", + "minorloglabels": "small digits" + }, + "xaxis3": { + "title": { "text": "small digits" }, + "dtick": "D2", + "type": "log", + "minorloglabels": "small digits" + }, + "xaxis4": { + "title": { "text": "complete" }, + "dtick": "D2", + "type": "log", + "minorloglabels": "complete", + "minor": { "showgrid": true } + }, + "xaxis5": { + "title": { "text": "complete
exponentformat: 'e'" }, + "exponentformat": "e", + "dtick": "D2", + "type": "log", + "minorloglabels": "complete", + "minor": { "showgrid": true } + }, + "xaxis6": { + "title": { "text": "complete
exponentformat: 'power'" }, + "exponentformat": "power", + "dtick": "D2", + "type": "log", + "minorloglabels": "complete", + "minor": { "showgrid": true } + }, + "title": { + "text": "options of minorloglabels" + }, + "width": 1400, + "height": 1200, + "showlegend": false + } +} diff --git a/test/plot-schema.json b/test/plot-schema.json index 161815bbaf3..887cd0d65cb 100644 --- a/test/plot-schema.json +++ b/test/plot-schema.json @@ -5197,6 +5197,17 @@ "min": 0, "valType": "number" }, + "minorloglabels": { + "description": "Determines how minor log labels are displayed. If *small digits*, small digits i.e. 2 or 5 are displayed. If *complete*, complete digits are displayed. If *none*, no labels are displayed.", + "dflt": "small digits", + "editType": "plot", + "valType": "enumerated", + "values": [ + "small digits", + "complete", + "none" + ] + }, "nticks": { "description": "Specifies the maximum number of ticks for the particular axis. The actual number of ticks will be chosen automatically to be less than or equal to `nticks`. Has an effect only if `tickmode` is set to *auto*.", "dflt": 0, @@ -5894,6 +5905,17 @@ "min": 0, "valType": "number" }, + "minorloglabels": { + "description": "Determines how minor log labels are displayed. If *small digits*, small digits i.e. 2 or 5 are displayed. If *complete*, complete digits are displayed. If *none*, no labels are displayed.", + "dflt": "small digits", + "editType": "plot", + "valType": "enumerated", + "values": [ + "small digits", + "complete", + "none" + ] + }, "nticks": { "description": "Specifies the maximum number of ticks for the particular axis. The actual number of ticks will be chosen automatically to be less than or equal to `nticks`. Has an effect only if `tickmode` is set to *auto*.", "dflt": 0, @@ -13907,6 +13929,17 @@ "valType": "number" } }, + "minorloglabels": { + "description": "Determines how minor log labels are displayed. If *small digits*, small digits i.e. 2 or 5 are displayed. If *complete*, complete digits are displayed. If *none*, no labels are displayed.", + "dflt": "small digits", + "editType": "calc", + "valType": "enumerated", + "values": [ + "small digits", + "complete", + "none" + ] + }, "mirror": { "description": "Determines if the axis lines or/and ticks are mirrored to the opposite side of the plotting area. If *true*, the axis lines are mirrored. If *ticks*, the axis lines and ticks are mirrored. If *false*, mirroring is disable. If *all*, axis lines are mirrored on all shared-axes subplots. If *allticks*, axis lines and ticks are mirrored on all shared-axes subplots.", "dflt": false, @@ -15468,6 +15501,17 @@ "valType": "number" } }, + "minorloglabels": { + "description": "Determines how minor log labels are displayed. If *small digits*, small digits i.e. 2 or 5 are displayed. If *complete*, complete digits are displayed. If *none*, no labels are displayed.", + "dflt": "small digits", + "editType": "calc", + "valType": "enumerated", + "values": [ + "small digits", + "complete", + "none" + ] + }, "mirror": { "description": "Determines if the axis lines or/and ticks are mirrored to the opposite side of the plotting area. If *true*, the axis lines are mirrored. If *ticks*, the axis lines and ticks are mirrored. If *false*, mirroring is disable. If *all*, axis lines are mirrored on all shared-axes subplots. If *allticks*, axis lines and ticks are mirrored on all shared-axes subplots.", "dflt": false,