簡體   English   中英

如何在d3上標注力導向圖?

[英]How to label a force directed Graph on d3?

我正在使用d3.js創建一個力導向圖,無法通過用文本標記節點的觀點。 我在StackOverflow和在線教程上嘗試了無數答案,但我相信問題出在我對Java基本的理解上。 在此處輸入圖片說明

我嘗試了.attr / .append / .text的不同組合,以使文本從源和目標中出現,但沒有任何反應。

這是有問題的區域:

node.append("title")
    .text(function (d) {return d.target});

node.append("text")
    .attr("dy", -3)
    .text(function (d) {return d.source})
    .attr("class", "font");

這是樣式的簡化摘錄:

<style>

.node {
    fill: #ccc; /* Fill of the circles*/
    stroke: #ffffff;
    stroke-width: 2px;
}

.font {
    font: 10px;
    font-family: sans-serif;

}

.link {
    stroke: #777; /* Colour of the lines*/
    stroke-width: 2px;
}
</style>

這是腳本的簡化摘錄:

var width = 640,
    height = 480;

    var links = [
    //this is an array
    {source: "Germany", target: "name1"},
    {source: "Germany", target: "name2"},
    {source: "Nigeria", target: "name3"},
    {source: "Environment", target: "name4"},

    ]; 

    //setting up the nodes:

    var nodes = {};


    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});    
    });


//add svg to the body, this is where the actual d3 starts

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

var force = d3.layout.force() //Here we specify the paramaters
    .size([width,height])
    .nodes(d3.values(nodes)) //this is where we pass the nodes of our dataset
    .links(links) // source of links
    .on("tick", tick) //on click of the nodes
    .linkDistance(300) //How far apart the nodes are
    .start(); //Start to render

//add link and nodes
var link = svg.selectAll(".link")
    .data(links) //get the data
    .enter().append('line') //binds the data in the links array to the svg 
    .attr("class", "link") //css styling

var node = svg.selectAll(".node")
    .data(force.nodes()) //way to reference the nodes in the force layout
    .enter().append("circle") 
    .attr("class", "node") //attribute CSS styling
    .attr("r", width * 0.03); //radius of the circle

//text element
node.append("title")
    .text(function (d) {return d.target});

node.append("text")
    .attr("dy", -3)
    .text(function (d) {return d.source})
    .attr("class", "font");

//creating the tick function from the force variable
//the "e" paramater can be used for positioning

function tick(e) {
    node.attr("cx", function(d) {return d.x;}) 
        .attr("cy", function(d) {return d.y;})
        .call(force.drag); //the relative location will activate a drag once the node is clicked

    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; })

    }
</script>

我目前沒有收到任何錯誤消息,這使我很難調試該文件。 任何幫助表示贊賞。 謝謝!

您的代碼中有兩個問題。

第一個問題是您的node選擇:

var node = svg.selectAll(".node")
    .data(force.nodes())
    .enter().append("circle") 
    //etc...

如您所見,這是一些圈子。 稍后,當您嘗試...

node.append("text")

...這是行不通的,因為您不能將<text>元素附加到<circle>元素。

最常見的解決方案是使node成為組( <g> )選擇,並在其上同時添加圓圈和文本。

第二個問題是節點的數據。 您的文本中包含以下內容:

node.append("text")
    .text(function (d) {return d.source})

但是,數據中沒有名為source屬性。 您擁有的唯一屬性是name

這是您所做的更改的代碼:

 var width = 640, height = 480; var links = [ //this is an array { source: "Germany", target: "name1" }, { source: "Germany", target: "name2" }, { source: "Nigeria", target: "name3" }, { source: "Environment", target: "name4" }, ]; //setting up the nodes: var nodes = {}; 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 }); }); //add svg to the body, this is where the actual d3 starts var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height); var force = d3.layout.force() //Here we specify the paramaters .size([width, height]) .nodes(d3.values(nodes)) //this is where we pass the nodes of our dataset .links(links) // source of links .on("tick", tick) //on click of the nodes .linkDistance(300) //How far apart the nodes are .start(); //Start to render //add link and nodes var link = svg.selectAll(".link") .data(links) //get the data .enter().append('line') //binds the data in the links array to the svg .attr("class", "link") //css styling var node = svg.selectAll(".node") .data(force.nodes()) //way to reference the nodes in the force layout .enter().append("g"); node.append("circle") .attr("class", "node") .attr("r", width * 0.03); //radius of the circle node.append("text") .attr("dy", -3) .text(function(d) { return d.name }) .attr("class", "font"); //creating the tick function from the force variable //the "e" paramater can be used for positioning function tick(e) { node.attr("transform", function(d) { return "translate(" + [dx, dy] + ")" }) .call(force.drag); //the relative location will activate a drag once the node is clicked 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 { fill: #ccc; /* Fill of the circles*/ stroke: #ffffff; stroke-width: 2px; } .font { font: 10px; font-family: sans-serif; } .link { stroke: #777; /* Colour of the lines*/ stroke-width: 2px; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM