d3.js Maximum call stack size exceeded error

狂风中的少年 提交于 2019-12-10 11:27:54

问题


When I try to layout my force-directed graph, the following is the error I receive. I read about this issue in Mike Bostock's github page and found that it might be due to NaN values of coordinates or all the points drawn at the same point. I checked into the console and I found that all of my points are getting drawn at the same X and Y values.

On an example data, the code worked perfectly well but no more now. My data goes like 45-50 levels away from the center node. I have successfully made a tree layout with this data. Wanted to try the force directed layout but it did not work.

Any help regarding how to draw the nodes on separate coordinates would be much appreciated.

<!DOCTYPE html>
<meta charset="utf-8">
<style>

.node {
  stroke: #fff;
  stroke-width: 1.5px;
}

.link {
  stroke: #999;
  stroke-opacity: .6;
}

</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>

var margin = {top: 10, right: 10, bottom: 20, left: 40},
    width = 1300 - margin.left - margin.right,
    height = 800 - margin.top - margin.bottom;

var color = d3.scale.category20();

var force = d3.layout.force().charge(-120)
            .linkDistance(30)
            .size([width, height]);

var svg = d3.select("body").append("svg:svg")
    .attr("width", width)
    .attr("height", height)
    //.attr("pointer-events","all")
    .append('svg:g')
    //.call(d3.behavior.zoom().translate([100,50]).scale(.5).on("zoom",redraw))
    .append('svg:g')
    .attr("transform","translate(100,50)scale(.5,.5)");

svg.append('svg:rect')
   .attr('width', width)
   .attr('height', height)
   .attr('fill','white')
   .attr('opacity',0);

function redraw() {
  var trans = d3.event.translate;
  var scale = d3.event.scale;
  svg.attr("transform",
      "translate(" + trans + ")"
      + " scale(" + scale + ")");
};

d3.json("test_data.json", function(error, graph) {

  var nodeMap = {};
  graph.nodes.forEach(function(x) { nodeMap[x.name] = x; });
  graph.links = graph.links.map(
  function(x) 
  {
    return {
        source: nodeMap[x.source],
        target: nodeMap[x.target],
        value: x.value
        };
  });
    console.log(graph.nodes);
    console.log(graph.links);
  force
      .nodes(graph.nodes)
      .links(graph.links)
      .start();

  var link = svg.selectAll(".link")
      .data(graph.links)
      .enter().append("line")
      .attr("class", "link")
      .style("stroke", function(d) { return color(d.value); })
      .style("stroke-width", function(d) { 
        //console.log(d.value);
        return Math.sqrt(d.value); });

  var node = svg.selectAll(".node")
      .data(graph.nodes)

      .enter().append("circle")
      .attr("class", "node")
      .attr("r", 5)
      .style("fill", function(d) { return color(d.value); })
      .call(force.drag)
      .on("mousedown",
        function(d) {
          d.fixed = true;
          d3.select(this).classed("sticky", true);
        }
          )
      .on("mouseover",fade(0.1))
      .on("mouseout",fade(1));


    var linkedByIndex = {};
    graph.links.forEach(function(d) {
        linkedByIndex[d.source.index + "," + d.target.index] = 1;
    });

    function isConnected(a, b) {
        return linkedByIndex[a.index + "," + b.index] || linkedByIndex[b.index + "," + a.index] || a.index == b.index;
    }

  node.append("title")
      .text(function(d) { 
        return "Name : "+d.name+"\n"+"Parent: "+d.parent +"\n"+"Relationship: "+ d.relationship +"\n"+ "Creation Date: "+ d.cod +"\n"; });

    function fade(opacity)
  {
            return function(d) {
            node.style("stroke-opacity", function(o) {
                thisOpacity = isConnected(d, o) ? 1 : opacity;
                this.setAttribute('fill-opacity', thisOpacity);
                return thisOpacity;
            });

            link.style("stroke-opacity", opacity).style("stroke-opacity", function(o) {
                return o.source === d || o.target === d ? 1 : opacity;
            });
        };
  }

 force.on("tick", function() {

    link.attr("x1", function(d) { return d.source.x; })
        .attr("y1", function(d) { return d.source.y; })
        .attr("x2", function(d) { return d.target.x; })
        .attr("y2", function(d) { return d.target.y; });

    node
    .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
    /*node.attr("cx", function(d) { return d.x; })
        .attr("cy", function(d) { return d.y; });*/
  });
});

</script>

The JSON looks like:

{
    "links": [
        {
            "source": "Me",
            "target": "Adam",
            "value": 10
        },
        {
            "source": "Me",
            "target": "You",
            "value": 10
        }
    ], "nodes": [
             {
            "ancestor": "Adam",
            "cod": 19061964,
            "distance": 0,
            "name": "Adam",
            "parent": null,
            "relationship": null,
            "value": 10
        },
        {
            "ancestor": "Adam",
            "cod": 13032003,
            "distance": 1,
            "name": "Me",
            "parent": "You",
            "relationship": "Father",
            "value": 10
        }
    ]
}

EDIT: I get the error in the following statement:

force
      .nodes(graph.nodes)
      .links(graph.links)
      .start();

highlighting:

"start();"

回答1:


In your data your links are to names as opposed to indices. Check out the example data from http://bl.ocks.org/mbostock/4062045.

Links have the form: {"source":1,"target":0,"value":1}, which points to the index of the node.



来源:https://stackoverflow.com/questions/18279922/d3-js-maximum-call-stack-size-exceeded-error

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!