简体   繁体   English

D3强制定向未捕获类型错误

[英]D3 force directed uncaught type error

I am trying to generate a D3 force direct graph based on the code here . 我正在尝试根据此处的代码生成D3强制直接图。 I generated the following script: 我生成了以下脚本:

<script src='http://d3js.org/d3.v3.min.js'></script>
    <script>
    var width = 640, height = 480;

var nodes = [{"name": "xxx"},{"name": "xxx"},{"name": "xxx"},{"name": "xxx"},{"name": "xxx"},{"name": "xxx"},{"name": "xxx"},{"name": "xxx"},{"name": "xxx"},{"name": "xxx"},{"name": "xxx"},{"name": "xxx"},{"name": "xxx"},{"name": "xxx"},{"name": "xxx"},{"name": "xxx"},{"name": "xxx"},{"name": "xxx"},{"name": "xxx"},{"name": "xxx"},{"name": "xxx"},{"name": "xxx"},{"name": "xxx"},{"name": "xxx"},{"name": "xxx"},{"name": "xxx"},{"name": "xxx"},{"name": "xxx"},{"name": "xxxn"},{"name": "xxx"},{"name": "xxx"},{"name": "xxx"},{"name": "xxx"},{"name": "xxx"},{"name": "xxx"},{"name": "xxx"},{"name": "xxx"}];
var links = [{"source": "0", "target": "1", "value": 1},{"source": "2", "target": "1", "value": 1},{"source": "3", "target": "1", "value": 1},{"source": "4", "target": "1", "value": 1},{"source": "5", "target": "1", "value": 1},{"source": "6", "target": "1", "value": 1},{"source": "7", "target": "1", "value": 1},{"source": "8", "target": "1", "value": 1},{"source": "9", "target": "1", "value": 1},{"source": "10", "target": "1", "value": 1},{"source": "11", "target": "1", "value": 1},{"source": "12", "target": "1", "value": 1},{"source": "13", "target": "1", "value": 1},{"source": "14", "target": "1", "value": 1},{"source": "1", "target": "15", "value": 1},{"source": "1", "target": "16", "value": 1},{"source": "1", "target": "17", "value": 1},{"source": "1", "target": "18", "value": 1},{"source": "1", "target": "19", "value": 1},{"source": "1", "target": "20", "value": 1},{"source": "1", "target": "21", "value": 1},{"source": "1", "target": "22", "value": 1},{"source": "1", "target": "23", "value": 1},{"source": "1", "target": "24", "value": 1},{"source": "1", "target": "25", "value": 1},{"source": "1", "target": "26", "value": 1},{"source": "1", "target": "27", "value": 1},{"source": "1", "target": "28", "value": 1},{"source": "1", "target": "29", "value": 1},{"source": "1", "target": "30", "value": 1},{"source": "1", "target": "31", "value": 1},{"source": "1", "target": "32", "value": 1},{"source": "1", "target": "33", "value": 1},{"source": "1", "target": "34", "value": 1},{"source": "1", "target": "35", "value": 1},{"source": "1", "target": "36", "value": 1}];
    var svg = d3.select('body').append('svg')
        .attr('width', width)
        .attr('height', height);

    var force = d3.layout.force()
        .size([width, height])
        .nodes(nodes)
        .links(links);

    force.linkDistance(width/2);

    var link = svg.selectAll('.link')
        .data(links)
        .enter().append('line')
        .attr('class', 'link');

    var node = svg.selectAll('.node')
        .data(nodes)
        .enter().append('circle')
        .attr('class', 'node');

    force.on('end', function() {
        node.attr('r', width/25)
            .attr('cx', function(d) { return d.x; })
            .attr('cy', function(d) { return d.y; });
        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; });

    });    
    force.start();

</script>

(the xxxs are actual names). (xxx是实际名称)。 It is throwing "Uncaught TypeError: Cannot read property 'push' of undefined". 它抛出“未捕获的TypeError:无法读取未定义的属性'push'”。 I read in another thread that this can be caused if the nodes are improperly numbered, but I am numbering the nodes from zero and as far as I can tell there are no nodes in links that don't exist in nodes. 我在另一个线程中读到,如果节点编号不正确,可能会导致这种情况,但是我是从零开始对节点进行编号,据我所知,节点中不存在不存在的节点。 Can anyone tell me what's wrong? 谁能告诉我怎么了?

Look at the objects in your links array: 查看links数组中的对象:

[{"source": "0", "target": "1", "value": 1},...
//this is a string ---------^

You don't have numbers here, just strings. 您在这里没有数字,只有字符串。 For the force to work, you have to set the number of the source and the target. 对于力量的工作,你必须设置源和目标的数量

A simple solution is coercing: 一个简单的解决方案是强制:

links.forEach(function(d) {
    d.source = +d.source;
    d.target = +d.target;
})

Here is the resulting code: 这是结果代码:

 var nodes = [{ "name": "xxx" }, { "name": "xxx" }, { "name": "xxx" }, { "name": "xxx" }, { "name": "xxx" }, { "name": "xxx" }, { "name": "xxx" }, { "name": "xxx" }, { "name": "xxx" }, { "name": "xxx" }, { "name": "xxx" }, { "name": "xxx" }, { "name": "xxx" }, { "name": "xxx" }, { "name": "xxx" }, { "name": "xxx" }, { "name": "xxx" }, { "name": "xxx" }, { "name": "xxx" }, { "name": "xxx" }, { "name": "xxx" }, { "name": "xxx" }, { "name": "xxx" }, { "name": "xxx" }, { "name": "xxx" }, { "name": "xxx" }, { "name": "xxx" }, { "name": "xxx" }, { "name": "xxxn" }, { "name": "xxx" }, { "name": "xxx" }, { "name": "xxx" }, { "name": "xxx" }, { "name": "xxx" }, { "name": "xxx" }, { "name": "xxx" }, { "name": "xxx" }]; var links = [{ "source": "0", "target": "1", "value": 1 }, { "source": "2", "target": "1", "value": 1 }, { "source": "3", "target": "1", "value": 1 }, { "source": "4", "target": "1", "value": 1 }, { "source": "5", "target": "1", "value": 1 }, { "source": "6", "target": "1", "value": 1 }, { "source": "7", "target": "1", "value": 1 }, { "source": "8", "target": "1", "value": 1 }, { "source": "9", "target": "1", "value": 1 }, { "source": "10", "target": "1", "value": 1 }, { "source": "11", "target": "1", "value": 1 }, { "source": "12", "target": "1", "value": 1 }, { "source": "13", "target": "1", "value": 1 }, { "source": "14", "target": "1", "value": 1 }, { "source": "1", "target": "15", "value": 1 }, { "source": "1", "target": "16", "value": 1 }, { "source": "1", "target": "17", "value": 1 }, { "source": "1", "target": "18", "value": 1 }, { "source": "1", "target": "19", "value": 1 }, { "source": "1", "target": "20", "value": 1 }, { "source": "1", "target": "21", "value": 1 }, { "source": "1", "target": "22", "value": 1 }, { "source": "1", "target": "23", "value": 1 }, { "source": "1", "target": "24", "value": 1 }, { "source": "1", "target": "25", "value": 1 }, { "source": "1", "target": "26", "value": 1 }, { "source": "1", "target": "27", "value": 1 }, { "source": "1", "target": "28", "value": 1 }, { "source": "1", "target": "29", "value": 1 }, { "source": "1", "target": "30", "value": 1 }, { "source": "1", "target": "31", "value": 1 }, { "source": "1", "target": "32", "value": 1 }, { "source": "1", "target": "33", "value": 1 }, { "source": "1", "target": "34", "value": 1 }, { "source": "1", "target": "35", "value": 1 }, { "source": "1", "target": "36", "value": 1 }]; links.forEach(function(d) { d.source = +d.source; d.target = +d.target; }) var width = 400, height = 400; var svg = d3.select('body').append('svg') .attr('width', width) .attr('height', height); var force = d3.layout.force() .size([width, height]) .nodes(nodes) .links(links); force.linkDistance(width / 2); var link = svg.selectAll('.link') .data(links) .enter().append('line') .attr('class', 'link'); var node = svg.selectAll('.node') .data(nodes) .enter().append('circle') .attr('class', 'node'); force.on("start", function(){ svg.append("text") .attr("class", "text") .attr("x", 150) .attr("y", 80) .text("Calculating..."); }); force.on('end', function() { svg.select(".text").remove(); node.attr('r', width / 25) .attr('cx', function(d) { return dx; }) .attr('cy', function(d) { return dy; }); 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; }); }); force.start(); 
 <script src='https://d3js.org/d3.v3.min.js'></script> 

EDIT: Since you're using .on("end" to paint your nodes, you'll have to wait until the force finishes. 编辑:由于您正在使用.on("end"来绘制节点,因此,您必须等到强制完成为止。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM