javascript - 如何在 d3 上标记力导向图?

标签 javascript d3.js d3-force-directed

我正在创建一个使用 d3.js 的力导向图,但无法通过用文本标记节点的点。我在 StackOverflow 和在线教程上尝试了无数答案,但我相信问题出在我对 Javascript 的基本理解上。 enter image description here

我尝试了 .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 的属性在数据中。你拥有的唯一属性(property)是 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(" + [d.x, 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;
    })

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

关于javascript - 如何在 d3 上标记力导向图?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57543466/

相关文章:

javascript - 如何在 d3 中向 svg 圆添加文本

javascript - 单击和双击 d3 力定向图中的节点

javascript - 使用 Angular UI Router 在 AngularJS 中具有历史记录的一页上的多个 View

javascript - event.preventDefault() 不会阻止代码运行

javascript - HTML5 "Canvas is null"

javascript - 从 Angular 中的 API 占位符 JSON 中删除数据

javascript - d3.js 气泡图 : Make div scrollable

javascript - 如何附加一个新的 div 元素,该元素是使用 d3 创建的第一个 div 的同级元素?

node.js - 使用 Node js 的 NVD3 图表

javascript - 固定节点未固定(d3 Force Directed Graph)