0

I hava tried some methods, such as d3 Node Labeling proposed by mbostock. But it doesn't work, my text still doesn't move with the nodes, they are static.

(Coded by using CoffeeScript)

vis = d3.select(selection).append("svg")
  .attr("width", width)
  .attr("height", height)
linksG = vis.append("g").attr("class", "links")
nodesG = vis.append("g").attr("class", "nodes")
labelG = vis.append("g").attr("class", "labels")

nodeP = nodesG.selectAll("circle.node")
  .data(curNodesDataP)
nodeP.enter().append("circle")
  .attr("class", "node")
  .attr("r", 15)
  .style("fill", (d) -> nodeColors(d.id))
  .style("stroke", (d) -> strokeFor(d))
  .style("stroke-width", 1.0)
  .call(force.drag)

text = labelG.selectAll("text")
  .data(curNodesDataP)
text.enter().append("text")
    .attr("dx", 12)
    .attr("dy", ".35em")
    .text((d) -> d.id)

I have troubled that several days, and how can i repair it? Thanks!

--zzcheng

Lars Kotthoff
  • 107,425
  • 16
  • 204
  • 204

1 Answers1

1

You are appending the links, nodes and labels in separate g groups. So you should update the position of each group in tick function (Link group, Node group and label Group).

Here is a sample fiddle for the same. Note that I am updating position of label group also in the tick function.

var w = 900,
    h = 400;

var circleWidth = 5;

var nodes = [{
    "name": "Matteo"
}, {
    "name": "Daniele"
}, {
    "name": "Marco"
}, {
    "name": "Lucio"
}, {
    "name": "Davide"
}];

var links = [{
    source: nodes[0],
    target: nodes[1]
}, {
    source: nodes[1],
    target: nodes[2]
}, {
    source: nodes[0],
    target: nodes[3]
}, {
    source: nodes[4],
    target: nodes[2]
}, {
    source: nodes[2],
    target: nodes[3]
}];



var vis = d3.select("body")
    .append("svg:svg")
    .attr("class", "stage")
    .attr("width", w)
    .attr("height", h);

var force = d3.layout.force()
    .nodes(nodes)
    .links([])
    .gravity(0.1)
    .charge(-1000)
    .size([w, h]);

var link = vis.selectAll(".link")
    .data(links)
    .enter().append("line")
    .attr("class", "link")
    .attr("stroke", "#CCC")
    .attr("fill", "none");

var node = vis.selectAll("circle.node")
    .data(nodes)
    .enter().append("g")
    .attr("class", "node")
    .call(force.drag);

var labels = vis.selectAll("text.label")
    .data(nodes)
    .enter().append("g")
    .attr("class", "label");   

//CIRCLE
node.append("svg:circle")
    .attr("cx", function(d) {
        return d.x;
    })
    .attr("cy", function(d) {
        return d.y;
    })
    .attr("r", circleWidth)
    .attr("fill", "pink");


//TEXT
labels.append("text")
    .text(function(d, i) {
        return d.name;
    })
    .attr("x", function(d, i) {
        return circleWidth + 5;
    })
    .attr("y", function(d, i) {
        if (i > 0) {
            return circleWidth + 0
        } else {
            return 8
        }
    })
    .attr("font-family", "Bree Serif")
    .attr("fill", "green")
    .attr("font-size", "1em")
    .attr("text-anchor", function(d, i) {
        if (i > 0) {
            return "beginning";
        } else {
            return "end"
        }
    })



force.on("tick", function(e) {
    node.attr("transform", function(d, i) {
        return "translate(" + d.x + "," + d.y + ")";
    });

    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;
        });
  
    labels.attr("transform", function(d, i) {
        return "translate(" + d.x + "," + d.y + ")";
    });
});

force.start();
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

Other possible and more efficient way would be to group nodes and labels together. Here is a sample fiddle in which nodes and labels are grouped and updated position of the node group and link group only in tick function.

var w = 900,
    h = 400;

var circleWidth = 5;

var nodes = [{
    "name": "Matteo"
}, {
    "name": "Daniele"
}, {
    "name": "Marco"
}, {
    "name": "Lucio"
}, {
    "name": "Davide"
}];

var links = [{
    source: nodes[0],
    target: nodes[1]
}, {
    source: nodes[1],
    target: nodes[2]
}, {
    source: nodes[0],
    target: nodes[3]
}, {
    source: nodes[4],
    target: nodes[2]
}, {
    source: nodes[2],
    target: nodes[3]
}];



var vis = d3.select("body")
    .append("svg:svg")
    .attr("class", "stage")
    .attr("width", w)
    .attr("height", h);

var force = d3.layout.force()
    .nodes(nodes)
    .links([])
    .gravity(0.1)
    .charge(-1000)
    .size([w, h]);

var link = vis.selectAll(".link")
    .data(links)
    .enter().append("line")
    .attr("class", "link")
    .attr("stroke", "#CCC")
    .attr("fill", "none");

var node = vis.selectAll("circle.node")
    .data(nodes)
    .enter().append("g")
    .attr("class", "node")
    .call(force.drag);

//CIRCLE
node.append("svg:circle")
    .attr("cx", function(d) {
        return d.x;
    })
    .attr("cy", function(d) {
        return d.y;
    })
    .attr("r", circleWidth)
    .attr("fill", "pink");
//TEXT
node.append("text")
    .text(function(d, i) {
        return d.name;
    })
    .attr("x", function(d, i) {
        return circleWidth + 5;
    })
    .attr("y", function(d, i) {
        if (i > 0) {
            return circleWidth + 0
        } else {
            return 8
        }
    })
    .attr("font-family", "Bree Serif")
    .attr("fill", "green")
    .attr("font-size", "1em")
    .attr("text-anchor", function(d, i) {
        if (i > 0) {
            return "beginning";
        } else {
            return "end"
        }
    })



force.on("tick", function(e) {
    node.attr("transform", function(d, i) {
        return "translate(" + d.x + "," + d.y + ")";
    });

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

force.start();
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
Gilsha
  • 14,431
  • 3
  • 32
  • 47