From cbac3aec591790ebd78b185108d52ae3170cf54f Mon Sep 17 00:00:00 2001 From: archmoj Date: Thu, 29 Oct 2020 11:50:37 -0400 Subject: [PATCH 01/25] issue 5195 - implement convertnumeric for axes and inherit from layout --- src/plots/cartesian/axes.js | 4 +++- src/plots/cartesian/axis_autotype.js | 18 +++++++++++------- src/plots/cartesian/layout_attributes.js | 12 +++++++++++- src/plots/cartesian/layout_defaults.js | 4 ++++ src/plots/cartesian/type_defaults.js | 3 +++ src/plots/gl3d/layout/axis_attributes.js | 1 + src/plots/gl3d/layout/defaults.js | 2 ++ src/plots/layout_attributes.js | 10 ++++++++++ src/plots/plots.js | 2 ++ src/plots/polar/layout_attributes.js | 1 + src/plots/polar/layout_defaults.js | 10 +++++++--- src/plots/ternary/layout_defaults.js | 1 + src/traces/box/defaults.js | 9 +++++++-- src/traces/carpet/axis_attributes.js | 3 ++- src/traces/carpet/axis_defaults.js | 5 ++++- src/traces/sunburst/attributes.js | 4 ++-- test/jasmine/tests/axes_test.js | 1 + 17 files changed, 72 insertions(+), 18 deletions(-) diff --git a/src/plots/cartesian/axes.js b/src/plots/cartesian/axes.js index 099848120ac..dae8555cb83 100644 --- a/src/plots/cartesian/axes.js +++ b/src/plots/cartesian/axes.js @@ -216,7 +216,9 @@ var getDataConversions = axes.getDataConversions = function(gd, trace, target, t // setup the data-to-calc method. if(Array.isArray(d2cTarget)) { ax = { - type: autoType(targetArray), + type: autoType(targetArray, undefined, { + convertNumeric: gd._fullLayout.axesconvertnumeric + }), _categories: [] }; axes.setConvert(ax); diff --git a/src/plots/cartesian/axis_autotype.js b/src/plots/cartesian/axis_autotype.js index 2cfd9707013..c482373c3ea 100644 --- a/src/plots/cartesian/axis_autotype.js +++ b/src/plots/cartesian/axis_autotype.js @@ -15,22 +15,26 @@ var Lib = require('../../lib'); var BADNUM = require('../../constants/numerical').BADNUM; module.exports = function autoType(array, calendar, opts) { - opts = opts || {}; + var convertNumeric = opts.convertNumeric; if(!opts.noMultiCategory && multiCategory(array)) return 'multicategory'; - if(moreDates(array, calendar)) return 'date'; + if(moreDates(array, calendar, convertNumeric)) return 'date'; if(category(array)) return 'category'; - if(linearOK(array)) return 'linear'; + if(linearOK(array, convertNumeric)) return 'linear'; else return '-'; }; +function hasTypeNumber(v, convertNumeric) { + return convertNumeric ? isNumeric(v) : typeof v === 'number'; +} + // is there at least one number in array? If not, we should leave // ax.type empty so it can be autoset later -function linearOK(array) { +function linearOK(array, convertNumeric) { if(!array) return false; for(var i = 0; i < array.length; i++) { - if(isNumeric(array[i])) return true; + if(hasTypeNumber(array[i], convertNumeric)) return true; } return false; @@ -42,7 +46,7 @@ function linearOK(array) { // dates as non-dates, to exclude cases with mostly 2 & 4 digit // numbers and a few dates // as with categories, consider DISTINCT values only. -function moreDates(a, calendar) { +function moreDates(a, calendar, convertNumeric) { // test at most 1000 points, evenly spaced var inc = Math.max(1, (a.length - 1) / 1000); var dcnt = 0; @@ -56,7 +60,7 @@ function moreDates(a, calendar) { seen[stri] = 1; if(Lib.isDateTime(ai, calendar)) dcnt += 1; - if(isNumeric(ai)) ncnt += 1; + if(hasTypeNumber(ai, convertNumeric)) ncnt += 1; } return (dcnt > ncnt * 2); diff --git a/src/plots/cartesian/layout_attributes.js b/src/plots/cartesian/layout_attributes.js index d62b424256a..d08233547b5 100644 --- a/src/plots/cartesian/layout_attributes.js +++ b/src/plots/cartesian/layout_attributes.js @@ -97,11 +97,21 @@ module.exports = { _noTemplating: true, description: [ 'Sets the axis type.', - 'By default, plotly attempts to determined the axis type', + 'By default, plotly.js attempts to determined the axis type', 'by looking into the data of the traces that referenced', 'the axis in question.' ].join(' ') }, + convertnumeric: { + valType: 'boolean', + role: 'info', + editType: 'calc', + description: [ + 'Determines whether or not a numeric string in this axis may be', + 'treated as a number during automatic axis `type` detection.', + 'Defaults to layout.axesconvertnumeric.' + ].join(' ') + }, autorange: { valType: 'enumerated', values: [true, false, 'reversed'], diff --git a/src/plots/cartesian/layout_defaults.js b/src/plots/cartesian/layout_defaults.js index 3e411ae0574..26dd164ce01 100644 --- a/src/plots/cartesian/layout_defaults.js +++ b/src/plots/cartesian/layout_defaults.js @@ -38,6 +38,8 @@ function appendList(cont, k, item) { } module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) { + var convertnumericDflt = layoutOut.axesconvertnumeric; + var ax2traces = {}; var xaMayHide = {}; var yaMayHide = {}; @@ -246,6 +248,7 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) { automargin: true, visibleDflt: visibleDflt, reverseDflt: reverseDflt, + convertnumericDflt: convertnumericDflt, splomStash: ((layoutOut._splomAxes || {})[axLetter] || {})[axId] }; @@ -310,6 +313,7 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) { automargin: true, visibleDflt: false, reverseDflt: false, + convertnumericDflt: convertnumericDflt, splomStash: ((layoutOut._splomAxes || {})[axLetter] || {})[axId] }; diff --git a/src/plots/cartesian/type_defaults.js b/src/plots/cartesian/type_defaults.js index f9d73cd3663..44968ee2db2 100644 --- a/src/plots/cartesian/type_defaults.js +++ b/src/plots/cartesian/type_defaults.js @@ -16,6 +16,7 @@ var autoType = require('./axis_autotype'); * name: axis object name (ie 'xaxis') if one should be stored */ module.exports = function handleTypeDefaults(containerIn, containerOut, coerce, options) { + coerce('convertnumeric', options.convertnumericDflt); var axType = coerce('type', (options.splomStash || {}).type); if(axType === '-') { @@ -68,6 +69,8 @@ function setAutoType(ax, data) { opts.noMultiCategory = true; } + opts.convertNumeric = ax.convertnumeric; + // check all boxes on this x axis to see // if they're dates, numbers, or categories if(isBoxWithoutPositionCoords(d0, axLetter)) { diff --git a/src/plots/gl3d/layout/axis_attributes.js b/src/plots/gl3d/layout/axis_attributes.js index 76081cc764f..ed2ac11be0d 100644 --- a/src/plots/gl3d/layout/axis_attributes.js +++ b/src/plots/gl3d/layout/axis_attributes.js @@ -78,6 +78,7 @@ module.exports = overrideAll({ type: extendFlat({}, axesAttrs.type, { values: ['-', 'linear', 'log', 'date', 'category'] }), + convertnumeric: axesAttrs.convertnumeric, autorange: axesAttrs.autorange, rangemode: axesAttrs.rangemode, range: extendFlat({}, axesAttrs.range, { diff --git a/src/plots/gl3d/layout/defaults.js b/src/plots/gl3d/layout/defaults.js index dd4c3eca2ce..b4042f881ef 100644 --- a/src/plots/gl3d/layout/defaults.js +++ b/src/plots/gl3d/layout/defaults.js @@ -40,6 +40,7 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) { font: layoutOut.font, fullData: fullData, getDfltFromLayout: getDfltFromLayout, + convertnumericDflt: layoutOut.axesconvertnumeric, paper_bgcolor: layoutOut.paper_bgcolor, calendar: layoutOut.calendar }); @@ -109,6 +110,7 @@ function handleGl3dDefaults(sceneLayoutIn, sceneLayoutOut, coerce, opts) { data: fullGl3dData, bgColor: bgColorCombined, calendar: opts.calendar, + convertnumericDflt: opts.convertnumericDflt, fullLayout: opts.fullLayout }); diff --git a/src/plots/layout_attributes.js b/src/plots/layout_attributes.js index e7b9191182f..de206d56ea6 100644 --- a/src/plots/layout_attributes.js +++ b/src/plots/layout_attributes.js @@ -292,6 +292,16 @@ module.exports = { 'Sets the background color of the plotting area in-between x and y axes.' ].join(' ') }, + axesconvertnumeric: { + valType: 'boolean', + dflt: true, + role: 'info', + editType: 'calc', + description: [ + 'Determines whether or not a numeric string in axes of the plot may be', + 'treated as a number during automatic axis `type` detection.' + ].join(' ') + }, separators: { valType: 'string', role: 'style', diff --git a/src/plots/plots.js b/src/plots/plots.js index c28b8f3df72..39471e6f4cb 100644 --- a/src/plots/plots.js +++ b/src/plots/plots.js @@ -1476,6 +1476,8 @@ plots.supplyLayoutGlobalDefaults = function(layoutIn, layoutOut, formatObj) { layoutOut._dataTemplate = template.data; } + coerce('axesconvertnumeric'); + var globalFont = Lib.coerceFont(coerce, 'font'); coerce('title.text', layoutOut._dfltTitle.plot); diff --git a/src/plots/polar/layout_attributes.js b/src/plots/polar/layout_attributes.js index c9cf34ecf29..84be18a950b 100644 --- a/src/plots/polar/layout_attributes.js +++ b/src/plots/polar/layout_attributes.js @@ -61,6 +61,7 @@ var radialAxisAttrs = { type: extendFlat({}, axesAttrs.type, { values: ['-', 'linear', 'log', 'date', 'category'] }), + convertnumeric: axesAttrs.convertnumeric, autorange: extendFlat({}, axesAttrs.autorange, {editType: 'plot'}), rangemode: { diff --git a/src/plots/polar/layout_defaults.js b/src/plots/polar/layout_defaults.js index f751ad9cef8..3fa227116a3 100644 --- a/src/plots/polar/layout_defaults.js +++ b/src/plots/polar/layout_defaults.js @@ -57,7 +57,7 @@ function handleDefaults(contIn, contOut, coerce, opts) { axOut._traceIndices = subplotData.map(function(t) { return t._expandedIndex; }); var dataAttr = constants.axisName2dataArray[axName]; - var axType = handleAxisTypeDefaults(axIn, axOut, coerceAxis, subplotData, dataAttr); + var axType = handleAxisTypeDefaults(axIn, axOut, coerceAxis, subplotData, dataAttr, opts.convertnumericDflt); handleCategoryOrderDefaults(axIn, axOut, coerceAxis, { axData: subplotData, @@ -187,7 +187,8 @@ function handleDefaults(contIn, contOut, coerce, opts) { } } -function handleAxisTypeDefaults(axIn, axOut, coerce, subplotData, dataAttr) { +function handleAxisTypeDefaults(axIn, axOut, coerce, subplotData, dataAttr, options) { + var convertnumeric = dataAttr.convertnumeric ? coerce('convertnumeric', options.convertnumericDflt) : false; var axType = coerce('type'); if(axType === '-') { @@ -201,7 +202,9 @@ function handleAxisTypeDefaults(axIn, axOut, coerce, subplotData, dataAttr) { } if(trace && trace[dataAttr]) { - axOut.type = autoType(trace[dataAttr], 'gregorian'); + axOut.type = autoType(trace[dataAttr], 'gregorian', { + convertNumeric: !convertnumeric + }); } if(axOut.type === '-') { @@ -224,6 +227,7 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) { attributes: layoutAttributes, handleDefaults: handleDefaults, font: layoutOut.font, + convertnumericDflt: layoutOut.axesconvertnumeric, paper_bgcolor: layoutOut.paper_bgcolor, fullData: fullData, layoutOut: layoutOut diff --git a/src/plots/ternary/layout_defaults.js b/src/plots/ternary/layout_defaults.js index 54fd942a2cd..b48b2b8750b 100644 --- a/src/plots/ternary/layout_defaults.js +++ b/src/plots/ternary/layout_defaults.js @@ -27,6 +27,7 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) { attributes: layoutAttributes, handleDefaults: handleTernaryDefaults, font: layoutOut.font, + convertnumericDflt: layoutOut.axesconvertnumeric, paper_bgcolor: layoutOut.paper_bgcolor }); }; diff --git a/src/traces/box/defaults.js b/src/traces/box/defaults.js index 849a3d433da..a2a5faabf2e 100644 --- a/src/traces/box/defaults.js +++ b/src/traces/box/defaults.js @@ -109,6 +109,11 @@ function handleSampleDefaults(traceIn, traceOut, coerce, layout) { var yLen = yDims && Lib.minRowLength(y); var xLen = xDims && Lib.minRowLength(x); + var calendar = null; // TODO: should we use ax.calendar here? + var opts = { + convertNumeric: true // TODO: should we use ax.convertnumeric here? + }; + var defaultOrientation, len; if(traceOut._hasPreCompStats) { switch(String(xDims) + String(yDims)) { @@ -160,7 +165,7 @@ function handleSampleDefaults(traceIn, traceOut, coerce, layout) { var hasCategories = false; var i; for(i = 0; i < x.length; i++) { - if(autoType(x[i]) === 'category') { + if(autoType(x[i], calendar, opts) === 'category') { hasCategories = true; break; } @@ -171,7 +176,7 @@ function handleSampleDefaults(traceIn, traceOut, coerce, layout) { len = Math.min(sLen, xLen, y.length); } else { for(i = 0; i < y.length; i++) { - if(autoType(y[i]) === 'category') { + if(autoType(y[i], calendar, opts) === 'category') { hasCategories = true; break; } diff --git a/src/traces/carpet/axis_attributes.js b/src/traces/carpet/axis_attributes.js index a6e1ea53cfb..5dd573e1edf 100644 --- a/src/traces/carpet/axis_attributes.js +++ b/src/traces/carpet/axis_attributes.js @@ -83,11 +83,12 @@ module.exports = { editType: 'calc', description: [ 'Sets the axis type.', - 'By default, plotly attempts to determined the axis type', + 'By default, plotly.js attempts to determined the axis type', 'by looking into the data of the traces that referenced', 'the axis in question.' ].join(' ') }, + convertnumeric: axesAttrs.convertnumeric, autorange: { valType: 'enumerated', values: [true, false, 'reversed'], diff --git a/src/traces/carpet/axis_defaults.js b/src/traces/carpet/axis_defaults.js index f6ae5e36344..5b0162c25c4 100644 --- a/src/traces/carpet/axis_defaults.js +++ b/src/traces/carpet/axis_defaults.js @@ -51,6 +51,7 @@ module.exports = function handleAxisDefaults(containerIn, containerOut, options) } // now figure out type and do some more initialization + coerce('convertnumeric', options.convertnumericDflt); var axType = coerce('type'); if(axType === '-') { if(options.data) setAutoType(containerOut, options.data); @@ -219,5 +220,7 @@ function setAutoType(ax, data) { var calAttr = axLetter + 'calendar'; var calendar = ax[calAttr]; - ax.type = autoType(data, calendar); + ax.type = autoType(data, calendar, { + convertNumeric: ax.convertnumeric + }); } diff --git a/src/traces/sunburst/attributes.js b/src/traces/sunburst/attributes.js index d8d3949a4f7..08dd2ad2c21 100644 --- a/src/traces/sunburst/attributes.js +++ b/src/traces/sunburst/attributes.js @@ -34,7 +34,7 @@ module.exports = { 'Empty string items \'\' are understood to reference', 'the root node in the hierarchy.', 'If `ids` is filled, `parents` items are understood to be "ids" themselves.', - 'When `ids` is not set, plotly attempts to find matching items in `labels`,', + 'When `ids` is not set, plotly.js attempts to find matching items in `labels`,', 'but beware they must be unique.' ].join(' ') }, @@ -83,7 +83,7 @@ module.exports = { description: [ 'Sets the level from which this trace hierarchy is rendered.', 'Set `level` to `\'\'` to start from the root node in the hierarchy.', - 'Must be an "id" if `ids` is filled in, otherwise plotly attempts to find a matching', + 'Must be an "id" if `ids` is filled in, otherwise plotly.js attempts to find a matching', 'item in `labels`.' ].join(' ') }, diff --git a/test/jasmine/tests/axes_test.js b/test/jasmine/tests/axes_test.js index 7a135ba11c0..f50b88a734d 100644 --- a/test/jasmine/tests/axes_test.js +++ b/test/jasmine/tests/axes_test.js @@ -190,6 +190,7 @@ describe('Test axes', function() { beforeEach(function() { layoutOut = { + axesconvertnumeric: true, _has: Plots._hasPlotType, _basePlotModules: [], _dfltTitle: {x: 'x', y: 'y'}, From c4224f4cf376c888d5f7fc20420f90bf51cbb5ed Mon Sep 17 00:00:00 2001 From: archmoj Date: Fri, 30 Oct 2020 09:29:59 -0400 Subject: [PATCH 02/25] adjust autoType return when convertNumeric is disabled - add tests --- src/plots/cartesian/axis_autotype.js | 2 +- test/jasmine/tests/axes_test.js | 40 ++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/plots/cartesian/axis_autotype.js b/src/plots/cartesian/axis_autotype.js index c482373c3ea..c7aca874bd7 100644 --- a/src/plots/cartesian/axis_autotype.js +++ b/src/plots/cartesian/axis_autotype.js @@ -21,7 +21,7 @@ module.exports = function autoType(array, calendar, opts) { if(moreDates(array, calendar, convertNumeric)) return 'date'; if(category(array)) return 'category'; if(linearOK(array, convertNumeric)) return 'linear'; - else return '-'; + else return convertNumeric ? '-' : 'category'; }; function hasTypeNumber(v, convertNumeric) { diff --git a/test/jasmine/tests/axes_test.js b/test/jasmine/tests/axes_test.js index f50b88a734d..05714c834d8 100644 --- a/test/jasmine/tests/axes_test.js +++ b/test/jasmine/tests/axes_test.js @@ -336,6 +336,46 @@ describe('Test axes', function() { }); }); + describe('autotype disable/enable converting numeric strings', function() { + it('should disable converting numeric strings using axis.convertnumeric', function() { + layoutIn = { + xaxis: {}, + yaxis: { convertnumeric: false } + }; + + supplyLayoutDefaults(layoutIn, layoutOut, [{ + type: 'scatter', + xaxis: 'x', + yaxis: 'y', + x: ['0', '1'], + y: ['0', '1'] + }]); + + expect(layoutOut.xaxis.type).toBe('linear'); + expect(layoutOut.yaxis.type).toBe('category'); + }); + + it('should enable converting numeric strings using axis.convertnumeric and inherit defaults from layout.axesconvertnumeric', function() { + layoutOut.axesconvertnumeric = false; + + layoutIn = { + xaxis: { convertnumeric: true }, + yaxis: {} + }; + + supplyLayoutDefaults(layoutIn, layoutOut, [{ + type: 'scatter', + xaxis: 'x', + yaxis: 'y', + x: ['0', '1'], + y: ['0', '1'] + }]); + + expect(layoutOut.xaxis.type).toBe('linear'); + expect(layoutOut.yaxis.type).toBe('category'); + }); + }); + it('should set undefined linewidth/linecolor if linewidth, linecolor or showline is not supplied', function() { layoutIn = { xaxis: {}, From 3b1dd0f58ca665696fa72e725ea98e64f621d007 Mon Sep 17 00:00:00 2001 From: archmoj Date: Fri, 30 Oct 2020 10:43:05 -0400 Subject: [PATCH 03/25] fixups and add polar tests --- src/plots/cartesian/axis_autotype.js | 6 ++-- src/plots/polar/layout_attributes.js | 1 + src/plots/polar/layout_defaults.js | 6 ++-- src/traces/box/defaults.js | 2 +- test/jasmine/tests/axes_test.js | 12 ++++--- test/jasmine/tests/polar_test.js | 51 ++++++++++++++++++++++++++++ 6 files changed, 67 insertions(+), 11 deletions(-) diff --git a/src/plots/cartesian/axis_autotype.js b/src/plots/cartesian/axis_autotype.js index c7aca874bd7..8dbc6ab1bf4 100644 --- a/src/plots/cartesian/axis_autotype.js +++ b/src/plots/cartesian/axis_autotype.js @@ -18,7 +18,7 @@ module.exports = function autoType(array, calendar, opts) { var convertNumeric = opts.convertNumeric; if(!opts.noMultiCategory && multiCategory(array)) return 'multicategory'; - if(moreDates(array, calendar, convertNumeric)) return 'date'; + if(convertNumeric && moreDates(array, calendar)) return 'date'; if(category(array)) return 'category'; if(linearOK(array, convertNumeric)) return 'linear'; else return convertNumeric ? '-' : 'category'; @@ -46,7 +46,7 @@ function linearOK(array, convertNumeric) { // dates as non-dates, to exclude cases with mostly 2 & 4 digit // numbers and a few dates // as with categories, consider DISTINCT values only. -function moreDates(a, calendar, convertNumeric) { +function moreDates(a, calendar) { // test at most 1000 points, evenly spaced var inc = Math.max(1, (a.length - 1) / 1000); var dcnt = 0; @@ -60,7 +60,7 @@ function moreDates(a, calendar, convertNumeric) { seen[stri] = 1; if(Lib.isDateTime(ai, calendar)) dcnt += 1; - if(hasTypeNumber(ai, convertNumeric)) ncnt += 1; + if(isNumeric(ai)) ncnt += 1; } return (dcnt > ncnt * 2); diff --git a/src/plots/polar/layout_attributes.js b/src/plots/polar/layout_attributes.js index 84be18a950b..76e71f16f07 100644 --- a/src/plots/polar/layout_attributes.js +++ b/src/plots/polar/layout_attributes.js @@ -180,6 +180,7 @@ var angularAxisAttrs = { 'If *category, use `period` to set the number of integer coordinates around polar axis.' ].join(' ') }, + convertnumeric: axesAttrs.convertnumeric, categoryorder: axesAttrs.categoryorder, categoryarray: axesAttrs.categoryarray, diff --git a/src/plots/polar/layout_defaults.js b/src/plots/polar/layout_defaults.js index 3fa227116a3..71176afe87c 100644 --- a/src/plots/polar/layout_defaults.js +++ b/src/plots/polar/layout_defaults.js @@ -57,7 +57,7 @@ function handleDefaults(contIn, contOut, coerce, opts) { axOut._traceIndices = subplotData.map(function(t) { return t._expandedIndex; }); var dataAttr = constants.axisName2dataArray[axName]; - var axType = handleAxisTypeDefaults(axIn, axOut, coerceAxis, subplotData, dataAttr, opts.convertnumericDflt); + var axType = handleAxisTypeDefaults(axIn, axOut, coerceAxis, subplotData, dataAttr, opts); handleCategoryOrderDefaults(axIn, axOut, coerceAxis, { axData: subplotData, @@ -188,7 +188,7 @@ function handleDefaults(contIn, contOut, coerce, opts) { } function handleAxisTypeDefaults(axIn, axOut, coerce, subplotData, dataAttr, options) { - var convertnumeric = dataAttr.convertnumeric ? coerce('convertnumeric', options.convertnumericDflt) : false; + var convertnumeric = coerce('convertnumeric', options.convertnumericDflt); var axType = coerce('type'); if(axType === '-') { @@ -203,7 +203,7 @@ function handleAxisTypeDefaults(axIn, axOut, coerce, subplotData, dataAttr, opti if(trace && trace[dataAttr]) { axOut.type = autoType(trace[dataAttr], 'gregorian', { - convertNumeric: !convertnumeric + convertNumeric: convertnumeric }); } diff --git a/src/traces/box/defaults.js b/src/traces/box/defaults.js index a2a5faabf2e..2ae935aa395 100644 --- a/src/traces/box/defaults.js +++ b/src/traces/box/defaults.js @@ -109,7 +109,7 @@ function handleSampleDefaults(traceIn, traceOut, coerce, layout) { var yLen = yDims && Lib.minRowLength(y); var xLen = xDims && Lib.minRowLength(x); - var calendar = null; // TODO: should we use ax.calendar here? + var calendar = 'gregorian'; // TODO: should we use ax.calendar here? var opts = { convertNumeric: true // TODO: should we use ax.convertnumeric here? }; diff --git a/test/jasmine/tests/axes_test.js b/test/jasmine/tests/axes_test.js index 05714c834d8..0cee49282cb 100644 --- a/test/jasmine/tests/axes_test.js +++ b/test/jasmine/tests/axes_test.js @@ -347,10 +347,12 @@ describe('Test axes', function() { type: 'scatter', xaxis: 'x', yaxis: 'y', - x: ['0', '1'], - y: ['0', '1'] + x: ['0', '1', '1970', '2000'], + y: ['0', '1', '1970', '2000'] }]); + expect(layoutOut.xaxis.convertnumeric).toBe(true); + expect(layoutOut.yaxis.convertnumeric).toBe(false); expect(layoutOut.xaxis.type).toBe('linear'); expect(layoutOut.yaxis.type).toBe('category'); }); @@ -367,10 +369,12 @@ describe('Test axes', function() { type: 'scatter', xaxis: 'x', yaxis: 'y', - x: ['0', '1'], - y: ['0', '1'] + x: ['0', '1', '1970', '2000'], + y: ['0', '1', '1970', '2000'] }]); + expect(layoutOut.xaxis.convertnumeric).toBe(true); + expect(layoutOut.yaxis.convertnumeric).toBe(false); expect(layoutOut.xaxis.type).toBe('linear'); expect(layoutOut.yaxis.type).toBe('category'); }); diff --git a/test/jasmine/tests/polar_test.js b/test/jasmine/tests/polar_test.js index 4262b87e41d..3e568ff8538 100644 --- a/test/jasmine/tests/polar_test.js +++ b/test/jasmine/tests/polar_test.js @@ -74,6 +74,7 @@ describe('Test polar plots defaults:', function() { }]; layoutOut = { + axesconvertnumeric: true, font: {color: 'red'}, _subplots: {polar: ['polar']} }; @@ -209,6 +210,56 @@ describe('Test polar plots defaults:', function() { expect(layoutOut.polar.radialaxis.hoverformat).toBe('g'); expect(layoutOut.polar.angularaxis.hoverformat).toBe('g'); }); + + it('should disable converting numeric strings using axis.convertnumeric', function() { + _supply({ + polar: { + radialaxis: { + convertnumeric: false + }, + angularaxis: { + convertnumeric: false + } + } + }, [{ + visible: true, + type: 'scatterpolar', + r: ['0', '1', '1970', '2000'], + theta: ['0', '1', '1970', '2000'], + subplot: 'polar' + }]); + + expect(layoutOut.polar.angularaxis.convertnumeric).toBe(false); + expect(layoutOut.polar.radialaxis.convertnumeric).toBe(false); + expect(layoutOut.polar.radialaxis.type).toBe('category'); + expect(layoutOut.polar.angularaxis.type).toBe('category'); + }); + + it('should enable converting numeric strings using axis.convertnumeric and inherit defaults from layout.axesconvertnumeric', function() { + layoutOut.axesconvertnumeric = false; + + _supply({ + polar: { + radialaxis: { + convertnumeric: true + }, + angularaxis: { + convertnumeric: true + } + } + }, [{ + visible: true, + type: 'scatterpolar', + r: ['0', '1', '1970', '2000'], + theta: ['0', '1', '1970', '2000'], + subplot: 'polar' + }]); + + expect(layoutOut.polar.angularaxis.convertnumeric).toBe(true); + expect(layoutOut.polar.radialaxis.convertnumeric).toBe(true); + expect(layoutOut.polar.radialaxis.type).toBe('linear'); + expect(layoutOut.polar.angularaxis.type).toBe('linear'); + }); }); describe('Test relayout on polar subplots:', function() { From 48fabdde481b9e8152cd94ba8c9f32f2f78f7cc6 Mon Sep 17 00:00:00 2001 From: archmoj Date: Fri, 30 Oct 2020 11:27:36 -0400 Subject: [PATCH 04/25] add gl3d tests --- test/jasmine/tests/gl3dlayout_test.js | 65 ++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/test/jasmine/tests/gl3dlayout_test.js b/test/jasmine/tests/gl3dlayout_test.js index 06232dab190..bbdc0b76099 100644 --- a/test/jasmine/tests/gl3dlayout_test.js +++ b/test/jasmine/tests/gl3dlayout_test.js @@ -26,7 +26,9 @@ describe('Test gl3d axes defaults', function() { }; beforeEach(function() { - layoutOut = {}; + layoutOut = { + axesconvertnumeric: true + }; }); it('should define specific default set with empty initial layout', function() { @@ -128,6 +130,7 @@ describe('Test Gl3d layout defaults', function() { beforeEach(function() { layoutOut = { + axesconvertnumeric: true, _basePlotModules: ['gl3d'], _dfltTitle: {x: 'xxx', y: 'yyy', colorbar: 'cbbb'}, _subplots: {gl3d: ['scene']} @@ -380,6 +383,66 @@ describe('Test Gl3d layout defaults', function() { expect(layoutOut.scene.zaxis.gridcolor) .toEqual(tinycolor.mix('#444', bgColor, frac).toRgbString()); }); + + it('should disable converting numeric strings using axis.convertnumeric', function() { + supplyLayoutDefaults({ + scene: { + xaxis: { + convertnumeric: false + }, + yaxis: { + convertnumeric: false + }, + zaxis: { + convertnumeric: false + } + } + }, layoutOut, [{ + type: 'scatter3d', + x: ['0', '1', '1970', '2000'], + y: ['0', '1', '1970', '2000'], + z: ['0', '1', '1970', '2000'], + scene: 'scene' + }]); + + expect(layoutOut.scene.xaxis.convertnumeric).toBe(false); + expect(layoutOut.scene.yaxis.convertnumeric).toBe(false); + expect(layoutOut.scene.zaxis.convertnumeric).toBe(false); + expect(layoutOut.scene.xaxis.type).toBe('category'); + expect(layoutOut.scene.yaxis.type).toBe('category'); + expect(layoutOut.scene.zaxis.type).toBe('category'); + }); + + it('should enable converting numeric strings using axis.convertnumeric and inherit defaults from layout.axesconvertnumeric', function() { + layoutOut.axesconvertnumeric = false; + + supplyLayoutDefaults({ + scene: { + xaxis: { + convertnumeric: true + }, + yaxis: { + convertnumeric: true + }, + zaxis: { + convertnumeric: true + } + } + }, layoutOut, [{ + type: 'scatter3d', + x: ['0', '1', '1970', '2000'], + y: ['0', '1', '1970', '2000'], + z: ['0', '1', '1970', '2000'], + scene: 'scene' + }]); + + expect(layoutOut.scene.xaxis.convertnumeric).toBe(true); + expect(layoutOut.scene.yaxis.convertnumeric).toBe(true); + expect(layoutOut.scene.zaxis.convertnumeric).toBe(true); + expect(layoutOut.scene.xaxis.type).toBe('linear'); + expect(layoutOut.scene.yaxis.type).toBe('linear'); + expect(layoutOut.scene.zaxis.type).toBe('linear'); + }); }); }); From 5aca807623c6cc56ef3956009ba7aa5f7096d651 Mon Sep 17 00:00:00 2001 From: archmoj Date: Fri, 30 Oct 2020 13:56:11 -0400 Subject: [PATCH 05/25] add box plot tests an improve gl3d tests --- test/jasmine/tests/box_test.js | 80 +++++++++++++++++++++++++++ test/jasmine/tests/gl3dlayout_test.js | 44 ++++++--------- 2 files changed, 96 insertions(+), 28 deletions(-) diff --git a/test/jasmine/tests/box_test.js b/test/jasmine/tests/box_test.js index 9ea11d6b406..06f0838e717 100644 --- a/test/jasmine/tests/box_test.js +++ b/test/jasmine/tests/box_test.js @@ -636,6 +636,86 @@ describe('Test boxes supplyDefaults', function() { }); }); +describe('Test box converting numeric strings', function() { + it('should disable converting numeric strings using axis.convertnumeric', function() { + var gd = { + layout: { + xaxis: { + convertnumeric: false + } + }, + data: [{ + type: 'box', + x: ['3', '0', '1', '2'], + + xaxis: 'x', + lowerfence: ['0', '0', '0', '0'], + q1: ['0.5', '1', '1.5', '2'], + median: ['1', '2', '3', '4'], + q3: ['1.5', '3', '4.5', '6'], + upperfence: ['2', '4', '6', '8'], + }] + }; + + supplyAllDefaults(gd); + + expect(gd._fullLayout.xaxis.convertnumeric).toBe(false); + expect(gd._fullLayout.xaxis.type).toBe('category'); + }); + + it('should enable converting numeric strings using axis.convertnumeric', function() { + var gd = { + layout: { + axesconvertnumeric: false, + xaxis: { + convertnumeric: true + } + }, + data: [{ + type: 'box', + x: ['3', '0', '1', '2'], + + xaxis: 'x', + lowerfence: ['0', '0', '0', '0'], + q1: ['0.5', '1', '1.5', '2'], + median: ['1', '2', '3', '4'], + q3: ['1.5', '3', '4.5', '6'], + upperfence: ['2', '4', '6', '8'], + }] + }; + + supplyAllDefaults(gd); + + expect(gd._fullLayout.xaxis.convertnumeric).toBe(true); + expect(gd._fullLayout.xaxis.type).toBe('linear'); + }); + + it('should enable converting numeric inherit defaults from layout.axesconvertnumeric', function() { + var gd = { + layout: { + axesconvertnumeric: false, + xaxis: {} + }, + data: [{ + type: 'box', + x: ['3', '0', '1', '2'], + + xaxis: 'x', + lowerfence: ['0', '0', '0', '0'], + q1: ['0.5', '1', '1.5', '2'], + median: ['1', '2', '3', '4'], + q3: ['1.5', '3', '4.5', '6'], + upperfence: ['2', '4', '6', '8'], + }] + }; + + supplyAllDefaults(gd); + + expect(gd._fullLayout.xaxis.convertnumeric).toBe(false); + expect(gd._fullLayout.xaxis.type).toBe('category'); + }); +}); + describe('Test box hover:', function() { var gd; diff --git a/test/jasmine/tests/gl3dlayout_test.js b/test/jasmine/tests/gl3dlayout_test.js index bbdc0b76099..2bdb01c26f5 100644 --- a/test/jasmine/tests/gl3dlayout_test.js +++ b/test/jasmine/tests/gl3dlayout_test.js @@ -387,29 +387,23 @@ describe('Test Gl3d layout defaults', function() { it('should disable converting numeric strings using axis.convertnumeric', function() { supplyLayoutDefaults({ scene: { - xaxis: { - convertnumeric: false - }, - yaxis: { - convertnumeric: false - }, - zaxis: { - convertnumeric: false - } + xaxis: { convertnumeric: false }, + yaxis: {}, + zaxis: { convertnumeric: false } } }, layoutOut, [{ type: 'scatter3d', - x: ['0', '1', '1970', '2000'], - y: ['0', '1', '1970', '2000'], - z: ['0', '1', '1970', '2000'], + x: ['1970', '2000', '0', '1'], + y: ['1970', '2000', '0', '1'], + z: ['1970', '2000', '0', '1'], scene: 'scene' }]); expect(layoutOut.scene.xaxis.convertnumeric).toBe(false); - expect(layoutOut.scene.yaxis.convertnumeric).toBe(false); + expect(layoutOut.scene.yaxis.convertnumeric).toBe(true); expect(layoutOut.scene.zaxis.convertnumeric).toBe(false); expect(layoutOut.scene.xaxis.type).toBe('category'); - expect(layoutOut.scene.yaxis.type).toBe('category'); + expect(layoutOut.scene.yaxis.type).toBe('linear'); expect(layoutOut.scene.zaxis.type).toBe('category'); }); @@ -418,29 +412,23 @@ describe('Test Gl3d layout defaults', function() { supplyLayoutDefaults({ scene: { - xaxis: { - convertnumeric: true - }, - yaxis: { - convertnumeric: true - }, - zaxis: { - convertnumeric: true - } + xaxis: { convertnumeric: true }, + yaxis: {}, + zaxis: { convertnumeric: true } } }, layoutOut, [{ type: 'scatter3d', - x: ['0', '1', '1970', '2000'], - y: ['0', '1', '1970', '2000'], - z: ['0', '1', '1970', '2000'], + x: ['1970', '2000', '0', '1'], + y: ['1970', '2000', '0', '1'], + z: ['1970', '2000', '0', '1'], scene: 'scene' }]); expect(layoutOut.scene.xaxis.convertnumeric).toBe(true); - expect(layoutOut.scene.yaxis.convertnumeric).toBe(true); + expect(layoutOut.scene.yaxis.convertnumeric).toBe(false); expect(layoutOut.scene.zaxis.convertnumeric).toBe(true); expect(layoutOut.scene.xaxis.type).toBe('linear'); - expect(layoutOut.scene.yaxis.type).toBe('linear'); + expect(layoutOut.scene.yaxis.type).toBe('category'); expect(layoutOut.scene.zaxis.type).toBe('linear'); }); }); From 84907dcd2472060f2c2ec8f3bc7436e914f86a94 Mon Sep 17 00:00:00 2001 From: archmoj Date: Fri, 30 Oct 2020 14:30:21 -0400 Subject: [PATCH 06/25] add tests for carpet --- test/jasmine/tests/box_test.js | 10 ++----- test/jasmine/tests/carpet_test.js | 49 +++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 7 deletions(-) diff --git a/test/jasmine/tests/box_test.js b/test/jasmine/tests/box_test.js index 06f0838e717..d91d55e23d8 100644 --- a/test/jasmine/tests/box_test.js +++ b/test/jasmine/tests/box_test.js @@ -636,13 +636,11 @@ describe('Test boxes supplyDefaults', function() { }); }); -describe('Test box converting numeric strings', function() { +describe('Test box autoType', function() { it('should disable converting numeric strings using axis.convertnumeric', function() { var gd = { layout: { - xaxis: { - convertnumeric: false - } + xaxis: { convertnumeric: false } }, data: [{ type: 'box', @@ -667,9 +665,7 @@ describe('Test box converting numeric strings', function() { var gd = { layout: { axesconvertnumeric: false, - xaxis: { - convertnumeric: true - } + xaxis: { convertnumeric: true } }, data: [{ type: 'box', diff --git a/test/jasmine/tests/carpet_test.js b/test/jasmine/tests/carpet_test.js index 8bf0aab5033..d32fa075799 100644 --- a/test/jasmine/tests/carpet_test.js +++ b/test/jasmine/tests/carpet_test.js @@ -217,6 +217,55 @@ describe('supplyDefaults visibility check', function() { }); }); +describe('Test carpet autoType', function() { + it('should disable converting numeric strings using axis.convertnumeric', function() { + var gd = { + layout: { + xaxis: { convertnumeric: false }, + yaxis: {} + }, + data: [{ + type: 'carpet', + a: ['1', '2', '3'], + b: ['1', '2'], + x: [['1', '2', '3'], ['4', '5', '6']], + y: [['1', '2', '3'], ['4', '5', '6']], + }] + }; + + supplyAllDefaults(gd); + + expect(gd._fullLayout.xaxis.convertnumeric).toBe(false); + expect(gd._fullLayout.yaxis.convertnumeric).toBe(true); + expect(gd._fullLayout.xaxis.type).toBe('category'); + expect(gd._fullLayout.yaxis.type).toBe('linear'); + }); + + it('should enable converting numeric strings using axis.convertnumeric and inherit defaults from layout.axesconvertnumeric', function() { + var gd = { + layout: { + axesconvertnumeric: false, + xaxis: { convertnumeric: true }, + yaxis: {} + }, + data: [{ + type: 'carpet', + a: ['1', '2', '3'], + b: ['1', '2'], + x: [['1', '2', '3'], ['4', '5', '6']], + y: [['1', '2', '3'], ['4', '5', '6']], + }] + }; + + supplyAllDefaults(gd); + + expect(gd._fullLayout.xaxis.convertnumeric).toBe(true); + expect(gd._fullLayout.yaxis.convertnumeric).toBe(false); + expect(gd._fullLayout.xaxis.type).toBe('linear'); + expect(gd._fullLayout.yaxis.type).toBe('category'); + }); +}); + describe('carpet smooth_fill_2d_array', function() { var _; From 04da8a1a3910cfed688cb9130b30479d241a707d Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi <33888540+archmoj@users.noreply.github.com> Date: Mon, 2 Nov 2020 17:02:43 -0500 Subject: [PATCH 07/25] Update src/plots/cartesian/layout_attributes.js Co-authored-by: Alex Johnson --- src/plots/cartesian/layout_attributes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plots/cartesian/layout_attributes.js b/src/plots/cartesian/layout_attributes.js index d08233547b5..7eb9016a034 100644 --- a/src/plots/cartesian/layout_attributes.js +++ b/src/plots/cartesian/layout_attributes.js @@ -107,7 +107,7 @@ module.exports = { role: 'info', editType: 'calc', description: [ - 'Determines whether or not a numeric string in this axis may be', + 'Determines whether or not a numeric string in data for this axis may be', 'treated as a number during automatic axis `type` detection.', 'Defaults to layout.axesconvertnumeric.' ].join(' ') From 01115cde1c1af755798f787d8fcc0a3321a61772 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi <33888540+archmoj@users.noreply.github.com> Date: Mon, 2 Nov 2020 17:03:34 -0500 Subject: [PATCH 08/25] Update src/plots/layout_attributes.js Co-authored-by: Alex Johnson --- src/plots/layout_attributes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plots/layout_attributes.js b/src/plots/layout_attributes.js index de206d56ea6..38973883842 100644 --- a/src/plots/layout_attributes.js +++ b/src/plots/layout_attributes.js @@ -298,7 +298,7 @@ module.exports = { role: 'info', editType: 'calc', description: [ - 'Determines whether or not a numeric string in axes of the plot may be', + 'Determines whether or not a numeric string in trace data may be', 'treated as a number during automatic axis `type` detection.' ].join(' ') }, From fb67c82a00661713e42ac885e406139f71f63b13 Mon Sep 17 00:00:00 2001 From: archmoj Date: Tue, 3 Nov 2020 10:08:24 -0500 Subject: [PATCH 09/25] revise new attribute names and val types --- src/plots/cartesian/axes.js | 2 +- src/plots/cartesian/axis_autotype.js | 4 +-- src/plots/cartesian/layout_attributes.js | 11 +++--- src/plots/cartesian/layout_defaults.js | 6 ++-- src/plots/cartesian/type_defaults.js | 4 +-- src/plots/gl3d/layout/axis_attributes.js | 2 +- src/plots/gl3d/layout/defaults.js | 4 +-- src/plots/layout_attributes.js | 13 ++++--- src/plots/plots.js | 2 +- src/plots/polar/layout_attributes.js | 4 +-- src/plots/polar/layout_defaults.js | 6 ++-- src/plots/ternary/layout_defaults.js | 2 +- src/traces/box/defaults.js | 2 +- src/traces/carpet/ab_defaults.js | 1 + src/traces/carpet/axis_attributes.js | 2 +- src/traces/carpet/axis_defaults.js | 4 +-- test/jasmine/tests/axes_test.js | 20 +++++------ test/jasmine/tests/box_test.js | 20 +++++------ test/jasmine/tests/carpet_test.js | 46 +++++++++++++++++------- test/jasmine/tests/gl3dlayout_test.js | 30 ++++++++-------- test/jasmine/tests/polar_test.js | 24 ++++++------- 21 files changed, 118 insertions(+), 91 deletions(-) diff --git a/src/plots/cartesian/axes.js b/src/plots/cartesian/axes.js index dae8555cb83..91e0f1c2f64 100644 --- a/src/plots/cartesian/axes.js +++ b/src/plots/cartesian/axes.js @@ -217,7 +217,7 @@ var getDataConversions = axes.getDataConversions = function(gd, trace, target, t if(Array.isArray(d2cTarget)) { ax = { type: autoType(targetArray, undefined, { - convertNumeric: gd._fullLayout.axesconvertnumeric + autotypenumbers: gd._fullLayout.autotypenumbers }), _categories: [] }; diff --git a/src/plots/cartesian/axis_autotype.js b/src/plots/cartesian/axis_autotype.js index 8dbc6ab1bf4..8a8f9894cd1 100644 --- a/src/plots/cartesian/axis_autotype.js +++ b/src/plots/cartesian/axis_autotype.js @@ -15,12 +15,12 @@ var Lib = require('../../lib'); var BADNUM = require('../../constants/numerical').BADNUM; module.exports = function autoType(array, calendar, opts) { - var convertNumeric = opts.convertNumeric; + var convertNumeric = opts.autotypenumbers !== 'strict'; // compare against strict, just in case autotypenumbers was not provided in opts if(!opts.noMultiCategory && multiCategory(array)) return 'multicategory'; if(convertNumeric && moreDates(array, calendar)) return 'date'; if(category(array)) return 'category'; - if(linearOK(array, convertNumeric)) return 'linear'; + if(linearOK(array)) return 'linear'; else return convertNumeric ? '-' : 'category'; }; diff --git a/src/plots/cartesian/layout_attributes.js b/src/plots/cartesian/layout_attributes.js index 7eb9016a034..b677a8c342d 100644 --- a/src/plots/cartesian/layout_attributes.js +++ b/src/plots/cartesian/layout_attributes.js @@ -102,14 +102,17 @@ module.exports = { 'the axis in question.' ].join(' ') }, - convertnumeric: { - valType: 'boolean', + autotypenumbers: { + valType: 'enumerated', + values: ['convert types', 'strict'], + dflt: 'convert types', role: 'info', editType: 'calc', description: [ - 'Determines whether or not a numeric string in data for this axis may be', + 'Using *strict* a numeric string in trace data is not converted to a number.', + 'Using *accept strings* a numeric string in trace data may be', 'treated as a number during automatic axis `type` detection.', - 'Defaults to layout.axesconvertnumeric.' + 'Defaults to layout.autotypenumbers.' ].join(' ') }, autorange: { diff --git a/src/plots/cartesian/layout_defaults.js b/src/plots/cartesian/layout_defaults.js index 26dd164ce01..6ce3c069db1 100644 --- a/src/plots/cartesian/layout_defaults.js +++ b/src/plots/cartesian/layout_defaults.js @@ -38,7 +38,7 @@ function appendList(cont, k, item) { } module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) { - var convertnumericDflt = layoutOut.axesconvertnumeric; + var autotypenumbersDflt = layoutOut.autotypenumbers; var ax2traces = {}; var xaMayHide = {}; @@ -248,7 +248,7 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) { automargin: true, visibleDflt: visibleDflt, reverseDflt: reverseDflt, - convertnumericDflt: convertnumericDflt, + autotypenumbersDflt: autotypenumbersDflt, splomStash: ((layoutOut._splomAxes || {})[axLetter] || {})[axId] }; @@ -313,7 +313,7 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) { automargin: true, visibleDflt: false, reverseDflt: false, - convertnumericDflt: convertnumericDflt, + autotypenumbersDflt: autotypenumbersDflt, splomStash: ((layoutOut._splomAxes || {})[axLetter] || {})[axId] }; diff --git a/src/plots/cartesian/type_defaults.js b/src/plots/cartesian/type_defaults.js index 44968ee2db2..80a6933cee4 100644 --- a/src/plots/cartesian/type_defaults.js +++ b/src/plots/cartesian/type_defaults.js @@ -16,7 +16,7 @@ var autoType = require('./axis_autotype'); * name: axis object name (ie 'xaxis') if one should be stored */ module.exports = function handleTypeDefaults(containerIn, containerOut, coerce, options) { - coerce('convertnumeric', options.convertnumericDflt); + coerce('autotypenumbers', options.autotypenumbersDflt); var axType = coerce('type', (options.splomStash || {}).type); if(axType === '-') { @@ -69,7 +69,7 @@ function setAutoType(ax, data) { opts.noMultiCategory = true; } - opts.convertNumeric = ax.convertnumeric; + opts.autotypenumbers = ax.autotypenumbers; // check all boxes on this x axis to see // if they're dates, numbers, or categories diff --git a/src/plots/gl3d/layout/axis_attributes.js b/src/plots/gl3d/layout/axis_attributes.js index ed2ac11be0d..587deabdf2c 100644 --- a/src/plots/gl3d/layout/axis_attributes.js +++ b/src/plots/gl3d/layout/axis_attributes.js @@ -78,7 +78,7 @@ module.exports = overrideAll({ type: extendFlat({}, axesAttrs.type, { values: ['-', 'linear', 'log', 'date', 'category'] }), - convertnumeric: axesAttrs.convertnumeric, + autotypenumbers: axesAttrs.autotypenumbers, autorange: axesAttrs.autorange, rangemode: axesAttrs.rangemode, range: extendFlat({}, axesAttrs.range, { diff --git a/src/plots/gl3d/layout/defaults.js b/src/plots/gl3d/layout/defaults.js index b4042f881ef..be2b7da07e1 100644 --- a/src/plots/gl3d/layout/defaults.js +++ b/src/plots/gl3d/layout/defaults.js @@ -40,7 +40,7 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) { font: layoutOut.font, fullData: fullData, getDfltFromLayout: getDfltFromLayout, - convertnumericDflt: layoutOut.axesconvertnumeric, + autotypenumbersDflt: layoutOut.autotypenumbers, paper_bgcolor: layoutOut.paper_bgcolor, calendar: layoutOut.calendar }); @@ -110,7 +110,7 @@ function handleGl3dDefaults(sceneLayoutIn, sceneLayoutOut, coerce, opts) { data: fullGl3dData, bgColor: bgColorCombined, calendar: opts.calendar, - convertnumericDflt: opts.convertnumericDflt, + autotypenumbersDflt: opts.autotypenumbersDflt, fullLayout: opts.fullLayout }); diff --git a/src/plots/layout_attributes.js b/src/plots/layout_attributes.js index 38973883842..d49fd76d96c 100644 --- a/src/plots/layout_attributes.js +++ b/src/plots/layout_attributes.js @@ -292,14 +292,17 @@ module.exports = { 'Sets the background color of the plotting area in-between x and y axes.' ].join(' ') }, - axesconvertnumeric: { - valType: 'boolean', - dflt: true, + autotypenumbers: { + valType: 'enumerated', + values: ['convert types', 'strict'], + dflt: 'convert types', role: 'info', editType: 'calc', description: [ - 'Determines whether or not a numeric string in trace data may be', - 'treated as a number during automatic axis `type` detection.' + 'Using *strict* a numeric string in trace data is not converted to a number.', + 'Using *accept strings* a numeric string in trace data may be', + 'treated as a number during automatic axis `type` detection.', + 'This is the default value; however it could be overridden for individual axes.' ].join(' ') }, separators: { diff --git a/src/plots/plots.js b/src/plots/plots.js index 39471e6f4cb..75f9360d83a 100644 --- a/src/plots/plots.js +++ b/src/plots/plots.js @@ -1476,7 +1476,7 @@ plots.supplyLayoutGlobalDefaults = function(layoutIn, layoutOut, formatObj) { layoutOut._dataTemplate = template.data; } - coerce('axesconvertnumeric'); + coerce('autotypenumbers'); var globalFont = Lib.coerceFont(coerce, 'font'); diff --git a/src/plots/polar/layout_attributes.js b/src/plots/polar/layout_attributes.js index 76e71f16f07..e4f7630d725 100644 --- a/src/plots/polar/layout_attributes.js +++ b/src/plots/polar/layout_attributes.js @@ -61,7 +61,7 @@ var radialAxisAttrs = { type: extendFlat({}, axesAttrs.type, { values: ['-', 'linear', 'log', 'date', 'category'] }), - convertnumeric: axesAttrs.convertnumeric, + autotypenumbers: axesAttrs.autotypenumbers, autorange: extendFlat({}, axesAttrs.autorange, {editType: 'plot'}), rangemode: { @@ -180,7 +180,7 @@ var angularAxisAttrs = { 'If *category, use `period` to set the number of integer coordinates around polar axis.' ].join(' ') }, - convertnumeric: axesAttrs.convertnumeric, + autotypenumbers: axesAttrs.autotypenumbers, categoryorder: axesAttrs.categoryorder, categoryarray: axesAttrs.categoryarray, diff --git a/src/plots/polar/layout_defaults.js b/src/plots/polar/layout_defaults.js index 71176afe87c..3088dcdc0d7 100644 --- a/src/plots/polar/layout_defaults.js +++ b/src/plots/polar/layout_defaults.js @@ -188,7 +188,7 @@ function handleDefaults(contIn, contOut, coerce, opts) { } function handleAxisTypeDefaults(axIn, axOut, coerce, subplotData, dataAttr, options) { - var convertnumeric = coerce('convertnumeric', options.convertnumericDflt); + var autotypenumbers = coerce('autotypenumbers', options.autotypenumbersDflt); var axType = coerce('type'); if(axType === '-') { @@ -203,7 +203,7 @@ function handleAxisTypeDefaults(axIn, axOut, coerce, subplotData, dataAttr, opti if(trace && trace[dataAttr]) { axOut.type = autoType(trace[dataAttr], 'gregorian', { - convertNumeric: convertnumeric + autotypenumbers: autotypenumbers }); } @@ -227,7 +227,7 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) { attributes: layoutAttributes, handleDefaults: handleDefaults, font: layoutOut.font, - convertnumericDflt: layoutOut.axesconvertnumeric, + autotypenumbersDflt: layoutOut.autotypenumbers, paper_bgcolor: layoutOut.paper_bgcolor, fullData: fullData, layoutOut: layoutOut diff --git a/src/plots/ternary/layout_defaults.js b/src/plots/ternary/layout_defaults.js index b48b2b8750b..b1cfc08dd78 100644 --- a/src/plots/ternary/layout_defaults.js +++ b/src/plots/ternary/layout_defaults.js @@ -27,7 +27,7 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) { attributes: layoutAttributes, handleDefaults: handleTernaryDefaults, font: layoutOut.font, - convertnumericDflt: layoutOut.axesconvertnumeric, + autotypenumbersDflt: layoutOut.autotypenumbers, paper_bgcolor: layoutOut.paper_bgcolor }); }; diff --git a/src/traces/box/defaults.js b/src/traces/box/defaults.js index 2ae935aa395..4aa51085d19 100644 --- a/src/traces/box/defaults.js +++ b/src/traces/box/defaults.js @@ -111,7 +111,7 @@ function handleSampleDefaults(traceIn, traceOut, coerce, layout) { var calendar = 'gregorian'; // TODO: should we use ax.calendar here? var opts = { - convertNumeric: true // TODO: should we use ax.convertnumeric here? + autotypenumbers: 'convert types' // TODO: should we use ax.autotypenumbers here? }; var defaultOrientation, len; diff --git a/src/traces/carpet/ab_defaults.js b/src/traces/carpet/ab_defaults.js index b0875392f19..76f1c0bde59 100644 --- a/src/traces/carpet/ab_defaults.js +++ b/src/traces/carpet/ab_defaults.js @@ -47,6 +47,7 @@ function mimickAxisDefaults(traceIn, traceOut, fullLayout, dfltColor) { calendar: traceOut.calendar, dfltColor: dfltColor, bgColor: fullLayout.paper_bgcolor, + autotypenumbersDflt: fullLayout.autotypenumbers, fullLayout: fullLayout }; diff --git a/src/traces/carpet/axis_attributes.js b/src/traces/carpet/axis_attributes.js index 5dd573e1edf..457043cf970 100644 --- a/src/traces/carpet/axis_attributes.js +++ b/src/traces/carpet/axis_attributes.js @@ -88,7 +88,7 @@ module.exports = { 'the axis in question.' ].join(' ') }, - convertnumeric: axesAttrs.convertnumeric, + autotypenumbers: axesAttrs.autotypenumbers, autorange: { valType: 'enumerated', values: [true, false, 'reversed'], diff --git a/src/traces/carpet/axis_defaults.js b/src/traces/carpet/axis_defaults.js index 5b0162c25c4..0c28cfdc741 100644 --- a/src/traces/carpet/axis_defaults.js +++ b/src/traces/carpet/axis_defaults.js @@ -51,7 +51,7 @@ module.exports = function handleAxisDefaults(containerIn, containerOut, options) } // now figure out type and do some more initialization - coerce('convertnumeric', options.convertnumericDflt); + coerce('autotypenumbers', options.autotypenumbersDflt); var axType = coerce('type'); if(axType === '-') { if(options.data) setAutoType(containerOut, options.data); @@ -221,6 +221,6 @@ function setAutoType(ax, data) { var calendar = ax[calAttr]; ax.type = autoType(data, calendar, { - convertNumeric: ax.convertnumeric + autotypenumbers: ax.autotypenumbers }); } diff --git a/test/jasmine/tests/axes_test.js b/test/jasmine/tests/axes_test.js index 0cee49282cb..7996b98faa6 100644 --- a/test/jasmine/tests/axes_test.js +++ b/test/jasmine/tests/axes_test.js @@ -190,7 +190,7 @@ describe('Test axes', function() { beforeEach(function() { layoutOut = { - axesconvertnumeric: true, + autotypenumbers: 'convert types', _has: Plots._hasPlotType, _basePlotModules: [], _dfltTitle: {x: 'x', y: 'y'}, @@ -337,10 +337,10 @@ describe('Test axes', function() { }); describe('autotype disable/enable converting numeric strings', function() { - it('should disable converting numeric strings using axis.convertnumeric', function() { + it('should disable converting numeric strings using axis.autotypenumbers', function() { layoutIn = { xaxis: {}, - yaxis: { convertnumeric: false } + yaxis: { autotypenumbers: 'strict' } }; supplyLayoutDefaults(layoutIn, layoutOut, [{ @@ -351,17 +351,17 @@ describe('Test axes', function() { y: ['0', '1', '1970', '2000'] }]); - expect(layoutOut.xaxis.convertnumeric).toBe(true); - expect(layoutOut.yaxis.convertnumeric).toBe(false); + expect(layoutOut.xaxis.autotypenumbers).toBe('convert types'); + expect(layoutOut.yaxis.autotypenumbers).toBe('strict'); expect(layoutOut.xaxis.type).toBe('linear'); expect(layoutOut.yaxis.type).toBe('category'); }); - it('should enable converting numeric strings using axis.convertnumeric and inherit defaults from layout.axesconvertnumeric', function() { - layoutOut.axesconvertnumeric = false; + it('should enable converting numeric strings using axis.autotypenumbers and inherit defaults from layout.autotypenumbers', function() { + layoutOut.autotypenumbers = 'strict'; layoutIn = { - xaxis: { convertnumeric: true }, + xaxis: { autotypenumbers: 'convert types' }, yaxis: {} }; @@ -373,8 +373,8 @@ describe('Test axes', function() { y: ['0', '1', '1970', '2000'] }]); - expect(layoutOut.xaxis.convertnumeric).toBe(true); - expect(layoutOut.yaxis.convertnumeric).toBe(false); + expect(layoutOut.xaxis.autotypenumbers).toBe('convert types'); + expect(layoutOut.yaxis.autotypenumbers).toBe('strict'); expect(layoutOut.xaxis.type).toBe('linear'); expect(layoutOut.yaxis.type).toBe('category'); }); diff --git a/test/jasmine/tests/box_test.js b/test/jasmine/tests/box_test.js index d91d55e23d8..ecb2a947e8b 100644 --- a/test/jasmine/tests/box_test.js +++ b/test/jasmine/tests/box_test.js @@ -637,10 +637,10 @@ describe('Test boxes supplyDefaults', function() { }); describe('Test box autoType', function() { - it('should disable converting numeric strings using axis.convertnumeric', function() { + it('should disable converting numeric strings using axis.autotypenumbers', function() { var gd = { layout: { - xaxis: { convertnumeric: false } + xaxis: { autotypenumbers: 'strict' } }, data: [{ type: 'box', @@ -657,15 +657,15 @@ describe('Test box autoType', function() { supplyAllDefaults(gd); - expect(gd._fullLayout.xaxis.convertnumeric).toBe(false); + expect(gd._fullLayout.xaxis.autotypenumbers).toBe('strict'); expect(gd._fullLayout.xaxis.type).toBe('category'); }); - it('should enable converting numeric strings using axis.convertnumeric', function() { + it('should enable converting numeric strings using axis.autotypenumbers', function() { var gd = { layout: { - axesconvertnumeric: false, - xaxis: { convertnumeric: true } + autotypenumbers: 'strict', + xaxis: { autotypenumbers: 'convert types' } }, data: [{ type: 'box', @@ -682,14 +682,14 @@ describe('Test box autoType', function() { supplyAllDefaults(gd); - expect(gd._fullLayout.xaxis.convertnumeric).toBe(true); + expect(gd._fullLayout.xaxis.autotypenumbers).toBe('convert types'); expect(gd._fullLayout.xaxis.type).toBe('linear'); }); - it('should enable converting numeric inherit defaults from layout.axesconvertnumeric', function() { + it('should enable converting numeric inherit defaults from layout.autotypenumbers', function() { var gd = { layout: { - axesconvertnumeric: false, + autotypenumbers: 'strict', xaxis: {} }, data: [{ @@ -707,7 +707,7 @@ describe('Test box autoType', function() { supplyAllDefaults(gd); - expect(gd._fullLayout.xaxis.convertnumeric).toBe(false); + expect(gd._fullLayout.xaxis.autotypenumbers).toBe('strict'); expect(gd._fullLayout.xaxis.type).toBe('category'); }); }); diff --git a/test/jasmine/tests/carpet_test.js b/test/jasmine/tests/carpet_test.js index d32fa075799..fa821fbdc5c 100644 --- a/test/jasmine/tests/carpet_test.js +++ b/test/jasmine/tests/carpet_test.js @@ -218,10 +218,10 @@ describe('supplyDefaults visibility check', function() { }); describe('Test carpet autoType', function() { - it('should disable converting numeric strings using axis.convertnumeric', function() { + it('should disable converting numeric strings using axis.autotypenumbers', function() { var gd = { layout: { - xaxis: { convertnumeric: false }, + xaxis: { autotypenumbers: 'strict' }, yaxis: {} }, data: [{ @@ -235,17 +235,27 @@ describe('Test carpet autoType', function() { supplyAllDefaults(gd); - expect(gd._fullLayout.xaxis.convertnumeric).toBe(false); - expect(gd._fullLayout.yaxis.convertnumeric).toBe(true); - expect(gd._fullLayout.xaxis.type).toBe('category'); - expect(gd._fullLayout.yaxis.type).toBe('linear'); + var xaxis = gd._fullLayout.xaxis; + var yaxis = gd._fullLayout.yaxis; + expect(xaxis.autotypenumbers).toBe('strict'); + expect(yaxis.autotypenumbers).toBe('convert types'); + expect(xaxis.type).toBe('category'); + expect(yaxis.type).toBe('linear'); + + // inherit default from layout.autotypenumbers + var aaxis = gd._fullData[0].aaxis; + var baxis = gd._fullData[0].baxis; + expect(aaxis.autotypenumbers).toBe('convert types'); + expect(baxis.autotypenumbers).toBe('convert types'); + expect(aaxis.type).toBe('linear'); + expect(baxis.type).toBe('linear'); }); - it('should enable converting numeric strings using axis.convertnumeric and inherit defaults from layout.axesconvertnumeric', function() { + it('should enable converting numeric strings using axis.autotypenumbers and inherit defaults from layout.autotypenumbers', function() { var gd = { layout: { - axesconvertnumeric: false, - xaxis: { convertnumeric: true }, + autotypenumbers: 'strict', + xaxis: { autotypenumbers: 'convert types' }, yaxis: {} }, data: [{ @@ -259,10 +269,20 @@ describe('Test carpet autoType', function() { supplyAllDefaults(gd); - expect(gd._fullLayout.xaxis.convertnumeric).toBe(true); - expect(gd._fullLayout.yaxis.convertnumeric).toBe(false); - expect(gd._fullLayout.xaxis.type).toBe('linear'); - expect(gd._fullLayout.yaxis.type).toBe('category'); + var xaxis = gd._fullLayout.xaxis; + var yaxis = gd._fullLayout.yaxis; + expect(xaxis.autotypenumbers).toBe('convert types'); + expect(yaxis.autotypenumbers).toBe('strict'); + expect(xaxis.type).toBe('linear'); + expect(yaxis.type).toBe('category'); + + // inherit default from layout.autotypenumbers + var aaxis = gd._fullData[0].aaxis; + var baxis = gd._fullData[0].baxis; + expect(aaxis.autotypenumbers).toBe('strict'); + expect(baxis.autotypenumbers).toBe('strict'); + expect(aaxis.type).toBe('category'); + expect(baxis.type).toBe('category'); }); }); diff --git a/test/jasmine/tests/gl3dlayout_test.js b/test/jasmine/tests/gl3dlayout_test.js index 2bdb01c26f5..85a57c2519c 100644 --- a/test/jasmine/tests/gl3dlayout_test.js +++ b/test/jasmine/tests/gl3dlayout_test.js @@ -27,7 +27,7 @@ describe('Test gl3d axes defaults', function() { beforeEach(function() { layoutOut = { - axesconvertnumeric: true + autotypenumbers: 'convert types' }; }); @@ -130,7 +130,7 @@ describe('Test Gl3d layout defaults', function() { beforeEach(function() { layoutOut = { - axesconvertnumeric: true, + autotypenumbers: 'convert types', _basePlotModules: ['gl3d'], _dfltTitle: {x: 'xxx', y: 'yyy', colorbar: 'cbbb'}, _subplots: {gl3d: ['scene']} @@ -384,12 +384,12 @@ describe('Test Gl3d layout defaults', function() { .toEqual(tinycolor.mix('#444', bgColor, frac).toRgbString()); }); - it('should disable converting numeric strings using axis.convertnumeric', function() { + it('should disable converting numeric strings using axis.autotypenumbers', function() { supplyLayoutDefaults({ scene: { - xaxis: { convertnumeric: false }, + xaxis: { autotypenumbers: 'strict' }, yaxis: {}, - zaxis: { convertnumeric: false } + zaxis: { autotypenumbers: 'strict' } } }, layoutOut, [{ type: 'scatter3d', @@ -399,22 +399,22 @@ describe('Test Gl3d layout defaults', function() { scene: 'scene' }]); - expect(layoutOut.scene.xaxis.convertnumeric).toBe(false); - expect(layoutOut.scene.yaxis.convertnumeric).toBe(true); - expect(layoutOut.scene.zaxis.convertnumeric).toBe(false); + expect(layoutOut.scene.xaxis.autotypenumbers).toBe('strict'); + expect(layoutOut.scene.yaxis.autotypenumbers).toBe('convert types'); + expect(layoutOut.scene.zaxis.autotypenumbers).toBe('strict'); expect(layoutOut.scene.xaxis.type).toBe('category'); expect(layoutOut.scene.yaxis.type).toBe('linear'); expect(layoutOut.scene.zaxis.type).toBe('category'); }); - it('should enable converting numeric strings using axis.convertnumeric and inherit defaults from layout.axesconvertnumeric', function() { - layoutOut.axesconvertnumeric = false; + it('should enable converting numeric strings using axis.autotypenumbers and inherit defaults from layout.autotypenumbers', function() { + layoutOut.autotypenumbers = 'strict'; supplyLayoutDefaults({ scene: { - xaxis: { convertnumeric: true }, + xaxis: { autotypenumbers: 'convert types' }, yaxis: {}, - zaxis: { convertnumeric: true } + zaxis: { autotypenumbers: 'convert types' } } }, layoutOut, [{ type: 'scatter3d', @@ -424,9 +424,9 @@ describe('Test Gl3d layout defaults', function() { scene: 'scene' }]); - expect(layoutOut.scene.xaxis.convertnumeric).toBe(true); - expect(layoutOut.scene.yaxis.convertnumeric).toBe(false); - expect(layoutOut.scene.zaxis.convertnumeric).toBe(true); + expect(layoutOut.scene.xaxis.autotypenumbers).toBe('convert types'); + expect(layoutOut.scene.yaxis.autotypenumbers).toBe('strict'); + expect(layoutOut.scene.zaxis.autotypenumbers).toBe('convert types'); expect(layoutOut.scene.xaxis.type).toBe('linear'); expect(layoutOut.scene.yaxis.type).toBe('category'); expect(layoutOut.scene.zaxis.type).toBe('linear'); diff --git a/test/jasmine/tests/polar_test.js b/test/jasmine/tests/polar_test.js index 3e568ff8538..6c3482420d2 100644 --- a/test/jasmine/tests/polar_test.js +++ b/test/jasmine/tests/polar_test.js @@ -74,7 +74,7 @@ describe('Test polar plots defaults:', function() { }]; layoutOut = { - axesconvertnumeric: true, + autotypenumbers: 'convert types', font: {color: 'red'}, _subplots: {polar: ['polar']} }; @@ -211,14 +211,14 @@ describe('Test polar plots defaults:', function() { expect(layoutOut.polar.angularaxis.hoverformat).toBe('g'); }); - it('should disable converting numeric strings using axis.convertnumeric', function() { + it('should disable converting numeric strings using axis.autotypenumbers', function() { _supply({ polar: { radialaxis: { - convertnumeric: false + autotypenumbers: 'strict' }, angularaxis: { - convertnumeric: false + autotypenumbers: 'strict' } } }, [{ @@ -229,22 +229,22 @@ describe('Test polar plots defaults:', function() { subplot: 'polar' }]); - expect(layoutOut.polar.angularaxis.convertnumeric).toBe(false); - expect(layoutOut.polar.radialaxis.convertnumeric).toBe(false); + expect(layoutOut.polar.angularaxis.autotypenumbers).toBe('strict'); + expect(layoutOut.polar.radialaxis.autotypenumbers).toBe('strict'); expect(layoutOut.polar.radialaxis.type).toBe('category'); expect(layoutOut.polar.angularaxis.type).toBe('category'); }); - it('should enable converting numeric strings using axis.convertnumeric and inherit defaults from layout.axesconvertnumeric', function() { - layoutOut.axesconvertnumeric = false; + it('should enable converting numeric strings using axis.autotypenumbers and inherit defaults from layout.autotypenumbers', function() { + layoutOut.autotypenumbers = 'strict'; _supply({ polar: { radialaxis: { - convertnumeric: true + autotypenumbers: 'convert types' }, angularaxis: { - convertnumeric: true + autotypenumbers: 'convert types' } } }, [{ @@ -255,8 +255,8 @@ describe('Test polar plots defaults:', function() { subplot: 'polar' }]); - expect(layoutOut.polar.angularaxis.convertnumeric).toBe(true); - expect(layoutOut.polar.radialaxis.convertnumeric).toBe(true); + expect(layoutOut.polar.angularaxis.autotypenumbers).toBe('convert types'); + expect(layoutOut.polar.radialaxis.autotypenumbers).toBe('convert types'); expect(layoutOut.polar.radialaxis.type).toBe('linear'); expect(layoutOut.polar.angularaxis.type).toBe('linear'); }); From f1c0e316462d595aee99395268af9165759108b8 Mon Sep 17 00:00:00 2001 From: archmoj Date: Tue, 3 Nov 2020 19:05:36 -0500 Subject: [PATCH 10/25] add early return for empty arrays to test category case and a bit of refactor --- src/plots/cartesian/axis_autotype.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/plots/cartesian/axis_autotype.js b/src/plots/cartesian/axis_autotype.js index 8a8f9894cd1..3994fb62406 100644 --- a/src/plots/cartesian/axis_autotype.js +++ b/src/plots/cartesian/axis_autotype.js @@ -69,14 +69,18 @@ function moreDates(a, calendar) { // are the (x,y)-values in gd.data mostly text? // require twice as many DISTINCT categories as distinct numbers function category(a) { + var len = a.length; + if(!len) return false; + // test at most 1000 points - var inc = Math.max(1, (a.length - 1) / 1000); + var inc = Math.max(1, (len - 1) / 1000); var curvenums = 0; var curvecats = 0; var seen = {}; - for(var i = 0; i < a.length; i += inc) { - var ai = a[Math.round(i)]; + for(var f = 0; f < len; f += inc) { + var i = Math.round(f); + var ai = a[i]; var stri = String(ai); if(seen[stri]) continue; seen[stri] = 1; From 837761c3b215f7b3362e5075774e964c0b851cf2 Mon Sep 17 00:00:00 2001 From: archmoj Date: Tue, 3 Nov 2020 19:21:50 -0500 Subject: [PATCH 11/25] maintain detecting dates using strict mode --- src/plots/cartesian/axis_autotype.js | 2 +- test/jasmine/tests/axes_test.js | 41 ++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/plots/cartesian/axis_autotype.js b/src/plots/cartesian/axis_autotype.js index 3994fb62406..94295dd2a2c 100644 --- a/src/plots/cartesian/axis_autotype.js +++ b/src/plots/cartesian/axis_autotype.js @@ -18,7 +18,7 @@ module.exports = function autoType(array, calendar, opts) { var convertNumeric = opts.autotypenumbers !== 'strict'; // compare against strict, just in case autotypenumbers was not provided in opts if(!opts.noMultiCategory && multiCategory(array)) return 'multicategory'; - if(convertNumeric && moreDates(array, calendar)) return 'date'; + if(moreDates(array, calendar)) return 'date'; if(category(array)) return 'category'; if(linearOK(array)) return 'linear'; else return convertNumeric ? '-' : 'category'; diff --git a/test/jasmine/tests/axes_test.js b/test/jasmine/tests/axes_test.js index 7996b98faa6..432baf11808 100644 --- a/test/jasmine/tests/axes_test.js +++ b/test/jasmine/tests/axes_test.js @@ -378,6 +378,47 @@ describe('Test axes', function() { expect(layoutOut.xaxis.type).toBe('linear'); expect(layoutOut.yaxis.type).toBe('category'); }); + + it('should autotype date having more dates with & without strict autotypenumbers', function() { + layoutIn = { + xaxis: {}, + yaxis: { autotypenumbers: 'strict' } + }; + + var dates = [ + 0, + '0', + '00', + '0000', + '1970', + '2000', + '2001-01', + '2001-02', + '2001-03', + '2001-04', + '2001-05', + '2001-06', + '2001-07', + '2001-08', + '2001-09', + '2001-10', + '2001-11', + '2001-12' + ]; + + supplyLayoutDefaults(layoutIn, layoutOut, [{ + type: 'scatter', + xaxis: 'x', + yaxis: 'y', + x: dates, + y: dates + }]); + + expect(layoutOut.xaxis.autotypenumbers).toBe('convert types'); + expect(layoutOut.yaxis.autotypenumbers).toBe('strict'); + expect(layoutOut.xaxis.type).toBe('date'); + expect(layoutOut.yaxis.type).toBe('date'); + }); }); it('should set undefined linewidth/linecolor if linewidth, linecolor or showline is not supplied', function() { From b73d3953825e977fa53c87d73faef1d07527671c Mon Sep 17 00:00:00 2001 From: archmoj Date: Tue, 3 Nov 2020 19:53:52 -0500 Subject: [PATCH 12/25] pass convertNumeric to linearOK and category --- src/plots/cartesian/axis_autotype.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/plots/cartesian/axis_autotype.js b/src/plots/cartesian/axis_autotype.js index 94295dd2a2c..323d30a820d 100644 --- a/src/plots/cartesian/axis_autotype.js +++ b/src/plots/cartesian/axis_autotype.js @@ -19,9 +19,9 @@ module.exports = function autoType(array, calendar, opts) { if(!opts.noMultiCategory && multiCategory(array)) return 'multicategory'; if(moreDates(array, calendar)) return 'date'; - if(category(array)) return 'category'; - if(linearOK(array)) return 'linear'; - else return convertNumeric ? '-' : 'category'; + if(category(array, convertNumeric)) return 'category'; + if(linearOK(array, convertNumeric)) return 'linear'; + else return '-'; }; function hasTypeNumber(v, convertNumeric) { @@ -68,7 +68,7 @@ function moreDates(a, calendar) { // are the (x,y)-values in gd.data mostly text? // require twice as many DISTINCT categories as distinct numbers -function category(a) { +function category(a, convertNumeric) { var len = a.length; if(!len) return false; @@ -86,7 +86,7 @@ function category(a) { seen[stri] = 1; if(typeof ai === 'boolean') curvecats++; - else if(Lib.cleanNumber(ai) !== BADNUM) curvenums++; + else if(convertNumeric ? Lib.cleanNumber(ai) !== BADNUM : typeof ai === 'number') curvenums++; else if(typeof ai === 'string') curvecats++; } From 0224fa0a3f93e39b4ecd0f39621eaba276f7605f Mon Sep 17 00:00:00 2001 From: archmoj Date: Tue, 3 Nov 2020 20:54:19 -0500 Subject: [PATCH 13/25] store type of --- src/plots/cartesian/axis_autotype.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/plots/cartesian/axis_autotype.js b/src/plots/cartesian/axis_autotype.js index 323d30a820d..e65baaf3cbf 100644 --- a/src/plots/cartesian/axis_autotype.js +++ b/src/plots/cartesian/axis_autotype.js @@ -85,9 +85,10 @@ function category(a, convertNumeric) { if(seen[stri]) continue; seen[stri] = 1; - if(typeof ai === 'boolean') curvecats++; - else if(convertNumeric ? Lib.cleanNumber(ai) !== BADNUM : typeof ai === 'number') curvenums++; - else if(typeof ai === 'string') curvecats++; + var t = typeof ai; + if(t === 'boolean') curvecats++; + else if(convertNumeric ? Lib.cleanNumber(ai) !== BADNUM : t === 'number') curvenums++; + else if(t === 'string') curvecats++; } return curvecats > curvenums * 2; From d218babde93fb06948357cb047c94e2724bc92ee Mon Sep 17 00:00:00 2001 From: archmoj Date: Tue, 3 Nov 2020 21:04:53 -0500 Subject: [PATCH 14/25] add early return for dates - remove unnecessary early return in linear - and refactor --- src/plots/cartesian/axis_autotype.js | 56 ++++++++++++++++------------ 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/src/plots/cartesian/axis_autotype.js b/src/plots/cartesian/axis_autotype.js index e65baaf3cbf..5ed66d713df 100644 --- a/src/plots/cartesian/axis_autotype.js +++ b/src/plots/cartesian/axis_autotype.js @@ -15,13 +15,14 @@ var Lib = require('../../lib'); var BADNUM = require('../../constants/numerical').BADNUM; module.exports = function autoType(array, calendar, opts) { - var convertNumeric = opts.autotypenumbers !== 'strict'; // compare against strict, just in case autotypenumbers was not provided in opts - if(!opts.noMultiCategory && multiCategory(array)) return 'multicategory'; if(moreDates(array, calendar)) return 'date'; + + var convertNumeric = opts.autotypenumbers !== 'strict'; // compare against strict, just in case autotypenumbers was not provided in opts if(category(array, convertNumeric)) return 'category'; if(linearOK(array, convertNumeric)) return 'linear'; - else return '-'; + + return '-'; }; function hasTypeNumber(v, convertNumeric) { @@ -30,11 +31,11 @@ function hasTypeNumber(v, convertNumeric) { // is there at least one number in array? If not, we should leave // ax.type empty so it can be autoset later -function linearOK(array, convertNumeric) { - if(!array) return false; +function linearOK(a, convertNumeric) { + var len = a.length; - for(var i = 0; i < array.length; i++) { - if(hasTypeNumber(array[i], convertNumeric)) return true; + for(var i = 0; i < len; i++) { + if(hasTypeNumber(a[i], convertNumeric)) return true; } return false; @@ -47,23 +48,31 @@ function linearOK(array, convertNumeric) { // numbers and a few dates // as with categories, consider DISTINCT values only. function moreDates(a, calendar) { - // test at most 1000 points, evenly spaced - var inc = Math.max(1, (a.length - 1) / 1000); - var dcnt = 0; - var ncnt = 0; + var len = a.length; + if(!len) return false; + + var inc = getIncrement(len); + var dats = 0; + var nums = 0; var seen = {}; - for(var i = 0; i < a.length; i += inc) { - var ai = a[Math.round(i)]; + for(var f = 0; f < len; f += inc) { + var i = Math.round(f); + var ai = a[i]; var stri = String(ai); if(seen[stri]) continue; seen[stri] = 1; - if(Lib.isDateTime(ai, calendar)) dcnt += 1; - if(isNumeric(ai)) ncnt += 1; + if(Lib.isDateTime(ai, calendar)) dats++; + if(isNumeric(ai)) nums++; } - return (dcnt > ncnt * 2); + return dats > nums * 2; +} + +// return increment to test at most 1000 points, evenly spaced +function getIncrement(len) { + return Math.max(1, (len - 1) / 1000); } // are the (x,y)-values in gd.data mostly text? @@ -72,10 +81,9 @@ function category(a, convertNumeric) { var len = a.length; if(!len) return false; - // test at most 1000 points - var inc = Math.max(1, (len - 1) / 1000); - var curvenums = 0; - var curvecats = 0; + var inc = getIncrement(len); + var nums = 0; + var cats = 0; var seen = {}; for(var f = 0; f < len; f += inc) { @@ -86,12 +94,12 @@ function category(a, convertNumeric) { seen[stri] = 1; var t = typeof ai; - if(t === 'boolean') curvecats++; - else if(convertNumeric ? Lib.cleanNumber(ai) !== BADNUM : t === 'number') curvenums++; - else if(t === 'string') curvecats++; + if(t === 'boolean') cats++; + else if(convertNumeric ? Lib.cleanNumber(ai) !== BADNUM : t === 'number') nums++; + else if(t === 'string') cats++; } - return curvecats > curvenums * 2; + return cats > nums * 2; } // very-loose requirements for multicategory, From b800a652793f97a08794e009f2eceac75c7ba0b1 Mon Sep 17 00:00:00 2001 From: archmoj Date: Tue, 3 Nov 2020 22:11:29 -0500 Subject: [PATCH 15/25] add early returns - array of arrays is not relevant to date, category & linear functions --- src/plots/cartesian/axis_autotype.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plots/cartesian/axis_autotype.js b/src/plots/cartesian/axis_autotype.js index 5ed66d713df..062fbbe0d8a 100644 --- a/src/plots/cartesian/axis_autotype.js +++ b/src/plots/cartesian/axis_autotype.js @@ -15,7 +15,10 @@ var Lib = require('../../lib'); var BADNUM = require('../../constants/numerical').BADNUM; module.exports = function autoType(array, calendar, opts) { + if(Lib.isArrayOrTypedArray(array) && !array.length) return '-'; if(!opts.noMultiCategory && multiCategory(array)) return 'multicategory'; + + if(Lib.isArrayOrTypedArray(array[0])) return '-'; if(moreDates(array, calendar)) return 'date'; var convertNumeric = opts.autotypenumbers !== 'strict'; // compare against strict, just in case autotypenumbers was not provided in opts @@ -49,7 +52,6 @@ function linearOK(a, convertNumeric) { // as with categories, consider DISTINCT values only. function moreDates(a, calendar) { var len = a.length; - if(!len) return false; var inc = getIncrement(len); var dats = 0; @@ -79,7 +81,6 @@ function getIncrement(len) { // require twice as many DISTINCT categories as distinct numbers function category(a, convertNumeric) { var len = a.length; - if(!len) return false; var inc = getIncrement(len); var nums = 0; From f6d8c39ffe28a8deb76fc9470272272cc1bc76b8 Mon Sep 17 00:00:00 2001 From: archmoj Date: Tue, 3 Nov 2020 23:07:18 -0500 Subject: [PATCH 16/25] flat input array before passing to autoType functions --- src/plots/cartesian/axis_autotype.js | 16 ++++++++++------ test/jasmine/tests/axes_test.js | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/plots/cartesian/axis_autotype.js b/src/plots/cartesian/axis_autotype.js index 062fbbe0d8a..e190e4805f9 100644 --- a/src/plots/cartesian/axis_autotype.js +++ b/src/plots/cartesian/axis_autotype.js @@ -15,15 +15,19 @@ var Lib = require('../../lib'); var BADNUM = require('../../constants/numerical').BADNUM; module.exports = function autoType(array, calendar, opts) { - if(Lib.isArrayOrTypedArray(array) && !array.length) return '-'; - if(!opts.noMultiCategory && multiCategory(array)) return 'multicategory'; + var a = array; - if(Lib.isArrayOrTypedArray(array[0])) return '-'; - if(moreDates(array, calendar)) return 'date'; + if(Lib.isArrayOrTypedArray(a) && !a.length) return '-'; + if(!opts.noMultiCategory && multiCategory(a)) return 'multicategory'; + if(opts.noMultiCategory && Lib.isArrayOrTypedArray(a[0])) { + a = a.flat(); // TODO: add support for IE + } + + if(moreDates(a, calendar)) return 'date'; var convertNumeric = opts.autotypenumbers !== 'strict'; // compare against strict, just in case autotypenumbers was not provided in opts - if(category(array, convertNumeric)) return 'category'; - if(linearOK(array, convertNumeric)) return 'linear'; + if(category(a, convertNumeric)) return 'category'; + if(linearOK(a, convertNumeric)) return 'linear'; return '-'; }; diff --git a/test/jasmine/tests/axes_test.js b/test/jasmine/tests/axes_test.js index 432baf11808..8489ab2ee3d 100644 --- a/test/jasmine/tests/axes_test.js +++ b/test/jasmine/tests/axes_test.js @@ -332,7 +332,7 @@ describe('Test axes', function() { ['d', 'e', 'f'] ] }); - checkTypes('linear', 'linear'); + checkTypes('linear', 'category'); }); }); From 560405ceaf785e58b1b9c0611fc501bb50262104 Mon Sep 17 00:00:00 2001 From: archmoj Date: Tue, 3 Nov 2020 23:24:08 -0500 Subject: [PATCH 17/25] revert description change --- src/plots/cartesian/layout_attributes.js | 2 +- src/traces/carpet/axis_attributes.js | 2 +- src/traces/sunburst/attributes.js | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plots/cartesian/layout_attributes.js b/src/plots/cartesian/layout_attributes.js index b677a8c342d..b5cb6078702 100644 --- a/src/plots/cartesian/layout_attributes.js +++ b/src/plots/cartesian/layout_attributes.js @@ -97,7 +97,7 @@ module.exports = { _noTemplating: true, description: [ 'Sets the axis type.', - 'By default, plotly.js attempts to determined the axis type', + 'By default, plotly attempts to determined the axis type', 'by looking into the data of the traces that referenced', 'the axis in question.' ].join(' ') diff --git a/src/traces/carpet/axis_attributes.js b/src/traces/carpet/axis_attributes.js index 457043cf970..b308bdbfaf8 100644 --- a/src/traces/carpet/axis_attributes.js +++ b/src/traces/carpet/axis_attributes.js @@ -83,7 +83,7 @@ module.exports = { editType: 'calc', description: [ 'Sets the axis type.', - 'By default, plotly.js attempts to determined the axis type', + 'By default, plotly attempts to determined the axis type', 'by looking into the data of the traces that referenced', 'the axis in question.' ].join(' ') diff --git a/src/traces/sunburst/attributes.js b/src/traces/sunburst/attributes.js index 08dd2ad2c21..d8d3949a4f7 100644 --- a/src/traces/sunburst/attributes.js +++ b/src/traces/sunburst/attributes.js @@ -34,7 +34,7 @@ module.exports = { 'Empty string items \'\' are understood to reference', 'the root node in the hierarchy.', 'If `ids` is filled, `parents` items are understood to be "ids" themselves.', - 'When `ids` is not set, plotly.js attempts to find matching items in `labels`,', + 'When `ids` is not set, plotly attempts to find matching items in `labels`,', 'but beware they must be unique.' ].join(' ') }, @@ -83,7 +83,7 @@ module.exports = { description: [ 'Sets the level from which this trace hierarchy is rendered.', 'Set `level` to `\'\'` to start from the root node in the hierarchy.', - 'Must be an "id" if `ids` is filled in, otherwise plotly.js attempts to find a matching', + 'Must be an "id" if `ids` is filled in, otherwise plotly attempts to find a matching', 'item in `labels`.' ].join(' ') }, From 4697f9ce79c9783bce058ac2f1ee6b68d2725703 Mon Sep 17 00:00:00 2001 From: archmoj Date: Tue, 3 Nov 2020 23:29:45 -0500 Subject: [PATCH 18/25] flat 2d arrays before passing to autotypes --- src/plots/cartesian/axis_autotype.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/plots/cartesian/axis_autotype.js b/src/plots/cartesian/axis_autotype.js index e190e4805f9..9dc29c13313 100644 --- a/src/plots/cartesian/axis_autotype.js +++ b/src/plots/cartesian/axis_autotype.js @@ -19,8 +19,16 @@ module.exports = function autoType(array, calendar, opts) { if(Lib.isArrayOrTypedArray(a) && !a.length) return '-'; if(!opts.noMultiCategory && multiCategory(a)) return 'multicategory'; - if(opts.noMultiCategory && Lib.isArrayOrTypedArray(a[0])) { - a = a.flat(); // TODO: add support for IE + if(opts.noMultiCategory && Array.isArray(a[0])) { + var b = []; + for(var i = 0; i < a.length; i++) { + if(Array.isArray(a[i])) { + for(var j = 0; j < a[i].length; j++) { + b.push(a[i][j]); + } + } + } + a = b; } if(moreDates(a, calendar)) return 'date'; From 688438c153d1f51c5de1f47fd72039da9ac522a5 Mon Sep 17 00:00:00 2001 From: archmoj Date: Wed, 4 Nov 2020 09:39:11 -0500 Subject: [PATCH 19/25] handle typed arrays inside a 2d array - plus a bit of optimization --- src/plots/cartesian/axis_autotype.js | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/plots/cartesian/axis_autotype.js b/src/plots/cartesian/axis_autotype.js index 9dc29c13313..de9e8045512 100644 --- a/src/plots/cartesian/axis_autotype.js +++ b/src/plots/cartesian/axis_autotype.js @@ -14,15 +14,21 @@ var isNumeric = require('fast-isnumeric'); var Lib = require('../../lib'); var BADNUM = require('../../constants/numerical').BADNUM; +var isArrayOrTypedArray = Lib.isArrayOrTypedArray; +var isDateTime = Lib.isDateTime; +var cleanNumber = Lib.cleanNumber; +var round = Math.round; + module.exports = function autoType(array, calendar, opts) { var a = array; - if(Lib.isArrayOrTypedArray(a) && !a.length) return '-'; - if(!opts.noMultiCategory && multiCategory(a)) return 'multicategory'; - if(opts.noMultiCategory && Array.isArray(a[0])) { + var noMultiCategory = opts.noMultiCategory; + if(isArrayOrTypedArray(a) && !a.length) return '-'; + if(!noMultiCategory && multiCategory(a)) return 'multicategory'; + if(noMultiCategory && Array.isArray(a[0])) { // no need to flat typed arrays here var b = []; for(var i = 0; i < a.length; i++) { - if(Array.isArray(a[i])) { + if(isArrayOrTypedArray(a[i])) { for(var j = 0; j < a[i].length; j++) { b.push(a[i][j]); } @@ -71,13 +77,13 @@ function moreDates(a, calendar) { var seen = {}; for(var f = 0; f < len; f += inc) { - var i = Math.round(f); + var i = round(f); var ai = a[i]; var stri = String(ai); if(seen[stri]) continue; seen[stri] = 1; - if(Lib.isDateTime(ai, calendar)) dats++; + if(isDateTime(ai, calendar)) dats++; if(isNumeric(ai)) nums++; } @@ -100,7 +106,7 @@ function category(a, convertNumeric) { var seen = {}; for(var f = 0; f < len; f += inc) { - var i = Math.round(f); + var i = round(f); var ai = a[i]; var stri = String(ai); if(seen[stri]) continue; @@ -108,7 +114,7 @@ function category(a, convertNumeric) { var t = typeof ai; if(t === 'boolean') cats++; - else if(convertNumeric ? Lib.cleanNumber(ai) !== BADNUM : t === 'number') nums++; + else if(convertNumeric ? cleanNumber(ai) !== BADNUM : t === 'number') nums++; else if(t === 'string') cats++; } @@ -119,5 +125,5 @@ function category(a, convertNumeric) { // trace modules that should never auto-type to multicategory // should be declared with 'noMultiCategory' function multiCategory(a) { - return Lib.isArrayOrTypedArray(a[0]) && Lib.isArrayOrTypedArray(a[1]); + return isArrayOrTypedArray(a[0]) && isArrayOrTypedArray(a[1]); } From e02deafeb641c9e651afd6bdd0aa1d7118abccbc Mon Sep 17 00:00:00 2001 From: archmoj Date: Wed, 4 Nov 2020 10:02:38 -0500 Subject: [PATCH 20/25] add tests for autotype - case of 2d arrays --- test/jasmine/tests/gl3dlayout_test.js | 127 +++++++++++++++++++++++--- 1 file changed, 115 insertions(+), 12 deletions(-) diff --git a/test/jasmine/tests/gl3dlayout_test.js b/test/jasmine/tests/gl3dlayout_test.js index 85a57c2519c..a4a56bd29a0 100644 --- a/test/jasmine/tests/gl3dlayout_test.js +++ b/test/jasmine/tests/gl3dlayout_test.js @@ -399,12 +399,15 @@ describe('Test Gl3d layout defaults', function() { scene: 'scene' }]); - expect(layoutOut.scene.xaxis.autotypenumbers).toBe('strict'); - expect(layoutOut.scene.yaxis.autotypenumbers).toBe('convert types'); - expect(layoutOut.scene.zaxis.autotypenumbers).toBe('strict'); - expect(layoutOut.scene.xaxis.type).toBe('category'); - expect(layoutOut.scene.yaxis.type).toBe('linear'); - expect(layoutOut.scene.zaxis.type).toBe('category'); + var xaxis = layoutOut.scene.xaxis; + var yaxis = layoutOut.scene.yaxis; + var zaxis = layoutOut.scene.zaxis; + expect(xaxis.autotypenumbers).toBe('strict'); + expect(yaxis.autotypenumbers).toBe('convert types'); + expect(zaxis.autotypenumbers).toBe('strict'); + expect(xaxis.type).toBe('category'); + expect(yaxis.type).toBe('linear'); + expect(zaxis.type).toBe('category'); }); it('should enable converting numeric strings using axis.autotypenumbers and inherit defaults from layout.autotypenumbers', function() { @@ -424,12 +427,112 @@ describe('Test Gl3d layout defaults', function() { scene: 'scene' }]); - expect(layoutOut.scene.xaxis.autotypenumbers).toBe('convert types'); - expect(layoutOut.scene.yaxis.autotypenumbers).toBe('strict'); - expect(layoutOut.scene.zaxis.autotypenumbers).toBe('convert types'); - expect(layoutOut.scene.xaxis.type).toBe('linear'); - expect(layoutOut.scene.yaxis.type).toBe('category'); - expect(layoutOut.scene.zaxis.type).toBe('linear'); + var xaxis = layoutOut.scene.xaxis; + var yaxis = layoutOut.scene.yaxis; + var zaxis = layoutOut.scene.zaxis; + expect(xaxis.autotypenumbers).toBe('convert types'); + expect(yaxis.autotypenumbers).toBe('strict'); + expect(zaxis.autotypenumbers).toBe('convert types'); + expect(xaxis.type).toBe('linear'); + expect(yaxis.type).toBe('category'); + expect(zaxis.type).toBe('linear'); + }); + + ['convert types', 'strict'].forEach(function(autotypenumbers) { + it('with autotypenumbers: *' + autotypenumbers + '* should autotype *linear* case of 2d array', function() { + var typedArray = new Float32Array(2); + typedArray[0] = 0; + typedArray[1] = 1; + + supplyLayoutDefaults({ + scene: { + xaxis: { autotypenumbers: autotypenumbers }, + yaxis: { autotypenumbers: autotypenumbers }, + zaxis: { autotypenumbers: autotypenumbers } + } + }, layoutOut, [{ + scene: 'scene', + type: 'surface', + x: [0, 1], + y: typedArray, + z: [ + typedArray, + [1, 0] + ] + }]); + + var xaxis = layoutOut.scene.xaxis; + var yaxis = layoutOut.scene.yaxis; + var zaxis = layoutOut.scene.zaxis; + expect(xaxis.autotypenumbers).toBe(autotypenumbers); + expect(yaxis.autotypenumbers).toBe(autotypenumbers); + expect(zaxis.autotypenumbers).toBe(autotypenumbers); + expect(xaxis.type).toBe('linear'); + expect(yaxis.type).toBe('linear'); + expect(zaxis.type).toBe('linear'); + }); + }); + + ['convert types', 'strict'].forEach(function(autotypenumbers) { + it('with autotypenumbers: *' + autotypenumbers + '* should autotype *category* case of 2d array', function() { + supplyLayoutDefaults({ + scene: { + xaxis: { autotypenumbers: autotypenumbers }, + yaxis: { autotypenumbers: autotypenumbers }, + zaxis: { autotypenumbers: autotypenumbers } + } + }, layoutOut, [{ + scene: 'scene', + type: 'surface', + x: ['A', 'B'], + y: ['C', 'D'], + z: [ + ['E', 'F'], + ['F', 'E'] + ] + }]); + + var xaxis = layoutOut.scene.xaxis; + var yaxis = layoutOut.scene.yaxis; + var zaxis = layoutOut.scene.zaxis; + expect(xaxis.autotypenumbers).toBe(autotypenumbers); + expect(yaxis.autotypenumbers).toBe(autotypenumbers); + expect(zaxis.autotypenumbers).toBe(autotypenumbers); + expect(xaxis.type).toBe('category'); + expect(yaxis.type).toBe('category'); + expect(zaxis.type).toBe('category'); + }); + }); + + ['convert types', 'strict'].forEach(function(autotypenumbers) { + it('with autotypenumbers: *' + autotypenumbers + '* should autotype *date* case of 2d array', function() { + supplyLayoutDefaults({ + scene: { + xaxis: { autotypenumbers: autotypenumbers }, + yaxis: { autotypenumbers: autotypenumbers }, + zaxis: { autotypenumbers: autotypenumbers } + } + }, layoutOut, [{ + scene: 'scene', + type: 'surface', + x: ['00-01', '00-02'], + y: ['00-01', '00-02'], + z: [ + ['00-01', '00-02'], + ['00-02', '00-01'] + ] + }]); + + var xaxis = layoutOut.scene.xaxis; + var yaxis = layoutOut.scene.yaxis; + var zaxis = layoutOut.scene.zaxis; + expect(xaxis.autotypenumbers).toBe(autotypenumbers); + expect(yaxis.autotypenumbers).toBe(autotypenumbers); + expect(zaxis.autotypenumbers).toBe(autotypenumbers); + expect(xaxis.type).toBe('date'); + expect(yaxis.type).toBe('date'); + expect(zaxis.type).toBe('date'); + }); }); }); }); From 4b5bfcc73782f935210db720fc52accde634869e Mon Sep 17 00:00:00 2001 From: archmoj Date: Wed, 4 Nov 2020 12:46:45 -0500 Subject: [PATCH 21/25] correct keys in description --- src/plots/cartesian/layout_attributes.js | 2 +- src/plots/layout_attributes.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plots/cartesian/layout_attributes.js b/src/plots/cartesian/layout_attributes.js index b5cb6078702..9251e2cd50b 100644 --- a/src/plots/cartesian/layout_attributes.js +++ b/src/plots/cartesian/layout_attributes.js @@ -110,7 +110,7 @@ module.exports = { editType: 'calc', description: [ 'Using *strict* a numeric string in trace data is not converted to a number.', - 'Using *accept strings* a numeric string in trace data may be', + 'Using *convert types* a numeric string in trace data may be', 'treated as a number during automatic axis `type` detection.', 'Defaults to layout.autotypenumbers.' ].join(' ') diff --git a/src/plots/layout_attributes.js b/src/plots/layout_attributes.js index d49fd76d96c..da0a15d8d91 100644 --- a/src/plots/layout_attributes.js +++ b/src/plots/layout_attributes.js @@ -300,7 +300,7 @@ module.exports = { editType: 'calc', description: [ 'Using *strict* a numeric string in trace data is not converted to a number.', - 'Using *accept strings* a numeric string in trace data may be', + 'Using *convert types* a numeric string in trace data may be', 'treated as a number during automatic axis `type` detection.', 'This is the default value; however it could be overridden for individual axes.' ].join(' ') From 08aa30098aa7efdea0205ad221a6c654e3fc4ff6 Mon Sep 17 00:00:00 2001 From: archmoj Date: Wed, 4 Nov 2020 13:14:56 -0500 Subject: [PATCH 22/25] drop unused option in ternary --- src/plots/ternary/layout_defaults.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plots/ternary/layout_defaults.js b/src/plots/ternary/layout_defaults.js index b1cfc08dd78..54fd942a2cd 100644 --- a/src/plots/ternary/layout_defaults.js +++ b/src/plots/ternary/layout_defaults.js @@ -27,7 +27,6 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) { attributes: layoutAttributes, handleDefaults: handleTernaryDefaults, font: layoutOut.font, - autotypenumbersDflt: layoutOut.autotypenumbers, paper_bgcolor: layoutOut.paper_bgcolor }); }; From 1198e56542ef03a342de5e100094bb5f6bdd3001 Mon Sep 17 00:00:00 2001 From: archmoj Date: Wed, 4 Nov 2020 13:17:21 -0500 Subject: [PATCH 23/25] add noMultiCategory option for polar --- src/plots/polar/layout_defaults.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plots/polar/layout_defaults.js b/src/plots/polar/layout_defaults.js index 3088dcdc0d7..5bdc69c746a 100644 --- a/src/plots/polar/layout_defaults.js +++ b/src/plots/polar/layout_defaults.js @@ -203,6 +203,7 @@ function handleAxisTypeDefaults(axIn, axOut, coerce, subplotData, dataAttr, opti if(trace && trace[dataAttr]) { axOut.type = autoType(trace[dataAttr], 'gregorian', { + noMultiCategory: true, autotypenumbers: autotypenumbers }); } From 99a201509782fadc9eaf009d42e68e1b15b7fd2a Mon Sep 17 00:00:00 2001 From: archmoj Date: Wed, 4 Nov 2020 13:25:29 -0500 Subject: [PATCH 24/25] apply layout.calnedar and layout.autotypenumbers in box defaults --- src/traces/box/defaults.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/traces/box/defaults.js b/src/traces/box/defaults.js index 4aa51085d19..b0e155042b1 100644 --- a/src/traces/box/defaults.js +++ b/src/traces/box/defaults.js @@ -109,9 +109,9 @@ function handleSampleDefaults(traceIn, traceOut, coerce, layout) { var yLen = yDims && Lib.minRowLength(y); var xLen = xDims && Lib.minRowLength(x); - var calendar = 'gregorian'; // TODO: should we use ax.calendar here? + var calendar = layout.calendar; var opts = { - autotypenumbers: 'convert types' // TODO: should we use ax.autotypenumbers here? + autotypenumbers: layout.autotypenumbers }; var defaultOrientation, len; From 6fdf5591b93880066fb3c255d5f269cba1a1b8be Mon Sep 17 00:00:00 2001 From: archmoj Date: Wed, 4 Nov 2020 13:40:25 -0500 Subject: [PATCH 25/25] fixup box plot test to have a layout object --- test/jasmine/tests/box_test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/jasmine/tests/box_test.js b/test/jasmine/tests/box_test.js index ecb2a947e8b..bf915365c95 100644 --- a/test/jasmine/tests/box_test.js +++ b/test/jasmine/tests/box_test.js @@ -26,7 +26,7 @@ describe('Test boxes supplyDefaults', function() { it('should set visible to false when x and y are empty', function() { traceIn = {}; - supplyDefaults(traceIn, traceOut, defaultColor); + supplyDefaults(traceIn, traceOut, defaultColor, {}); expect(traceOut.visible).toBe(false); traceIn = {