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)']
);
})