diff --git a/src/traces/sankey/attributes.js b/src/traces/sankey/attributes.js index f45acc67075..94dd451bc5e 100644 --- a/src/traces/sankey/attributes.js +++ b/src/traces/sankey/attributes.js @@ -84,6 +84,9 @@ var attrs = module.exports = overrideAll({ description: 'Sets the font for node labels' }), + // Remove top-level customdata + customdata: undefined, + node: { label: { valType: 'data_array', @@ -128,6 +131,13 @@ var attrs = module.exports = overrideAll({ 'what is beneath the node.' ].join(' ') }, + customdata: { + valType: 'data_array', + editType: 'calc', + description: [ + 'Assigns extra data to each node.' + ].join(' ') + }, line: { color: { valType: 'color', @@ -200,6 +210,13 @@ var attrs = module.exports = overrideAll({ 'If `link.color` is omitted, then by default, a translucent grey link will be used.' ].join(' ') }, + customdata: { + valType: 'data_array', + editType: 'calc', + description: [ + 'Assigns extra data to each link.' + ].join(' ') + }, line: { color: { valType: 'color', diff --git a/src/traces/sankey/calc.js b/src/traces/sankey/calc.js index 21514ec0c85..84de346cdf8 100644 --- a/src/traces/sankey/calc.js +++ b/src/traces/sankey/calc.js @@ -22,6 +22,7 @@ function convertToD3Sankey(trace) { var links = []; var hasLinkColorArray = isArrayOrTypedArray(linkSpec.color); + var hasLinkCustomdataArray = isArrayOrTypedArray(linkSpec.customdata); var linkedNodes = {}; var components = {}; @@ -103,6 +104,7 @@ function convertToD3Sankey(trace) { pointNumber: i, label: label, color: hasLinkColorArray ? linkSpec.color[i] : linkSpec.color, + customdata: hasLinkCustomdataArray ? linkSpec.customdata[i] : linkSpec.customdata, concentrationscale: concentrationscale, source: source, target: target, @@ -116,6 +118,7 @@ function convertToD3Sankey(trace) { // Process nodes var totalCount = nodeCount + groups.length; var hasNodeColorArray = isArrayOrTypedArray(nodeSpec.color); + var hasNodeCustomdataArray = isArrayOrTypedArray(nodeSpec.customdata); var nodes = []; for(i = 0; i < totalCount; i++) { if(!linkedNodes[i]) continue; @@ -126,7 +129,8 @@ function convertToD3Sankey(trace) { childrenNodes: [], pointNumber: i, label: l, - color: hasNodeColorArray ? nodeSpec.color[i] : nodeSpec.color + color: hasNodeColorArray ? nodeSpec.color[i] : nodeSpec.color, + customdata: hasNodeCustomdataArray ? nodeSpec.customdata[i] : nodeSpec.customdata }); } diff --git a/src/traces/sankey/defaults.js b/src/traces/sankey/defaults.js index 797a20ec986..9a73591eb12 100644 --- a/src/traces/sankey/defaults.js +++ b/src/traces/sankey/defaults.js @@ -50,6 +50,7 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout coerceNode('color', nodeOut.label.map(function(d, i) { return Color.addOpacity(defaultNodePalette(i), 0.8); })); + coerceNode('customdata'); // link attributes var linkIn = traceIn.link || {}; @@ -73,6 +74,7 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout 'rgba(0, 0, 0, 0.2)'; coerceLink('color', Lib.repeat(defaultLinkColor, linkOut.value.length)); + coerceLink('customdata'); handleArrayContainerDefaults(linkIn, linkOut, { name: 'colorscales', diff --git a/test/jasmine/tests/sankey_test.js b/test/jasmine/tests/sankey_test.js index 5f0f02e5c07..01ead26d544 100644 --- a/test/jasmine/tests/sankey_test.js +++ b/test/jasmine/tests/sankey_test.js @@ -816,6 +816,10 @@ describe('sankey tests', function() { it('should show the correct hover labels when hovertemplate is specified', function(done) { var gd = createGraphDiv(); var mockCopy = Lib.extendDeep({}, mock); + mockCopy.data[0].node.customdata = []; + mockCopy.data[0].node.customdata[4] = ['nodeCustomdata0', 'nodeCustomdata1']; + mockCopy.data[0].link.customdata = []; + mockCopy.data[0].link.customdata[61] = ['linkCustomdata0', 'linkCustomdata1']; Plotly.plot(gd, mockCopy).then(function() { _hover(404, 302); @@ -836,15 +840,15 @@ describe('sankey tests', function() { // Test (node|link).hovertemplate .then(function() { return Plotly.restyle(gd, { - 'node.hovertemplate': 'hovertemplate
%{value}
%{value:0.2f}%{fullData.name}', - 'link.hovertemplate': 'hovertemplate
source: %{source.label}
target: %{target.label}
size: %{value:0.0f}TWh%{fullData.name}' + 'node.hovertemplate': 'hovertemplate
%{value}
%{value:0.2f}
%{customdata[0]}/%{customdata[1]}%{fullData.name}', + 'link.hovertemplate': 'hovertemplate
source: %{source.label}
target: %{target.label}
size: %{value:0.0f}TWh
%{customdata[1]}%{fullData.name}' }); }) .then(function() { _hover(404, 302); assertLabel( - [ 'hovertemplate', '447TWh', '447.48', 'trace 0'], + [ 'hovertemplate', '447TWh', '447.48', 'nodeCustomdata0/nodeCustomdata1', 'trace 0'], ['rgb(148, 103, 189)', 'rgb(255, 255, 255)', 13, 'Arial', 'rgb(255, 255, 255)'] ); }) @@ -852,7 +856,7 @@ describe('sankey tests', function() { _hover(450, 300); assertLabel( - ['hovertemplate', 'source: Solid', 'target: Industry', 'size: 46TWh', 'trace 0'], + ['hovertemplate', 'source: Solid', 'target: Industry', 'size: 46TWh', 'linkCustomdata1', 'trace 0'], ['rgb(0, 0, 96)', 'rgb(255, 255, 255)', 13, 'Arial', 'rgb(255, 255, 255)'] ); })