Typically by adding an svg:text element. Something like this in terms of SVG:
<svg:g class="node" transform="translate(d.x, d.y)">
<svg:circle r="5"/>
<svg:text x="10" dy=".31em" text="d.name"/>
</svg:g>
Or, in D3:
var g = svg.selectAll("g.node")
.data(nodes)
.enter().append("svg:g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + d.x + ","
+ d.y + ")"; })
.call(force.drag);
g.append("svg:circle")
.attr("r", 5);
g.append("svg:text")
.attr("x", 10)
.attr("dy", ".31em")
.text(function(d) { return d.name; });
This does have a drawback, though, which is that later nodes' circles
will be drawn over earlier nodes' text labels. Also, there's a nice
technique where you draw the text twice, first with a thick white
stroke, such that the text has a white halo that improves legibility.
I used this in yesterday's example of mobile patent suits:
This involves adding two different svg:g layers: one for the circles,
and one on top for the labels. In terms of SVG:
<svg:g>
<svg:circle class="node" cx="d.x" cy="d.y" r="5"/>
<svg:circle class="node" cx="d.x" cy="d.y" r="5"/>
…
</svg:g>
<svg:g>
<svg:text class="label" x="d.x + 10" y="d.y" dy=".35em" text="d.name"/>
<svg:text class="label" x="d.x + 10" y="d.y" dy=".35em" text="d.name"/>
…
</svg:g>
In terms of D3, first you add the svg:g for the circles:
var circle = svg.append("svg:g").selectAll("circle")
.data(nodes)
.enter().append("svg:circle")
.attr("r", 6)
.call(force.drag);
Then a second svg:g for the labels:
var text = svg.append("svg:g").selectAll("g")
.data(nodes)
.enter().append("svg:g");
text.append("svg:text")
.attr("x", 8)
.attr("y", ".31em")
.attr("class", "shadow")
.text(function(d) { return d.name; });
text.append("svg:text")
.attr("x", 8)
.attr("y", ".31em")
.text(function(d) { return d.name; });
It's a bit more work because you're mapping the nodes twice (once for
the circles, and once for the labels). Versus in the simpler example,
you map once to an svg:g element that contains both a circle and a
label. But the benefit of the second approach is more legible text,
which is a big plus.
Mike
var g = svg.selectAll("g.node")
.data(nodes)
.enter().append("svg:g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + d.x + ","
+ d.y + ")"; })
.call(force.drag);
g.append("svg:circle")
.attr("r", 5);
g.append("svg:text")
.attr("x", 10)
.attr("dy", ".31em")
.text(function(d) { return d.name; });