diff --git a/src/traces/sankey/plot.js b/src/traces/sankey/plot.js index 2ce25e533f6..1f120266ad6 100644 --- a/src/traces/sankey/plot.js +++ b/src/traces/sankey/plot.js @@ -145,7 +145,7 @@ module.exports = function plot(gd, calcData) { y: hoverCenterY - rootBBox.top, name: d3.format(d.valueFormat)(d.link.value) + d.valueSuffix, text: [ - d.link.label, + d.link.label || '', ['Source:', d.link.source.label].join(' '), ['Target:', d.link.target.label].join(' ') ].filter(renderableValuePresent).join('
'), diff --git a/test/jasmine/tests/sankey_test.js b/test/jasmine/tests/sankey_test.js index 93f8f8b59e7..571c74f33aa 100644 --- a/test/jasmine/tests/sankey_test.js +++ b/test/jasmine/tests/sankey_test.js @@ -112,6 +112,8 @@ describe('sankey tests', function() { expect(fullTrace.link.target) .toEqual([], 'presence of link target array is guaranteed'); + expect(fullTrace.link.label) + .toEqual([], 'presence of link target array is guaranteed'); }); it('\'Sankey\' specification should have proper types', @@ -179,6 +181,40 @@ describe('sankey tests', function() { }); + it('does not fill \'link\' labels even if not specified', function() { + + var fullTrace = _supply({ + node: { + label: ['a', 'b'] + }, + link: { + source: [0, 1], + target: [1, 0], + value: [1, 2] + } + }); + + expect(Lib.isArray(fullTrace.link.label)).toBe(true, 'must be an array'); + expect(fullTrace.link.label).toEqual([], 'an array of empty strings'); + }); + + it('preserves \'link\' labels if specified', function() { + + var fullTrace = _supply({ + node: { + label: ['a', 'b'] + }, + link: { + source: [0, 1], + target: [1, 0], + value: [1, 2], + label: ['a', 'b'] + } + }); + + expect(Lib.isArray(fullTrace.link.label)).toBe(true, 'must be an array'); + expect(fullTrace.link.label).toEqual(['a', 'b'], 'an array of the supplied values'); + }); }); describe('sankey calc', function() { @@ -316,29 +352,6 @@ describe('sankey tests', function() { describe('Test hover/click interactions:', function() { afterEach(destroyGraphDiv); - function assertLabel(content, style) { - var g = d3.selectAll('.hovertext'); - var lines = g.selectAll('.nums .line'); - var name = g.selectAll('.name'); - - expect(lines.size()).toBe(content.length - 1); - - lines.each(function(_, i) { - expect(d3.select(this).text()).toBe(content[i]); - }); - - expect(name.text()).toBe(content[content.length - 1]); - - var path = g.select('path'); - expect(path.style('fill')).toEqual(style[0], 'bgcolor'); - expect(path.style('stroke')).toEqual(style[1], 'bordercolor'); - - var text = g.select('text.nums'); - expect(parseInt(text.style('font-size'))).toEqual(style[2], 'font.size'); - expect(text.style('font-family').split(',')[0]).toEqual(style[3], 'font.family'); - expect(text.style('fill')).toEqual(style[4], 'font.color'); - } - it('should shows the correct hover labels', function(done) { var gd = createGraphDiv(); var mockCopy = Lib.extendDeep({}, mock); @@ -409,6 +422,30 @@ describe('sankey tests', function() { .catch(fail) .then(done); }); + + it('should show correct hover labels even if there is no link.label supplied', function(done) { + var gd = createGraphDiv(); + var mockCopy = Lib.extendDeep({}, mock); + delete mockCopy.data[0].link.label; + + function _hover(px, py) { + mouseEvent('mousemove', px, py); + mouseEvent('mouseover', px, py); + delete gd._lastHoverTime; + } + + Plotly.plot(gd, mockCopy) + .then(function() { + _hover(450, 300); + + assertLabel( + ['Source: Solid', 'Target: Industry', '46TWh'], + ['rgb(0, 0, 96)', 'rgb(255, 255, 255)', 13, 'Arial', 'rgb(255, 255, 255)'] + ); + }) + .catch(fail) + .then(done); + }); }); describe('Test hover/click event data:', function() { @@ -520,3 +557,31 @@ describe('sankey tests', function() { }); }); }); + +function assertLabel(content, style) { + var g = d3.selectAll('.hovertext'); + var lines = g.selectAll('.nums .line'); + var name = g.selectAll('.name'); + var tooltipBoundingBox = g.node().getBoundingClientRect(); + var nameBoundingBox = name.node().getBoundingClientRect(); + + expect(tooltipBoundingBox.top <= nameBoundingBox.top); + expect(tooltipBoundingBox.bottom >= nameBoundingBox.bottom); + + expect(lines.size()).toBe(content.length - 1); + + lines.each(function(_, i) { + expect(d3.select(this).text()).toBe(content[i]); + }); + + expect(name.text()).toBe(content[content.length - 1]); + + var path = g.select('path'); + expect(path.style('fill')).toEqual(style[0], 'bgcolor'); + expect(path.style('stroke')).toEqual(style[1], 'bordercolor'); + + var text = g.select('text.nums'); + expect(parseInt(text.style('font-size'))).toEqual(style[2], 'font.size'); + expect(text.style('font-family').split(',')[0]).toEqual(style[3], 'font.family'); + expect(text.style('fill')).toEqual(style[4], 'font.color'); +}