labels wont show up on d3 force diagram

女生的网名这么多〃 提交于 2020-01-11 10:41:12

问题


I am a beginner at d3. One of the diagrams I find particularly helpful and fun is the d3 force diagram. I've been playing around with it, but for some reason I've had a lot of trouble with this particular data set. Specifically, I've been trying forever to get the labels to show up on my d3 force diagram, but it just won't work. Here is my code:

 <!DOCTYPE html>
 <meta charset="utf-8">
 <style>
 .links line {
  stroke: #999;
  stroke-opacity: 0.6;
}
.nodes circle {
  stroke: #fff;
  stroke-width: 1.5px;
}
.node text {
  pointer-events: none;
  font: 10px sans-serif;
}

</style>
<svg width="960" height="600"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var svg = d3.select("svg"),
    width = +svg.attr("width"),
    height = +svg.attr("height");

var color = d3.scaleOrdinal(d3.schemeCategory20);

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

d3.json("links.json", function(error, graph) {
  if (error) throw error;
  var link = svg.append("g")
      .attr("class", "links")
    .selectAll("line")
    .data(graph.links)
    .enter().append("line")
      .attr("stroke-width", function(d) { return 1});

  var node = svg.append("g")
      .attr("class", "nodes")
    .selectAll("circle")
    .data(graph.nodes)
    .enter().append("circle")
      .attr("r", function(d){
        return 3*d.size;
      })
      .attr("fill", function(d) { return color(d.id); })
      .call(d3.drag()
          .on("start", dragstarted)
          .on("drag", dragged)
          .on("end", dragended));

      node.append("svg:title")
      .attr("dx", 12)
      .attr("dy", ".35em")
      .text(function(d) { return d.id });

  simulation
      .nodes(graph.nodes)
      .on("tick", ticked);

  simulation.force("link")
      .links(graph.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;
}
</script>

thanks so much for your help

edit: here is my links.json

{
  "nodes": [
  {"id": "AK","size": "1.414213562"},
  {"id": "AL","size": "1.414213562"},
  {"id": "AR","size": "1.414213562"},
  {"id": "AZ","size": "2.828427125"}],
"links": [
  {"source": "ABC","target": "CO","value": "A"},
  {"source": "ABC","target": "CO","value": "A"},
  {"source": "ABC","target": "CO","value": "A"},
  {"source": "ABC","target": "FL","value": "A"}
}

回答1:


Added Edit below :

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

var color = d3.scaleOrdinal(d3.schemeCategory20);

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

graph = {
  "nodes": [
  {"id": "AK","size": "1.414213562"},
  {"id": "AL","size": "1.414213562"},
  {"id": "AR","size": "1.414213562"},
  {"id": "AZ","size": "2.828427125"}],
"links": [
  {"source": "AK","target": "AL","value": "A"},
  {"source": "AL","target": "AZ","value": "A"},
  {"source": "AL","target": "AR","value": "A"},
  {"source": "AZ","target": "AR","value": "A"}]
};
  var link = svg.append("g")
      .attr("class", "links")
    .selectAll("line")
    .data(graph.links)
    .enter().append("line")
      .attr("stroke-width", function(d) { return 1});

  var node = svg.append("g")
      .attr("class", "nodes")
    .selectAll("circle")
    .data(graph.nodes)
    .enter().append("circle")
      .attr("r", function(d){
        return 5;
      })
      .attr("fill", function(d) { return color(d.id); })
      .call(d3.drag()
          .on("start", dragstarted)
          .on("drag", dragged)
          .on("end", dragended));

      node.append("svg:title")
      .attr("dx", 12)
      .attr("dy", ".35em")
      .text(function(d) { return d.id });
	
	var labels = svg.append("g")
      .attr("class", "label")
    .selectAll("text")
    .data(graph.nodes)
    .enter().append("text")
      .attr("dx", 6)
      .attr("dy", ".35em")
	   .style("font-size",10)
      .text(function(d) { return d.id });

	
  simulation
      .nodes(graph.nodes)
      .on("tick", ticked);

  simulation.force("link")
      .links(graph.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; });
	  
	labels
        .attr("x", function(d) { return d.x; })
        .attr("y", 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;
}
 .links line {
  stroke: #999;
  stroke-opacity: 0.6;
}
.nodes circle {
  stroke: #fff;
  stroke-width: 1.5px;
}
.node text {
  pointer-events: none;
  font: 10px sans-serif;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="960" height="600"></svg>	

Original answer :

Your json is not "proper". First of all there is no source named ABC or targets named CO or FL. Source and target values should be an id from the nodes. You cannot link something that is not defined. Also you are not using the size and value attribute.

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

var color = d3.scaleOrdinal(d3.schemeCategory20);

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

graph = {
  "nodes": [
  {"id": "AK","size": "1.414213562"},
  {"id": "AL","size": "1.414213562"},
  {"id": "AR","size": "1.414213562"},
  {"id": "AZ","size": "2.828427125"}],
"links": [
  {"source": "AK","target": "AL","value": "A"},
  {"source": "AL","target": "AZ","value": "A"},
  {"source": "AL","target": "AR","value": "A"},
  {"source": "AZ","target": "AR","value": "A"}]
};
  var link = svg.append("g")
      .attr("class", "links")
    .selectAll("line")
    .data(graph.links)
    .enter().append("line")
      .attr("stroke-width", function(d) { return 1});

  var node = svg.append("g")
      .attr("class", "nodes")
    .selectAll("circle")
    .data(graph.nodes)
    .enter().append("circle")
      .attr("r", function(d){
        return 5;
      })
      .attr("fill", function(d) { return color(d.id); })
      .call(d3.drag()
          .on("start", dragstarted)
          .on("drag", dragged)
          .on("end", dragended));

      node.append("svg:title")
      .attr("dx", 12)
      .attr("dy", ".35em")
      .text(function(d) { return d.id });

  simulation
      .nodes(graph.nodes)
      .on("tick", ticked);

  simulation.force("link")
      .links(graph.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;
}
 .links line {
  stroke: #999;
  stroke-opacity: 0.6;
}
.nodes circle {
  stroke: #fff;
  stroke-width: 1.5px;
}
.node text {
  pointer-events: none;
  font: 10px sans-serif;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="960" height="600"></svg>


来源:https://stackoverflow.com/questions/38596775/labels-wont-show-up-on-d3-force-diagram

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!