Recursive text
HTML
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://underscorejs.org/underscore-min.js"></script>
<html>
<body>
<svg/>
</body>
</html>
JavaScript
var data = { children: [{
txt: "a", children: [{
txt: "aa", children: [{
txt: "aaa"}, {
txt: "aab"}]}, {
txt: "ab"}]}, {
txt: "b", children: [{
txt: "ba"}, {
txt: "bb"}, {
txt: "bc"}]}, {
txt: "c"}]};
var svg = d3.selectAll("svg");
svg.attr({ width: 500, height: 500});
var recurse = svg.selectAll("g.level0")
.data([data])
recurse.enter()
.append("g").classed("level0", true)
recurse.exit().remove()
var maxLevels = 4;
for (var level = 0; level < maxLevels; level++) {
var nextLevel = level + 1;
var next = svg.selectAll("g.level" + level).filter(function (d) {
return d.children !== undefined;
});
next.selectAll("g.level" + nextLevel)
.data(function (d) { return d.children; })
.enter().append("g")
.attr("class", function (d) {
return "level" + nextLevel + " " + d.txt;
})
.attr("transform", function (d, i) {
return "translate(" + (nextLevel * 25) + "," + (i * 10 * (5 - level) + 15) + ")";
});
next.selectAll("text")
.data(function (d) { return d.children; })
.enter().append("text")
.attr("x", function (d, i, j) { return nextLevel * 25; })
.attr("y", function (d, i, j) {
return j * (10 * (10 - level)) + (i+1) * 15;
})
.attr("fill", "black")
.text(function (d) { return d.txt; });
}