1

I'm attempting to create a Sankey diagram, and while I am now able to load my source codes, I am running into a slight issue between the sankey.js, and my html code.

When I run the HTML code, I get an error message like this: Uncaught TypeError: Cannot call method 'push' of undefined

This is where the error link directs me to:

// Populate the sourceLinks and targetLinks for each node. 
// Also, if the source and target are not objects, assume they are indices.  
function computeNodeLinks() {    
  nodes.forEach(function(node) {      
    node.sourceLinks = [];      
    node.targetLinks = [];    
  });
  links.forEach(function(link) {      
    var source = link.source,          
    target = link.target;      
    if (typeof source === "name") source = link.source = nodes[link.source];      
    if (typeof target === "name") target = link.target = nodes[link.target];      
    source.sourceLinks.push(link);      
    target.targetLinks.push(link);    
  });  
}

This is the input in the HTML code (my data is taken from a csv file).

//set up graph in same style as original example but empty
graph = {"nodes" : [], "links" : []};

data.forEach(function (d) {
  graph.nodes.push({ "name": d.source });
  graph.nodes.push({ "name": d.target });
  graph.links.push({ 
    "source": d.source,
    "target": d.target,
    "value": +d.value
  });
});

My question is: is the sankey.js relying on the assumption that my data is from a json file?. If so, how can I adjust it so that it is compatible with a csv file? The data is saved as a csv file listed below:

source,target,value
Barry,Elvis,2
Frodo,Elvis,2
Frodo,Sarah,2
Barry,Alice,2
Elvis,Sarah,2
Elvis,Alice,2
Sarah,Alice,4
VividD
  • 10,456
  • 6
  • 64
  • 111
jducz
  • 23
  • 1
  • 5

1 Answers1

0

You need to use either objects present in nodes or indices into nodes in the .source and .target of a link. It looks like you're using the strings from the CSV for this, which will break in the manner you have observed.

To fix, keep references to the objects you're creating and use those in the links:

data.forEach(function (d) {
      var source = { "name": d.source },
          target = { "name": d.target };
      graph.nodes.push(source);
      graph.nodes.push(target);
      graph.links.push({ "source": source,
                         "target": target,
                         "value": +d.value });
     });
Lars Kotthoff
  • 107,425
  • 16
  • 204
  • 204
  • Excellent! This worked great. Silly question: Would I define value in the same manner (and include it in the sankey.js script as well)? Or does it need to be defined differently? – jducz Dec 13 '13 at 16:54
  • I'm not sure if I understand your question. What's "value"? – Lars Kotthoff Dec 13 '13 at 17:52
  • Value is defined as the size of each node (Below is how it's created in the initial sankey.js script): // Compute the value (size) of each node by summing the associated links. function computeNodeValues() { nodes.forEach(function(node) { node.value = Math.max( d3.sum(node.sourceLinks, value), d3.sum(node.targetLinks, value) While the html script has value in there, it keeps telling me that it's not defined. I know value is a different entity as it's not a variable, but how would I define it? – jducz Dec 13 '13 at 17:56
  • It looks like it's assuming that each link has a `.value` attribute, so you would have to specify that there. So it should work with the data structure you're producing. – Lars Kotthoff Dec 13 '13 at 18:40