简体   繁体   English

如何在d3上标注力导向图?

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

I am creating a force-directed graph with d3.js and can't get passed the point of labelling the nodes with text. 我正在使用d3.js创建一个力导向图,无法通过用文本标记节点的观点。 I have tried countless answers here on StackOverflow and online tutorials, yet I believe that the problems lie in my fundamental Javascript understanding. 我在StackOverflow和在线教程上尝试了无数答案,但我相信问题出在我对Java基本的理解上。 在此处输入图片说明

I have tried different combinations of .attr/.append/.text to get the text from the source and target to appear, but nothing ever happens. 我尝试了.attr / .append / .text的不同组合,以使文本从源和目标中出现,但没有任何反应。

This is the area in question: 这是有问题的区域:

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

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

This is a simplified excerpt of the style: 这是样式的简化摘录:

<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>

This is a simplified excerpt of the script: 这是脚本的简化摘录:

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>

I'm currently not getting any error messages which is making it hard for me to debug the file. 我目前没有收到任何错误消息,这使我很难调试该文件。 Any help is appreciated. 任何帮助表示赞赏。 Thank you! 谢谢!

There are two problems in your code. 您的代码中有两个问题。

The first problem is your node selection: 第一个问题是您的node选择:

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

As you can see, this is a selection of circles. 如您所见,这是一些圈子。 Later, when you try... 稍后,当您尝试...

node.append("text")

... it won't work because you cannot append a <text> element to a <circle> element. ...这是行不通的,因为您不能将<text>元素附加到<circle>元素。

The most common solution is making node a group ( <g> ) selection, to which you append both circles and texts. 最常见的解决方案是使node成为组( <g> )选择,并在其上同时添加圆圈和文本。

The second problem is the data for the nodes. 第二个问题是节点的数据。 You have this in your texts: 您的文本中包含以下内容:

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

However, there is no property named source in the data. 但是,数据中没有名为source属性。 The only property you have is name . 您拥有的唯一属性是name

Here is your code with those changes: 这是您所做的更改的代码:

 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