1

Problem faced: Im trying to add text to a "Sticky" force directed graph node using D3 v4 . The problem Im facing is that the "text" attribute is not getting attached to the node circle, its not visible(Refer to my jsfiddle below). I have been trying to debug this for a day. Can someone advice me on how to add a text to a graph using d3 V4?

Code Referred Referred this for a sticky force directed graph : https://bl.ocks.org/mbostock/3750558

Referred this code for adding text : https://bl.ocks.org/heybignick/3faf257bbbbc7743bb72310d03b86ee8

jsfiddle : https://jsfiddle.net/rohit2219/5gsk4t7f/6

jsfiddle Code is below

<!DOCTYPE html>
<meta charset="utf-8">
<style>
.links line {
  stroke: #999;
  stroke-opacity: 0.6;
}
.nodes circle {
  stroke: #fff;
  stroke-width: 1.5px;
}

.text {
  font-family: sans-serif;
  font-size: 10px;
}
</style>
<svg width="400" height="300"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
//create somewhere to put the force directed graph
var svg = d3.select("svg"),
    width = +svg.attr("width"),
    height = +svg.attr("height");


var nodes_data =  [
    {"name": "Travis", "sex": "M"},
    {"name": "Rake", "sex": "M"},
    {"name": "Diana", "sex": "F"},
    {"name": "Rachel", "sex": "F"},
    {"name": "Shawn", "sex": "M"},
    {"name": "Emerald", "sex": "F"}
    ]
var links_data = [
    {"source": "Travis", "target": "Rake"},
    {"source": "Diana", "target": "Rake"},
    {"source": "Diana", "target": "Rachel"},
    {"source": "Rachel", "target": "Rake"},
    {"source": "Rachel", "target": "Shawn"},
    {"source": "Emerald", "target": "Rachel"}
]
//set up the simulation 
var simulation = d3.forceSimulation()
                    //add nodes
                    .nodes(nodes_data);


//add forces
//we're going to add a charge to each node 
//also going to add a centering force
//and a link force
var link_force =  d3.forceLink(links_data)
                        .id(function(d) { return d.name; });
simulation
    .force("charge_force", d3.forceManyBody())
    .force("center_force", d3.forceCenter(width / 2, height / 2))
    .force("links",link_force);

//add tick instructions: 
simulation.on("tick", tickActions );
//draw circles for the links 
var node = svg.append("g")
        .attr("class", "nodes")
        .selectAll("circle")
        .data(nodes_data)
        .enter()
        .append("circle")
        .attr("r", 10)
        .attr("fill", "red");  
//draw lines for the links 
var link = svg.append("g")
      .attr("class", "links")
    .selectAll("line")
    .data(links_data)
    .enter().append("line")
      .attr("stroke-width", 2);        

 var lables = node.append("text")
      .text(function(d) {
        return d.name;
      })
      .attr('x', 6)
      .attr('y', 3);

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

var drag_handler = d3.drag()
    .on("start", drag_start)
    .on("drag", drag_drag)
    .on("end", drag_end);   

//same as using .call on the node variable as in https://bl.ocks.org/mbostock/4062045 
drag_handler(node)
//drag handler
//d is the node 
function drag_start(d) {
 if (!d3.event.active) simulation.alphaTarget(0.3   ).restart();
   d.fx = d.x;
   d.fy = d.y;
}
function drag_drag(d) {
  d.fx = d3.event.x;
  d.fy = d3.event.y;
}
function drag_end(d) {
  if (!d3.event.active) simulation.alphaTarget(0);
  d.fx = d.x;
  d.fy = d.y;
}

function tickActions() {
    //update circle positions each tick of the simulation 
    node
        .attr("cx", function(d) { return d.x; })
        .attr("cy", function(d) { return d.y; });

    //update link positions 
    //simply tells one end of the line to follow one node around
    //and the other end of the line to follow the other node around
    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>
rohit2219
  • 218
  • 2
  • 12
  • 3
    You can't append a child `text` element to a `circle` element (as the variable `node` is a selection of circles). However, you could append both to a `g`: `var node = svg.append("g").selectAll(...).data(...).enter().append("g")` and then: `node.append("circle")...` and `node.append("text")` – Andrew Reid Sep 23 '19 at 22:22
  • 3
    Updated [fiddle](https://jsfiddle.net/bs7ac1k0/) - note that I position the `g` each tick rather than the circles and the text. – Andrew Reid Sep 23 '19 at 22:32

0 Answers0