Some visualizations seem to be more sophisticated (to implement) than they actual are, specifically the radial projections. Starting from a tree representation with nodes and links it is quite easy to get to the radial version.
Remark: Of course there are more challenging radial diagrams like the bundle, but lets get started with something simple first !
“Standard” Tree
(I added few more nodes to make the visual difference more obvious)
We change 1 line of our sourcecode (see previous tutorial for complete code):
var tree = d3.layout.tree().size([300,300]); to var tree = d3.layout.cluster().size([300,300]);
Cluster
Same like tree but all end-nodes/leafs at one level.
Radial Cluster
With a few changes we can convert this cluster diagram into a radial one.
Change these lines:
The path generator
var diagonal = d3.svg.diagonal()
.projection(function(d) { return [d.y, d.x]; });
// to
var diagonal = d3.svg.diagonal.radial()
.projection(function(d) { return [d.y, d.x / 180 * Math.PI]; });
The nodes
var node = vis.selectAll("g.node")
.data(nodes)
.enter().append("svg:g")
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; })
to
.attr("transform", function(d) { return "rotate(" + (d.x - 90) + ")translate(" + d.y + ")"; })
and the text (rotated):
Add this line
.attr("transform", function(d) { return d.x < 180 ? null : "rotate(180)"; })
You also should change the svg canvas to center everything:
var vis = d3.select("#viz").append("svg:svg")
.attr("width", 400)
.attr("height", 400)
.append("svg:g")
.attr("transform", "translate(200, 200)");
Obviously is visually more appealing with more nodes in place. After all, the new visualization was not done by changing parameters (like using a visualization library) but by applying mathematics and geometry. From here I will explore the more challenging bundle diagram and start to play with interaction.
Remark: This is a very stripped down sample for understanding, in real projects you should use variables for canvas sizes, etc. Also place visual attributes like color, etc in style in a css.
The complete code:
<!DOCTYPE html>
<html>
<head>
<title>Radial Cluster Demo</title>
<script type="text/javascript" src="libnew/d3.v2.min.js"></script>
<style>
svg {
border: solid 1px #ccc;
font: 10px sans-serif;
}
.link {
fill: none;
stroke: #ccc;
stroke-width: 1.5px;
}
</style>
</head>
<body>
<div id="viz"></div>
<script type="text/javascript">
//JSON object with the data
var treeData = {"name" : "A", "info" : "tst", "children" : [
{"name" : "A1", "children" : [
{"name" : "A12" },
{"name" : "A13" },
{"name" : "A14" },
{"name" : "A15" },
{"name" : "A16" }
] },
{"name" : "A2", "children" : [
{"name" : "A21" },
{"name" : "A22", "children" : [
{"name" : "A221" },
{"name" : "A222" },
{"name" : "A223" },
{"name" : "A22" }
]},
{"name" : "A23" },
{"name" : "A24" },
{"name" : "A25" }] },
{"name" : "A3", "children": [
{"name" : "A31", "children" :[
{"name" : "A311" },
{"name" : "A312" },
{"name" : "A313" },
{"name" : "A314" },
{"name" : "A315" }
]}] }
]};
// Create a svg canvas
var vis = d3.select("#viz").append("svg:svg")
.attr("width", 400)
.attr("height", 400)
.append("svg:g")
.attr("transform", "translate(200, 200)");
// Create a cluster "canvas"
var cluster = d3.layout.cluster()
.size([300,150]);
var diagonal = d3.svg.diagonal.radial()
.projection(function(d) { return [d.y, d.x / 180 * Math.PI]; });
var nodes = cluster.nodes(treeData);
var links = cluster.links(nodes);
var link = vis.selectAll("pathlink")
.data(links)
.enter().append("svg:path")
.attr("class", "link")
.attr("d", diagonal)
var node = vis.selectAll("g.node")
.data(nodes)
.enter().append("svg:g")
.attr("transform", function(d) { return "rotate(" + (d.x - 90) + ")translate(" + d.y + ")"; })
// Add the dot at every node
node.append("svg:circle")
.attr("r", 3.5);
node.append("svg:text")
.attr("dx", function(d) { return d.x < 180 ? 8 : -8; })
.attr("dy", ".31em")
.attr("text-anchor", function(d) { return d.x < 180 ? "start" : "end"; })
.attr("transform", function(d) { return d.x < 180 ? null : "rotate(180)"; })
.text(function(d) { return d.name; });
</script>
</body>
</html>



Great tutorial. I used this to create a dynamic way of toggling between the two types of the tree.
Using a transition ?
Yes. Basically I parametrized all node transforms and edge projection functions. So whenever the tree is updated it checks whats the current type of the tree and calls the appropriate function.
would you share it with me, i thought about transition but didnt get it running.
Hi~. please let me know that how to draw other circle of the circle. I’d like to make empty circles.