diff --git a/src/traces/bar/plot.js b/src/traces/bar/plot.js index 37653f9c3a8..ee16cc099e4 100644 --- a/src/traces/bar/plot.js +++ b/src/traces/bar/plot.js @@ -1105,52 +1105,43 @@ function calcTextinfo(cd, index, xa, ya) { var text = []; var tx; - var hasFlag = function (flag) { + function hasFlag(flag) { return parts.indexOf(flag) !== -1; - }; - - if (hasFlag('label')) { - text.push(formatLabel(cd[index].p)); } - if (hasFlag('text')) { - tx = Lib.castOption(trace, cdi.i, 'text'); - if (tx === 0 || tx) text.push(tx); + var nPercent = 0; + if(isFunnel) { + if(hasFlag('percent initial')) nPercent++; + if(hasFlag('percent previous')) nPercent++; + if(hasFlag('percent total')) nPercent++; } - - if (isWaterfall) { - var delta = +cdi.rawS || cdi.s; - var final = cdi.v; - var initial = final - delta; - - if (hasFlag('initial')) text.push(formatNumber(initial)); - if (hasFlag('delta')) text.push(formatNumber(delta)); - if (hasFlag('final')) text.push(formatNumber(final)); - } - - if (isFunnel) { - if (hasFlag('value')) text.push(formatNumber(cdi.s)); - - var nPercent = 0; - if (hasFlag('percent initial')) nPercent++; - if (hasFlag('percent previous')) nPercent++; - if (hasFlag('percent total')) nPercent++; - - var hasMultiplePercents = nPercent > 1; - - if (hasFlag('percent initial')) { + var hasMultiplePercents = nPercent > 1; + for(var i in parts) { + var part = parts[i]; + if(part === 'label') { + text.push(formatLabel(cdi.p)); + } else if(part === 'text') { + tx = Lib.castOption(trace, cdi.i, 'text'); + if(tx === 0 || tx) text.push(tx); + } else if(isWaterfall && part === 'initial') { + text.push(formatNumber(cdi.v - (+cdi.rawS || cdi.s))); + } else if(isWaterfall && part === 'delta') { + text.push(formatNumber(+cdi.rawS || cdi.s)); + } else if(isWaterfall && part === 'final') { + text.push(formatNumber(cdi.v)); + } else if(isFunnel && part === 'value') { + text.push(formatNumber(cdi.s)); + } else if(isFunnel && part === 'percent initial') { tx = Lib.formatPercent(cdi.begR); - if (hasMultiplePercents) tx += ' of initial'; + if(hasMultiplePercents) tx += ' of initial'; text.push(tx); - } - if (hasFlag('percent previous')) { + } else if(isFunnel && part === 'percent previous') { tx = Lib.formatPercent(cdi.difR); - if (hasMultiplePercents) tx += ' of previous'; + if(hasMultiplePercents) tx += ' of previous'; text.push(tx); - } - if (hasFlag('percent total')) { + } else if(isFunnel && part === 'percent total') { tx = Lib.formatPercent(cdi.sumR); - if (hasMultiplePercents) tx += ' of total'; + if(hasMultiplePercents) tx += ' of total'; text.push(tx); } } diff --git a/src/traces/pie/plot.js b/src/traces/pie/plot.js index d31ad0a7c32..97800b4604d 100644 --- a/src/traces/pie/plot.js +++ b/src/traces/pie/plot.js @@ -1229,24 +1229,22 @@ function formatSliceLabel(gd, pt, cd0) { var textinfo = trace.textinfo; if (!texttemplate && textinfo && textinfo !== 'none') { var parts = textinfo.split('+'); - var hasFlag = function (flag) { - return parts.indexOf(flag) !== -1; - }; - var hasLabel = hasFlag('label'); - var hasText = hasFlag('text'); - var hasValue = hasFlag('value'); - var hasPercent = hasFlag('percent'); - var separators = fullLayout.separators; - var text; - - text = hasLabel ? [pt.label] : []; - if (hasText) { - var tx = helpers.getFirstFilled(trace.text, pt.pts); - if (isValidTextValue(tx)) text.push(tx); + var text = []; + var tx; + for(var i in parts) { + var part = parts[i]; + if(part === 'label') { + text.push(pt.label); + } else if(part === 'text') { + tx = helpers.getFirstFilled(trace.text, pt.pts); + if(isValidTextValue(tx)) text.push(tx); + } else if(part === 'value') { + text.push(helpers.formatPieValue(pt.v, separators)); + } else if(part === 'percent') { + text.push(helpers.formatPiePercent(pt.v / cd0.vTotal, separators)); + } } - if (hasValue) text.push(helpers.formatPieValue(pt.v, separators)); - if (hasPercent) text.push(helpers.formatPiePercent(pt.v / cd0.vTotal, separators)); pt.text = text.join('
'); } diff --git a/src/traces/sunburst/plot.js b/src/traces/sunburst/plot.js index 3708e2b8136..377bd4c02e2 100644 --- a/src/traces/sunburst/plot.js +++ b/src/traces/sunburst/plot.js @@ -544,58 +544,39 @@ exports.formatSliceLabel = function (pt, entry, trace, cd, fullLayout) { if (!texttemplate) { var parts = textinfo.split('+'); - var hasFlag = function (flag) { - return parts.indexOf(flag) !== -1; - }; var thisText = []; var tx; - if (hasFlag('label') && cdi.label) { - thisText.push(cdi.label); - } - - if (cdi.hasOwnProperty('v') && hasFlag('value')) { - thisText.push(helpers.formatValue(cdi.v, separators)); + var nPercent = 0; + for(var p = 0; p < parts.length; p++) { + var f = parts[p]; + if(f === 'percent parent' || f === 'percent entry' || f === 'percent root') nPercent++; } - - if (!isRoot) { - if (hasFlag('current path')) { + var hasMultiplePercents = nPercent > 1; + for(var i in parts) { + var part = parts[i]; + if(part === 'label' && cdi.label) { + thisText.push(cdi.label); + } else if(part === 'value' && cdi.hasOwnProperty('v')) { + thisText.push(helpers.formatValue(cdi.v, separators)); + } else if(part === 'text') { + tx = Lib.castOption(trace, cdi.i, 'text'); + if(Lib.isValidTextValue(tx)) thisText.push(tx); + } else if(!isRoot && part === 'current path') { thisText.push(helpers.getPath(pt.data)); + } else if(!isRoot && part === 'percent parent') { + tx = helpers.formatPercent(val / helpers.getValue(parent), separators); + if(hasMultiplePercents) tx += ' of parent'; + thisText.push(tx); + } else if(!isRoot && part === 'percent entry') { + tx = helpers.formatPercent(val / helpers.getValue(entry), separators); + if(hasMultiplePercents) tx += ' of entry'; + thisText.push(tx); + } else if(!isRoot && part === 'percent root') { + tx = helpers.formatPercent(val / helpers.getValue(hierarchy), separators); + if(hasMultiplePercents) tx += ' of root'; + thisText.push(tx); } - - var nPercent = 0; - if (hasFlag('percent parent')) nPercent++; - if (hasFlag('percent entry')) nPercent++; - if (hasFlag('percent root')) nPercent++; - var hasMultiplePercents = nPercent > 1; - - if (nPercent) { - var percent; - var addPercent = function (key) { - tx = helpers.formatPercent(percent, separators); - - if (hasMultiplePercents) tx += ' of ' + key; - thisText.push(tx); - }; - - if (hasFlag('percent parent') && !isRoot) { - percent = val / helpers.getValue(parent); - addPercent('parent'); - } - if (hasFlag('percent entry')) { - percent = val / helpers.getValue(entry); - addPercent('entry'); - } - if (hasFlag('percent root')) { - percent = val / helpers.getValue(hierarchy); - addPercent('root'); - } - } - } - - if (hasFlag('text')) { - tx = Lib.castOption(trace, cdi.i, 'text'); - if (Lib.isValidTextValue(tx)) thisText.push(tx); } return thisText.join('
'); diff --git a/test/image/baselines/display-text_zero-number.png b/test/image/baselines/display-text_zero-number.png index 508ca937acd..98a6c0e4b54 100644 Binary files a/test/image/baselines/display-text_zero-number.png and b/test/image/baselines/display-text_zero-number.png differ diff --git a/test/image/baselines/funnelarea_with_other_traces.png b/test/image/baselines/funnelarea_with_other_traces.png index 5dd61a8c47e..5c80f49151d 100644 Binary files a/test/image/baselines/funnelarea_with_other_traces.png and b/test/image/baselines/funnelarea_with_other_traces.png differ diff --git a/test/image/baselines/icicle_textposition.png b/test/image/baselines/icicle_textposition.png index 1c1fbfc12a8..5adf6f61194 100644 Binary files a/test/image/baselines/icicle_textposition.png and b/test/image/baselines/icicle_textposition.png differ diff --git a/test/image/baselines/icicle_with-without_values.png b/test/image/baselines/icicle_with-without_values.png index 1dca4bcfad0..65d621f79e4 100644 Binary files a/test/image/baselines/icicle_with-without_values.png and b/test/image/baselines/icicle_with-without_values.png differ diff --git a/test/image/baselines/sunburst_with-without_values.png b/test/image/baselines/sunburst_with-without_values.png index 6cfc8dd3e45..d6dca921c36 100644 Binary files a/test/image/baselines/sunburst_with-without_values.png and b/test/image/baselines/sunburst_with-without_values.png differ diff --git a/test/image/baselines/treemap_sunburst_marker_colors.png b/test/image/baselines/treemap_sunburst_marker_colors.png index 209427c1b2a..d57b8e15f6e 100644 Binary files a/test/image/baselines/treemap_sunburst_marker_colors.png and b/test/image/baselines/treemap_sunburst_marker_colors.png differ diff --git a/test/image/baselines/treemap_textposition.png b/test/image/baselines/treemap_textposition.png index 6959e66b90e..f571dcaec2a 100644 Binary files a/test/image/baselines/treemap_textposition.png and b/test/image/baselines/treemap_textposition.png differ diff --git a/test/image/baselines/treemap_with-without_values.png b/test/image/baselines/treemap_with-without_values.png index ad8a8f1e8d7..63e9c304855 100644 Binary files a/test/image/baselines/treemap_with-without_values.png and b/test/image/baselines/treemap_with-without_values.png differ diff --git a/test/jasmine/tests/funnel_test.js b/test/jasmine/tests/funnel_test.js index 0506aba9da3..19f169651e5 100644 --- a/test/jasmine/tests/funnel_test.js +++ b/test/jasmine/tests/funnel_test.js @@ -1757,4 +1757,25 @@ describe('funnel uniformtext', function() { })) .then(done, done.fail); }); + + it('should respect textinfo token order', function(done) { + Plotly.newPlot(gd, [{ + type: 'funnel', + y: ['Awareness', 'Interest', 'Action'], + x: [1000, 700, 400], + textinfo: 'percent initial+value' + }], {}) + .then(function() { + var textEls = gd.querySelectorAll('text.bartext'); + var textContent = Array.from(textEls).map(function(el) { + return el.textContent; + }); + expect(textContent.length).toBe(3); + expect(textContent[0]).toBe('100%1000'); + expect(textContent[1]).toBe('70%700'); + expect(textContent[2]).toBe('40%400'); + }) + .then(done, done.fail); + }); + }); diff --git a/test/jasmine/tests/pie_test.js b/test/jasmine/tests/pie_test.js index 5aad071dc2e..f316f9dff76 100644 --- a/test/jasmine/tests/pie_test.js +++ b/test/jasmine/tests/pie_test.js @@ -909,6 +909,27 @@ describe('Pie traces', function() { })) .then(done, done.fail); }); + + it('should respect textinfo token order', function(done) { + Plotly.newPlot(gd, [{ + type: 'pie', + labels: ['A', 'B', 'C'], + values: [10, 20, 70], + textinfo: 'percent+label', + sort: false + }], {}) + .then(function() { + var textEls = gd.querySelectorAll('text.slicetext'); + var textContent = Array.from(textEls).map(function(el) { + return el.textContent; + }); + expect(textContent.length).toBe(3); + expect(textContent[0]).toBe('10%A'); + expect(textContent[1]).toBe('20%B'); + expect(textContent[2]).toBe('70%C'); + }) + .then(done, done.fail); + }); }); describe('Pie texttemplate:', function() { diff --git a/test/jasmine/tests/sunburst_test.js b/test/jasmine/tests/sunburst_test.js index 09ae8bf4ad6..b0e6067aa63 100644 --- a/test/jasmine/tests/sunburst_test.js +++ b/test/jasmine/tests/sunburst_test.js @@ -1199,6 +1199,28 @@ describe('Test sunburst restyle:', function () { .then(_assert('back to dflt', ['Root\nnode0', 'B\nnode2', 'A\nnode1', 'b\nnode3'])) .then(done, done.fail); }); + + it('should respect textinfo token order', function(done) { + Plotly.newPlot(gd, [{ + type: 'sunburst', + labels: ['Root', 'A', 'B'], + parents: ['', 'Root', 'Root'], + values: [0, 10, 20], + textinfo: 'percent root+value+label' + }], {}) + .then(function() { + var layer = d3Select(gd).select('.sunburstlayer'); + var textContent = []; + layer.selectAll('text.slicetext').each(function() { + textContent.push(this.textContent); + }); + expect(textContent.length).toBe(3); + expect(textContent[0]).toBe('0Root'); + expect(textContent[1]).toBe('33%20B'); + expect(textContent[2]).toBe('17%10A'); + }) + .then(done, done.fail); + }); }); describe('Test sunburst tweening:', function () { diff --git a/test/jasmine/tests/treemap_test.js b/test/jasmine/tests/treemap_test.js index bf427dc4eae..96578d60ec5 100644 --- a/test/jasmine/tests/treemap_test.js +++ b/test/jasmine/tests/treemap_test.js @@ -1431,7 +1431,7 @@ describe('Test treemap restyle:', function () { } Plotly.newPlot(gd, mock) - .then(_assert('base', ['Root', 'B', 'A\nnode1', 'b\nnode3'])) + .then(_assert('base', ['Root', 'B', 'node1\nA', 'node3\nb'])) .then(function () { spyOn(Plots, 'doCalcdata').and.callThrough(); }) @@ -1442,9 +1442,9 @@ describe('Test treemap restyle:', function () { .then(_restyle({ textinfo: 'none' })) .then(_assert('no textinfo', ['Root', 'B', ' ', ' '])) // use one space character instead of a blank string to avoid jumps during transition .then(_restyle({ textinfo: 'label+text+value' })) - .then(_assert('show everything', ['Root', 'B', 'A\n1\nnode1', 'b\n3\nnode3'])) + .then(_assert('show everything', ['Root', 'B', 'A\nnode1\n1', 'b\nnode3\n3'])) .then(_restyle({ textinfo: null })) - .then(_assert('back to dflt', ['Root', 'B', 'A\nnode1', 'b\nnode3'])) + .then(_assert('back to dflt', ['Root', 'B', 'node1\nA', 'node3\nb'])) .then(done, done.fail); });