score:3

Accepted answer

Approach:

So my approach to that would to to create group elements g with circle and text inside them, and then we can use force layout to position them with transform. This way we only care about group element position and circle with text should follow that position. So the node structure might look like that:

<g transform='translate(30,70)'>
    <circle r='3'>/<circle> 
    <text>sample text</text>
</g>

Code:

You have quite a lot of code in your sample so I'll just focus on having persistent labels over circles. This might break some other things I'm not focusing on but should give you direction and hopefully you'll be able to fix the rest if not fell free to ask.

Using your plunker first thing you have to do it so associate data with g elements instead of circle :

node = vis.selectAll('g.node')
    .data(nodes, function(d) { return d.filename })
    .enter().append('g');

Then you can append circles to those g elements, and in this case there is no need to define cx and cy as this is taken care of by transform applied to g elements, so all you need to specify is r and any other styles you wan to apply:

node.append('circle')
.attr('class', 'node')
.attr('r', function(d) {
    return scale * (d.root ? 8 : d.module && !d.native ? 5 : 3)
})
(...)

Now you can add your labels:

node.append('text')
.text(function(d){return d.id})
.style('text-anchor',middle); // this will center label horizontally

One last step is to update on 'tick' function as before it was updating circle position and now we want it to update g position, so instead of:

node.attr('cx', function(d) { return d.x; })
    .attr('cy', function(d) { return d.y; });

you should do:

node.attr('transform', function(d) { 
      return 'translate('+ d.x + ',' + d.y + ')'; 
    });

And here you have your plunker with my changes, hope thats what you asked for. http://plnkr.co/edit/Q69DkEH5Z9aOe92UwlOB?p=preview

Fell free to ask any more questions if you have any :)


Related Query