Converting data from the python networkx graph manipulation library into a d3 hierarchy.
For Stack Overflow question how to use d3.js to visualise a json tree graph
license: mit | |
border: yes | |
scrolling: yes | |
height: 600 |
Converting data from the python networkx graph manipulation library into a d3 hierarchy.
For Stack Overflow question how to use d3.js to visualise a json tree graph
{ | |
"issueid": "3295658", | |
"issuetype": "Portfolio-Epic", | |
"status": "In Progress", | |
"pirank": 24, | |
"id": "ATROB-2523", | |
"children": [ | |
{ | |
"issueid": "3288189", | |
"issuetype": "Epic", | |
"status": "Implementation", | |
"id": "ATTDATA-233", | |
"children": [ | |
{ | |
"issueid": "3305730", | |
"issuetype": "Task", | |
"status": "Implementation", | |
"id": "ATTDATA-363" | |
}, | |
{ | |
"issueid": "3305723", | |
"issuetype": "Task", | |
"status": "Open", | |
"id": "ATTDATA-361" | |
}, | |
{ | |
"issueid": "3301728", | |
"issuetype": "Task", | |
"status": "Open", | |
"id": "ATTDATA-336" | |
}, | |
{ | |
"issueid": "3297381", | |
"issuetype": "Task", | |
"status": "Closed", | |
"id": "ATTDATA-300" | |
}, | |
{ | |
"issueid": "3295913", | |
"issuetype": "Task", | |
"status": "Review", | |
"id": "ATTDATA-290" | |
}, | |
{ | |
"issueid": "3295893", | |
"issuetype": "Task", | |
"status": "Open", | |
"id": "ATTDATA-289" | |
}, | |
{ | |
"issueid": "3291658", | |
"issuetype": "Task", | |
"status": "Closed", | |
"id": "ATTDATA-256" | |
}, | |
{ | |
"issueid": "3291653", | |
"issuetype": "Task", | |
"status": "Closed", | |
"id": "ATTDATA-255" | |
}, | |
{ | |
"issueid": "3291530", | |
"issuetype": "Task", | |
"status": "Open", | |
"id": "ATTDATA-253" | |
}, | |
{ | |
"issueid": "3290232", | |
"issuetype": "Task", | |
"status": "Open", | |
"id": "ATTDATA-247" | |
}, | |
{ | |
"issueid": "3287061", | |
"issuetype": "Task", | |
"status": "Resolved", | |
"id": "ATTDATA-226" | |
} | |
] | |
}, | |
{ | |
"issueid": "3300899", | |
"issuetype": "Request", | |
"status": "REJECTED", | |
"id": "ATI-1478" | |
} | |
] | |
} |
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<head> | |
<style> | |
.node circle { | |
fill: #999; | |
} | |
.node text { | |
font: 10px sans-serif; | |
} | |
.node--internal circle { | |
fill: #555; | |
} | |
.node--internal text { | |
text-shadow: 0 1px 0 #fff, 0 -1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff; | |
} | |
.link { | |
fill: none; | |
stroke: #555; | |
stroke-opacity: 0.4; | |
stroke-width: 1.5px; | |
} | |
</style> | |
</head> | |
<body> | |
<svg width="960" height="1060"></svg> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<script> | |
var svg = d3.select("svg"), | |
width = +svg.attr("width"), | |
height = +svg.attr("height"), | |
g = svg.append("g").attr("transform", "translate(" + (width / 2 + 40) + ",400)"); | |
var tree = d3.tree() | |
.size([2 * Math.PI, 300]) | |
.separation(function(a, b) { return (a.parent == b.parent ? 1 : 2) / a.depth; }); | |
d3.json("data.json", function(error, data) { | |
if (error) throw error; | |
var root = tree(d3.hierarchy(data)); | |
var link = g.selectAll(".link") | |
.data(root.links()) | |
.enter().append("path") | |
.attr("class", "link") | |
.attr("d", d3.linkRadial() | |
.angle(function(d) { return d.x; }) | |
.radius(function(d) { return d.y; })); | |
var node = g.selectAll(".node") | |
.data(root.descendants()) | |
.enter().append("g") | |
.attr("class", function(d) { return "node" + (d.children ? " node--internal" : " node--leaf"); }) | |
.attr("transform", function(d) { return "translate(" + radialPoint(d.x, d.y) + ")"; }); | |
node.append("circle") | |
.attr("r", 2.5); | |
node.append("text") | |
.attr("dy", "0.31em") | |
.attr("x", function(d) { return d.x < Math.PI === !d.children ? 6 : -6; }) | |
.attr("text-anchor", function(d) { return d.x < Math.PI === !d.children ? "start" : "end"; }) | |
.attr("transform", function(d) { return "rotate(" + (d.x < Math.PI ? d.x - Math.PI / 2 : d.x + Math.PI / 2) * 180 / Math.PI + ")"; }) | |
.text(function(d) { | |
return d.data.id | |
}); | |
}); | |
function radialPoint(x, y) { | |
return [(y = +y) * Math.cos(x -= Math.PI / 2), y * Math.sin(x)]; | |
} | |
</script> | |
</body> | |
</html> |