2017-10-26 14 views
1

d3.js.Myコードを使用してデータセットの強制有向グラフを実装しようとすると、エッジが描画されないうちにページ上部の小さなドットとしてノードが出力されます。シミュレーションからリンクが抜けた場合、ノードが描画されます正しく、私はそれが間違っているかもしれないどこのヒントが役立つだろう!強制的なグラフに線や辺を描く方法は?

link to codepen

データセット:あなたのlinks配列で

{ nodes": [ 
     { "country": "East Timor", "code": "tl" }, 
     { "country": "Canada", "code": "ca" }, 
     { "country": "Turkmenistan", "code": "tm" }, 
     { "country": "United States of America", "code": "us" }, 
     { "country": "Lithuania", "code": "lt" }, 
     { "country": "Cambodia", "code": "kh" }, 
     { "country": "Ethiopia", "code": "et" }, 
     { "country": "Swaziland", "code": "sz" }, 
     ], 
"links": [ 
     { "target": 66, "source": 0 }, 
     { "target": 3, "source": 1 }, 
     { "target": 100, "source": 2 }, 
     { "target": 40, "source": 2 }, 
     { "target": 125, "source": 2 }, 
     { "target": 147, "source": 2 }, 
     { "target": 159, "source": 3 }, 
     { "target": 18, "source": 3 }, 
     } 


let request = new XMLHttpRequest(); 
request.addEventListener("load", loaded); 

function loaded() { 
    const data = JSON.parse(request.responseText); 

    var nodes = data.nodes; 
    var links = data.links; 

    // sets up svg 
    var svg = d3.select("svg"), 
     width = +svg.attr("width"), 
     height = +svg.attr("height"); 


    // starts simulation 
    var simulation = d3 
    .forceSimulation() 
    .force(
    "link", 
    d3.forceLink().id(function(d) { 
     return d.country; 
    }) 
) 
    .force("charge", d3.forceManyBody()) 
    .force("center", d3.forceCenter(width/2, height/2)); 

    // creates lines in graph, 
    var link = svg 
    .append("g") 
    .attr("class", "links") 
    .selectAll("line") 
    .data(links) 
    .enter() 
    .append("line"); 


    var node = svg 
    .append("g") 
    .attr("class", "nodes") 
    .selectAll("circle") 
    //pass node data 
    .data(nodes) 

    .enter() 
    .append("circle") 
    .attr("r", 5) 

    .attr("fill", "red") 

    .call(
    d3 
    .drag() 
    .on("start", dragstarted) 
    .on("drag", dragged) 
    .on("end", dragended) 
); 

    simulation 
    // pass nodes,on tick call function ticked 
    .nodes(nodes) 
    .on("tick", ticked); 
    // pass links 
    simulation.force("link").links(links); 

    function ticked() { 
    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("cx", function(d) { 
     return d.x; 
    }) 
     .attr("cy", function(d) { 
     return d.y; 
    }); 
    } 

    function dragstarted(d) { 
    if (!d3.event.active) simulation.alphaTarget(0.3).restart(); 
    d.fx = d.x; 
    d.fy = d.y; 
    } 

    function dragged(d) { 
    d.fx = d3.event.x; 
    d.fy = d3.event.y; 
    } 

    function dragended(d) { 
    if (!d3.event.active) simulation.alphaTarget(0); 
    d.fx = null; 
    d.fy = null; 
    } 
} 
request.open(
    "GET", 
    "https://www.cs.mun.ca/~h65ped/Public/country%20data%20for%20force%20directed%20graph/countries.json", 
    true 
); 
request.send(null); 

答えて

1

ルック:

"links": [ 
    { "target": 66, "source": 0 }, 
    { "target": 3, "source": 1 }, 
    { "target": 100, "source": 2 }, 
    //etc.. 

あなたが見ることができるように、値として、どちらもターゲットにはが存在しないもソースのために。リンクはノードのインデックスを代わりに使用しています。

したがって、この...

.force("link", d3.forceLink().id(function(d) { 
    return d.country; 
})); 

は...間違っています。ただ、idを削除します。ここでは

.force("link", d3.forceLink()); 

が更新Codepenです:https://codepen.io/anon/pen/NwKvbg?editors=0010

関連する問題