Uncaught TypeError: Cannot call method 'push&#

2020-02-13 04:34发布

问题:

I can't figure out why I'm getting this error for the life of me (using a force layout). It started when I switched over to reading my nodes from a json file. If I uncomment the lines below it doesn't throw an error. If I leave as is, I get "Cannot call method 'push' of undefined". I'm not sure what the issue is. Am I missing anything?

<html>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js"></script>
<script>

   d3.json("http://katejustin.com/autosys1.json", function(data) {

   //var nodes = {};

   //data.links.forEach(function(link) {
   //   link.source = nodes[link.source] || (nodes[link.source] = {name: link.source});
   //   link.target = nodes[link.target] || (nodes[link.target] = {name: link.target}); });


var width = 200,
    height = 200;

var svg = d3.select("body").append("svg:svg")
    .attr("width", width)
    .attr("height", height);

var force = d3.layout.force()
    //.nodes(d3.values(nodes))
    .nodes(data.nodes)
    .links(data.links)
    .size([width, height])
    .distance(100)
    .charge(-1000)
    .start();
});
</script>
</html>

回答1:

The problem is that you try to access the nodes by name in links. In the original implementation you access the nodes by index.

Here is a trick that I usually use in these situations, even if I am sure that something easier exists:

var findNode = function(id) {
    for (var i in force.nodes()) {
        if (force.nodes()[i]["name"] == id) return force.nodes()[i]
    };
    return null;
}

var pushLink = function (link) {
    //console.log(link)
    if(findNode(link.source)!= null && findNode(link.target)!= null) {        
        force.links().push ({
            "source":findNode(link.source),
            "target":findNode(link.target)
        })
    }
}

var force = d3.layout.force()
    .nodes(data.nodes)
    .size([width, height])
    .distance(100)
    .charge(-1000)
    .start();

data.links.forEach(pushLink)

So, the goal of these functions is to replace for each link, its source and its destination by the actual object representing the node in force.nodes.

You can find a working jsFiddle here: http://jsfiddle.net/chrisJamesC/nrbQ4/1/ (See via the console as nothing is displayed in the visualization).