From e7aeee48dc56c81c8efc1c56b4712248b4028e78 Mon Sep 17 00:00:00 2001 From: Cristian Kiss Date: Mon, 26 Jun 2017 09:19:08 +0300 Subject: [PATCH 1/6] added hoverlabel namelength option --- src/components/fx/attributes.js | 7 +++++++ src/components/fx/hover.js | 2 +- src/components/fx/hoverlabel_defaults.js | 1 + src/components/fx/layout_attributes.js | 7 +++++++ 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/components/fx/attributes.js b/src/components/fx/attributes.js index 65685335015..4416197170f 100644 --- a/src/components/fx/attributes.js +++ b/src/components/fx/attributes.js @@ -33,6 +33,13 @@ module.exports = { family: extendFlat({}, fontAttrs.family, { arrayOk: true }), size: extendFlat({}, fontAttrs.size, { arrayOk: true }), color: extendFlat({}, fontAttrs.color, { arrayOk: true }) + }, + namelength: { + valType: 'number', + min: 0, + dflt: 15, + role: 'style', + description: 'Sets the length (in number of characters) of the hover labels for this trace' } } }; diff --git a/src/components/fx/hover.js b/src/components/fx/hover.js index 3a90939bb0f..f520276f670 100644 --- a/src/components/fx/hover.js +++ b/src/components/fx/hover.js @@ -689,7 +689,7 @@ function createHoverText(hoverData, opts, gd) { // strip out our pseudo-html elements from d.name (if it exists at all) name = svgTextUtils.plainText(d.name || ''); - if(name.length > 15) name = name.substr(0, 12) + '...'; + if(name.length > commonLabelOpts.namelength) name = name.substr(0, commonLabelOpts.namelength - 3) + '...'; } // used by other modules (initially just ternary) that diff --git a/src/components/fx/hoverlabel_defaults.js b/src/components/fx/hoverlabel_defaults.js index 85fb682dee0..0b3573fe92d 100644 --- a/src/components/fx/hoverlabel_defaults.js +++ b/src/components/fx/hoverlabel_defaults.js @@ -15,5 +15,6 @@ module.exports = function handleHoverLabelDefaults(contIn, contOut, coerce, opts coerce('hoverlabel.bgcolor', opts.bgcolor); coerce('hoverlabel.bordercolor', opts.bordercolor); + coerce('hoverlabel.namelength', opts.namelength); Lib.coerceFont(coerce, 'hoverlabel.font', opts.font); }; diff --git a/src/components/fx/layout_attributes.js b/src/components/fx/layout_attributes.js index f09e0dff0d1..f5ca5d945bf 100644 --- a/src/components/fx/layout_attributes.js +++ b/src/components/fx/layout_attributes.js @@ -55,6 +55,13 @@ module.exports = { dflt: constants.HOVERFONTSIZE }), color: extendFlat({}, fontAttrs.color) + }, + namelength: { + valType: 'number', + min: 0, + dflt: 15, + role: 'style', + description: 'Sets the length (in number of characters) of the hover labels for this trace' } } }; From 8abf2ea26a532e84cb2c22f1652a9950c0e729e3 Mon Sep 17 00:00:00 2001 From: Cristian Kiss Date: Mon, 26 Jun 2017 11:27:53 +0300 Subject: [PATCH 2/6] zero means no trimming at all --- src/components/fx/hover.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/fx/hover.js b/src/components/fx/hover.js index f520276f670..11842eac3c1 100644 --- a/src/components/fx/hover.js +++ b/src/components/fx/hover.js @@ -689,7 +689,7 @@ function createHoverText(hoverData, opts, gd) { // strip out our pseudo-html elements from d.name (if it exists at all) name = svgTextUtils.plainText(d.name || ''); - if(name.length > commonLabelOpts.namelength) name = name.substr(0, commonLabelOpts.namelength - 3) + '...'; + if(name.length > commonLabelOpts.namelength && commonLabelOpts.namelength > 0) name = name.substr(0, commonLabelOpts.namelength - 3) + '...'; } // used by other modules (initially just ternary) that From ac2f7f49c9e2b36df0d98f82c7e47eab28b873dc Mon Sep 17 00:00:00 2001 From: Cristian Kiss Date: Mon, 26 Jun 2017 14:58:47 +0300 Subject: [PATCH 3/6] fixed tests --- test/jasmine/tests/fx_test.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/jasmine/tests/fx_test.js b/test/jasmine/tests/fx_test.js index 3ffea51d51c..3844045d65c 100644 --- a/test/jasmine/tests/fx_test.js +++ b/test/jasmine/tests/fx_test.js @@ -148,7 +148,8 @@ describe('Fx defaults', function() { family: 'Roboto', size: 40, color: 'pink' - } + }, + namelength: 15 }); expect(out.data[1].hoverlabel).toEqual({ @@ -158,7 +159,8 @@ describe('Fx defaults', function() { family: 'Roboto', size: 20, color: 'red' - } + }, + namelength: 15 }); expect(out.layout.annotations[0].hoverlabel).toEqual({ From 8a308a81f34fd7b0dee16dafc3af324e3f00ce56 Mon Sep 17 00:00:00 2001 From: Cristian Kiss Date: Wed, 5 Jul 2017 10:36:37 +0300 Subject: [PATCH 4/6] review fixes --- src/components/fx/attributes.js | 1 + src/components/fx/hover.js | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/fx/attributes.js b/src/components/fx/attributes.js index 4416197170f..443ccdb3a36 100644 --- a/src/components/fx/attributes.js +++ b/src/components/fx/attributes.js @@ -38,6 +38,7 @@ module.exports = { valType: 'number', min: 0, dflt: 15, + arrayOk: true, role: 'style', description: 'Sets the length (in number of characters) of the hover labels for this trace' } diff --git a/src/components/fx/hover.js b/src/components/fx/hover.js index 11842eac3c1..e79c0e5f2b5 100644 --- a/src/components/fx/hover.js +++ b/src/components/fx/hover.js @@ -689,7 +689,9 @@ function createHoverText(hoverData, opts, gd) { // strip out our pseudo-html elements from d.name (if it exists at all) name = svgTextUtils.plainText(d.name || ''); - if(name.length > commonLabelOpts.namelength && commonLabelOpts.namelength > 0) name = name.substr(0, commonLabelOpts.namelength - 3) + '...'; + if(commonLabelOpts.namelength > 0 && name.length > commonLabelOpts.namelength) { + name = name.substr(0, commonLabelOpts.namelength - 3) + '...'; + } } // used by other modules (initially just ternary) that From 94f660ad850ca7453f9d29895204dc3873328d15 Mon Sep 17 00:00:00 2001 From: alexcjohnson Date: Wed, 19 Jul 2017 15:16:31 -0400 Subject: [PATCH 5/6] finish and test hoverlabel.namelength - -1 for no constraint - more complete description - complete arrayOk support - tests --- src/components/fx/attributes.js | 14 ++++++++++---- src/components/fx/calc.js | 1 + src/components/fx/hover.js | 8 ++++++-- src/components/fx/layout_attributes.js | 13 ++++++++++--- test/jasmine/tests/hover_label_test.js | 14 ++++++++++---- 5 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/components/fx/attributes.js b/src/components/fx/attributes.js index 443ccdb3a36..8ea95a84031 100644 --- a/src/components/fx/attributes.js +++ b/src/components/fx/attributes.js @@ -35,12 +35,18 @@ module.exports = { color: extendFlat({}, fontAttrs.color, { arrayOk: true }) }, namelength: { - valType: 'number', - min: 0, - dflt: 15, + valType: 'integer', + min: -1, arrayOk: true, role: 'style', - description: 'Sets the length (in number of characters) of the hover labels for this trace' + description: [ + 'Sets the length (in number of characters) of the trace name in', + 'the hover labels for this trace. -1 shows the whole name', + 'regardless of length. 0-3 shows the first 0-3 characters, and', + 'an integer >3 will show the whole name if it is less than that', + 'many characters, but if it is longer, will truncate to', + '`namelength - 3` characters and add an ellipsis.' + ].join(' ') } } }; diff --git a/src/components/fx/calc.js b/src/components/fx/calc.js index 38433e3094f..677dc620778 100644 --- a/src/components/fx/calc.js +++ b/src/components/fx/calc.js @@ -41,6 +41,7 @@ module.exports = function calc(gd) { fillFn(trace.hoverlabel.font.size, cd, 'hts'); fillFn(trace.hoverlabel.font.color, cd, 'htc'); fillFn(trace.hoverlabel.font.family, cd, 'htf'); + fillFn(trace.hoverlabel.namelength, cd, 'hnl'); } }; diff --git a/src/components/fx/hover.js b/src/components/fx/hover.js index e79c0e5f2b5..ffc44a338ce 100644 --- a/src/components/fx/hover.js +++ b/src/components/fx/hover.js @@ -689,8 +689,11 @@ function createHoverText(hoverData, opts, gd) { // strip out our pseudo-html elements from d.name (if it exists at all) name = svgTextUtils.plainText(d.name || ''); - if(commonLabelOpts.namelength > 0 && name.length > commonLabelOpts.namelength) { - name = name.substr(0, commonLabelOpts.namelength - 3) + '...'; + var nameLength = Math.round(d.nameLength); + + if(nameLength > -1 && name.length > nameLength) { + if(nameLength > 3) name = name.substr(0, nameLength - 3) + '...'; + else name = name.substr(0, nameLength); } } @@ -1063,6 +1066,7 @@ function cleanPoint(d, hovermode) { fill('fontFamily', 'htf', 'hoverlabel.font.family'); fill('fontSize', 'hts', 'hoverlabel.font.size'); fill('fontColor', 'htc', 'hoverlabel.font.color'); + fill('nameLength', 'hnl', 'hoverlabel.namelength'); d.posref = hovermode === 'y' ? (d.x0 + d.x1) / 2 : (d.y0 + d.y1) / 2; diff --git a/src/components/fx/layout_attributes.js b/src/components/fx/layout_attributes.js index f5ca5d945bf..ef975bc79d4 100644 --- a/src/components/fx/layout_attributes.js +++ b/src/components/fx/layout_attributes.js @@ -57,11 +57,18 @@ module.exports = { color: extendFlat({}, fontAttrs.color) }, namelength: { - valType: 'number', - min: 0, + valType: 'integer', + min: -1, dflt: 15, role: 'style', - description: 'Sets the length (in number of characters) of the hover labels for this trace' + description: [ + 'Sets the default length (in number of characters) of the trace name in', + 'the hover labels for all traces. -1 shows the whole name', + 'regardless of length. 0-3 shows the first 0-3 characters, and', + 'an integer >3 will show the whole name if it is less than that', + 'many characters, but if it is longer, will truncate to', + '`namelength - 3` characters and add an ellipsis.' + ].join(' ') } } }; diff --git a/test/jasmine/tests/hover_label_test.js b/test/jasmine/tests/hover_label_test.js index 5498d69aff1..92f713a722f 100644 --- a/test/jasmine/tests/hover_label_test.js +++ b/test/jasmine/tests/hover_label_test.js @@ -683,7 +683,13 @@ describe('hover info on stacked subplots', function() { }); describe('hover info on stacked subplots with shared y-axis', function() { - var mock = require('@mocks/stacked_subplots_shared_yaxis.json'); + var mock = Lib.extendDeep(require('@mocks/stacked_subplots_shared_yaxis.json')); + mock.data[0].name = 'Who put the bomp in the bomp bah bomp bah bomp'; + mock.data[0].hoverlabel = {namelength: -1}; + mock.data[1].name = 'Who put the ram in the rama lama ding dong'; + mock.data[1].hoverlabel = {namelength: [2, 4]}; + mock.data[2].name = 'Who put the bop in the bop shoo bop shoo bop'; + mock.layout.hoverlabel = {namelength: 10}; beforeEach(function(done) { Plotly.plot(createGraphDiv(), mock.data, mock.layout).then(done); @@ -727,11 +733,11 @@ describe('hover info on stacked subplots', function() { expect(d3.selectAll('g.hovertext').size()).toEqual(3); var textNodes = d3.selectAll('g.hovertext').selectAll('text'); - expect(textNodes[0][0].innerHTML).toEqual('trace 0'); + expect(textNodes[0][0].innerHTML).toEqual('Who put the bomp in the bomp bah bomp bah bomp'); expect(textNodes[0][1].innerHTML).toEqual('1'); - expect(textNodes[1][0].innerHTML).toEqual('trace 1'); + expect(textNodes[1][0].innerHTML).toEqual('Wh'); expect(textNodes[1][1].innerHTML).toEqual('2.1'); - expect(textNodes[2][0].innerHTML).toEqual('trace 2'); + expect(textNodes[2][0].innerHTML).toEqual('Who put...'); expect(textNodes[2][1].innerHTML).toEqual('3'); }); }); From e9375192e3675f5902bbd0012642018ce1bc949c Mon Sep 17 00:00:00 2001 From: alexcjohnson Date: Wed, 19 Jul 2017 15:57:15 -0400 Subject: [PATCH 6/6] integer can be arrayOk --- src/lib/coerce.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/coerce.js b/src/lib/coerce.js index eacdfe1f637..bdca900b14c 100644 --- a/src/lib/coerce.js +++ b/src/lib/coerce.js @@ -94,7 +94,7 @@ exports.valObjects = { 'are coerced to the `dflt`.' ].join(' '), requiredOpts: [], - otherOpts: ['dflt', 'min', 'max'], + otherOpts: ['dflt', 'min', 'max', 'arrayOk'], coerceFunction: function(v, propOut, dflt, opts) { if(v % 1 || !isNumeric(v) || (opts.min !== undefined && v < opts.min) ||