From 9da20003d9026ebe9f6ec332584307962e20d0bf Mon Sep 17 00:00:00 2001 From: satotake <doublequotation@gmail.com> Date: Fri, 12 Aug 2016 22:41:17 +0900 Subject: [PATCH 01/12] add optional arg `separatethousands`to numSeparate --- src/lib/index.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/lib/index.js b/src/lib/index.js index e2b0a6f8f95..1c32a168686 100644 --- a/src/lib/index.js +++ b/src/lib/index.js @@ -581,15 +581,21 @@ lib.objectFromPath = function(path, value) { * // returns '2016' * * @example + * lib.numSeparate(3000, '.,', true); + * // returns '3,000' + * + * @example * lib.numSeparate(1234.56, '|,') * // returns '1,234|56' * * @param {string|number} value the value to be converted * @param {string} separators string of decimal, then thousands separators + * @param {boolean} separatethousands boolean, 4-digit integers are separated if true * * @return {string} the value that has been separated */ -lib.numSeparate = function(value, separators) { +lib.numSeparate = function(value, separators, separatethousands) { + if(!separatethousands) separatethousands = false; if(typeof separators !== 'string' || separators.length === 0) { throw new Error('Separator string required for formatting!'); @@ -608,7 +614,7 @@ lib.numSeparate = function(value, separators) { x2 = x.length > 1 ? decimalSep + x[1] : ''; // Years are ignored for thousands separators - if(thouSep && (x.length > 1 || x1.length > 4)) { + if(thouSep && (x.length > 1 || x1.length > 4 || separatethousands)) { while(thousandsRe.test(x1)) { x1 = x1.replace(thousandsRe, '$1' + thouSep + '$2'); } From d61c963d28055b7d296486bd34ca709b59e71a7f Mon Sep 17 00:00:00 2001 From: satotake <doublequotation@gmail.com> Date: Fri, 12 Aug 2016 22:42:47 +0900 Subject: [PATCH 02/12] add test of numSeparate for new arg --- test/jasmine/tests/lib_test.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/jasmine/tests/lib_test.js b/test/jasmine/tests/lib_test.js index 76d0dff5b1e..16361f79cae 100644 --- a/test/jasmine/tests/lib_test.js +++ b/test/jasmine/tests/lib_test.js @@ -1315,6 +1315,10 @@ describe('Test lib.js:', function() { expect(Lib.numSeparate(2016, '.,')).toBe('2016'); }); + it('should work even for 4-digit integer if third argument is true', function() { + expect(Lib.numSeparate(3000, '.,', true)).toBe('3,000'); + }); + it('should work for multiple thousands', function() { expect(Lib.numSeparate(1000000000, '.,')).toBe('1,000,000,000'); }); From c40f47411b8d029e84e5c13b378a09d76d8392e5 Mon Sep 17 00:00:00 2001 From: satotake <doublequotation@gmail.com> Date: Fri, 12 Aug 2016 22:44:24 +0900 Subject: [PATCH 03/12] add prop `separatethousands` to layout_attributes --- src/plots/cartesian/axes.js | 5 +++-- src/plots/cartesian/layout_attributes.js | 8 ++++++++ src/plots/cartesian/tick_label_defaults.js | 1 + 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/plots/cartesian/axes.js b/src/plots/cartesian/axes.js index d6ffb8cc97f..8e574fe49e9 100644 --- a/src/plots/cartesian/axes.js +++ b/src/plots/cartesian/axes.js @@ -1092,7 +1092,8 @@ function numFormat(v, ax, fmtoverride, hover) { tickRound = ax._tickround, exponentFormat = fmtoverride || ax.exponentformat || 'B', exponent = ax._tickexponent, - tickformat = ax.tickformat; + tickformat = ax.tickformat, + separatethousands = ax.separatethousands; // special case for hover: set exponent just for this value, and // add a couple more digits of precision over tick labels @@ -1156,7 +1157,7 @@ function numFormat(v, ax, fmtoverride, hover) { if(dp) v = v.substr(0, dp + tickRound).replace(/\.?0+$/, ''); } // insert appropriate decimal point and thousands separator - v = Lib.numSeparate(v, ax._gd._fullLayout.separators); + v = Lib.numSeparate(v, ax._gd._fullLayout.separators, separatethousands); } // add exponent diff --git a/src/plots/cartesian/layout_attributes.js b/src/plots/cartesian/layout_attributes.js index b4c4d134bc3..044fb94c546 100644 --- a/src/plots/cartesian/layout_attributes.js +++ b/src/plots/cartesian/layout_attributes.js @@ -310,6 +310,14 @@ module.exports = { 'If *B*, 1B.' ].join(' ') }, + separatethousands: { + valType: 'boolean', + dflt: false, + role: 'style', + description: [ + 'even 4-digit integers are separated if true' + ].join(' ') + }, tickformat: { valType: 'string', dflt: '', diff --git a/src/plots/cartesian/tick_label_defaults.js b/src/plots/cartesian/tick_label_defaults.js index 9d5a83d67a1..148368cb6b4 100644 --- a/src/plots/cartesian/tick_label_defaults.js +++ b/src/plots/cartesian/tick_label_defaults.js @@ -43,6 +43,7 @@ module.exports = function handleTickLabelDefaults(containerIn, containerOut, coe if(!tickFormat && axType !== 'date') { coerce('showexponent', showAttrDflt); coerce('exponentformat'); + coerce('separatethousands'); } } } From 78d06a95dcbbf3192e05b91c8570c231e3820376 Mon Sep 17 00:00:00 2001 From: satotake <doublequotation@gmail.com> Date: Sat, 13 Aug 2016 15:45:13 +0900 Subject: [PATCH 04/12] make description clear in the layout_attributes --- 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 044fb94c546..a0e44874bd6 100644 --- a/src/plots/cartesian/layout_attributes.js +++ b/src/plots/cartesian/layout_attributes.js @@ -315,7 +315,7 @@ module.exports = { dflt: false, role: 'style', description: [ - 'even 4-digit integers are separated if true' + 'If "true", even 4-digit integers are separated' ].join(' ') }, tickformat: { From edea7f10bbb1d7513c8a96a303876b31c6f04da7 Mon Sep 17 00:00:00 2001 From: satotake <doublequotation@gmail.com> Date: Sat, 13 Aug 2016 17:27:34 +0900 Subject: [PATCH 05/12] write mock json and generate baseline with docker --- .../baselines/axislabel_separatethousands.png | Bin 0 -> 26221 bytes .../mocks/axislabel_separatethousands.json | 15 +++++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 test/image/baselines/axislabel_separatethousands.png create mode 100644 test/image/mocks/axislabel_separatethousands.json diff --git a/test/image/baselines/axislabel_separatethousands.png b/test/image/baselines/axislabel_separatethousands.png new file mode 100644 index 0000000000000000000000000000000000000000..d3af4c99e6db39bc840fa70a9feb4075d9642e49 GIT binary patch literal 26221 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 literal 0 HcmV?d00001 diff --git a/test/image/mocks/axislabel_separatethousands.json b/test/image/mocks/axislabel_separatethousands.json new file mode 100644 index 00000000000..2a853d23aab --- /dev/null +++ b/test/image/mocks/axislabel_separatethousands.json @@ -0,0 +1,15 @@ +{ + "data": [ + { + "x": [1000, 2000, 3000, 4000], + "y": [1000, 1500, 2000, 10000], + "type": "scatter" + } + ], + "layout": { + "yaxis": { + "exponentformat": "none", + "separatethousands": true + } + } +} From f3e886e66bc186bce970c636ede9d3d8a35e807e Mon Sep 17 00:00:00 2001 From: satotake <doublequotation@gmail.com> Date: Sat, 13 Aug 2016 18:15:51 +0900 Subject: [PATCH 06/12] add separatethousands to draw.js --- src/components/colorbar/draw.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/colorbar/draw.js b/src/components/colorbar/draw.js index 3d287532a51..e8a91d78ffc 100644 --- a/src/components/colorbar/draw.js +++ b/src/components/colorbar/draw.js @@ -158,6 +158,7 @@ module.exports = function draw(gd, id) { tickangle: opts.tickangle, tickformat: opts.tickformat, exponentformat: opts.exponentformat, + separatethousands: opts.separatethousands, showexponent: opts.showexponent, showtickprefix: opts.showtickprefix, tickprefix: opts.tickprefix, From a36ec799c8ab15081e4b91dec9b68272d27cd3a0 Mon Sep 17 00:00:00 2001 From: satotake <doublequotation@gmail.com> Date: Sat, 13 Aug 2016 18:16:46 +0900 Subject: [PATCH 07/12] add separatethousands to colorbar.attributes --- src/components/colorbar/attributes.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/colorbar/attributes.js b/src/components/colorbar/attributes.js index 9ded21dd822..261fb7dd368 100644 --- a/src/components/colorbar/attributes.js +++ b/src/components/colorbar/attributes.js @@ -167,6 +167,7 @@ module.exports = { showtickprefix: axesAttrs.showtickprefix, ticksuffix: axesAttrs.ticksuffix, showticksuffix: axesAttrs.showticksuffix, + separatethousands: opts.separatethousands, exponentformat: axesAttrs.exponentformat, showexponent: axesAttrs.showexponent, title: { From 8c2d97094ed37840b410d5372ae7d212bef36135 Mon Sep 17 00:00:00 2001 From: satotake <doublequotation@gmail.com> Date: Sat, 13 Aug 2016 18:20:13 +0900 Subject: [PATCH 08/12] add separatethousands to gl3d.layout --- src/plots/gl3d/layout/axis_attributes.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plots/gl3d/layout/axis_attributes.js b/src/plots/gl3d/layout/axis_attributes.js index 6c948c1c1cb..faad75ece28 100644 --- a/src/plots/gl3d/layout/axis_attributes.js +++ b/src/plots/gl3d/layout/axis_attributes.js @@ -98,6 +98,7 @@ module.exports = { showticksuffix: axesAttrs.showticksuffix, showexponent: axesAttrs.showexponent, exponentformat: axesAttrs.exponentformat, + separatethousands: axesAttrs.separatethousands, tickformat: axesAttrs.tickformat, hoverformat: axesAttrs.hoverformat, // lines and grids From e76c35cb4ea6fb99e35d3a92b07cd3e1f5f0e14e Mon Sep 17 00:00:00 2001 From: satotake <doublequotation@gmail.com> Date: Sat, 13 Aug 2016 18:21:22 +0900 Subject: [PATCH 09/12] add separatethousands to ternay.layout --- src/plots/ternary/layout/axis_attributes.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plots/ternary/layout/axis_attributes.js b/src/plots/ternary/layout/axis_attributes.js index 42b00778682..8fc611161ed 100644 --- a/src/plots/ternary/layout/axis_attributes.js +++ b/src/plots/ternary/layout/axis_attributes.js @@ -35,6 +35,7 @@ module.exports = { ticksuffix: axesAttrs.ticksuffix, showexponent: axesAttrs.showexponent, exponentformat: axesAttrs.exponentformat, + separatethousands: axesAttrs.exponentformat, tickfont: axesAttrs.tickfont, tickangle: axesAttrs.tickangle, tickformat: axesAttrs.tickformat, From e4fb310513521c811d2f4445771cf27bfe643747 Mon Sep 17 00:00:00 2001 From: satotake <doublequotation@gmail.com> Date: Sat, 13 Aug 2016 18:22:39 +0900 Subject: [PATCH 10/12] fix typo --- src/plots/ternary/layout/axis_attributes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plots/ternary/layout/axis_attributes.js b/src/plots/ternary/layout/axis_attributes.js index 8fc611161ed..8ceb94f5771 100644 --- a/src/plots/ternary/layout/axis_attributes.js +++ b/src/plots/ternary/layout/axis_attributes.js @@ -35,7 +35,7 @@ module.exports = { ticksuffix: axesAttrs.ticksuffix, showexponent: axesAttrs.showexponent, exponentformat: axesAttrs.exponentformat, - separatethousands: axesAttrs.exponentformat, + separatethousands: axesAttrs.separatethousands, tickfont: axesAttrs.tickfont, tickangle: axesAttrs.tickangle, tickformat: axesAttrs.tickformat, From 08b75b563284551ea200a2192ab7c5eea2194242 Mon Sep 17 00:00:00 2001 From: satotake <doublequotation@gmail.com> Date: Sat, 13 Aug 2016 18:39:00 +0900 Subject: [PATCH 11/12] fix typo --- src/components/colorbar/attributes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/colorbar/attributes.js b/src/components/colorbar/attributes.js index 261fb7dd368..1a01bc2646d 100644 --- a/src/components/colorbar/attributes.js +++ b/src/components/colorbar/attributes.js @@ -167,7 +167,7 @@ module.exports = { showtickprefix: axesAttrs.showtickprefix, ticksuffix: axesAttrs.ticksuffix, showticksuffix: axesAttrs.showticksuffix, - separatethousands: opts.separatethousands, + separatethousands: axesAttrs.separatethousands, exponentformat: axesAttrs.exponentformat, showexponent: axesAttrs.showexponent, title: { From f2e710f0fbfde3c20f0bb32f38acd6daaaa3a664 Mon Sep 17 00:00:00 2001 From: satotake <doublequotation@gmail.com> Date: Sat, 13 Aug 2016 19:05:08 +0900 Subject: [PATCH 12/12] empty commit: CI test again