JSFiddle - React, Tailwind, and code Playground
CSS
.node {
cursor: pointer;
}
.node circle {
fill: #DC0963;
stroke: #4F2662;
stroke-width: 3px;
}
.node text {
font: 12px sans-serif;
}
.link {
fill: none;
stroke: #ccc;
stroke-width: 2px;
}
JavaScript
//Flat file style... Should reduce Glide queries. Reordering is done client side.
var data = [
{ "id" : "001", "name" : "Level 2: A", "parent":"002" },
{ "id" : "002", "name" : "Top Level", "parent":"null" },
{ "id" : "003", "name" : "Son of A", "parent":"001" },
{ "id" : "004", "name" : "Daughter of A", "parent":"001" },
{ "id" : "005", "name" : "Level 2: B", "parent":"002" },
{ "id" : "006", "name" : "Son of B", "parent":"005" }
];
//Create a name based map for the array
var dataMap = data.reduce(function(map, node) {
map[node.id] = node;
return map;
}, {});
//Iteratively add each child to its parents, or to the root array if no parent is found;
var treeData = [];
data.forEach(function(node) {
// add to parent
var parent = dataMap[node.parent];
if (parent) {
// create child array if it doesn't exist
(parent.children || (parent.children = []))
// add node to child array
.push(node);
} else {
// parent is null or missing
treeData.push(node);
}
});
// ************** Generate the tree diagram *****************
var margin = {top: 50, right: 120, bottom: 20, left: 120},
width = 1000 - margin.right - margin.left,
height = 1000 - margin.top - margin.bottom;
var i = 0,
duration = 750,
root;
var tree = d3.layout.tree()
.size([height, width]);
var diagonal = d3.svg.diagonal()
.projection(function(d) { return [d.y, d.x]; });
var svg = d3.select("body").append("svg")
.attr("width", width + margin.right + margin.left)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
root = treeData[0];
root.x0 = height / 2;
root.y0 = 0;
update(root);
d3.select(self.frameElement).style("height", "500px");
function update(source) {
// Compute the new tree layout.
var nodes = tree.nodes(root).reverse(),
links = tree.links(nodes);
// Normalize for fixed-depth.
nodes.forEach(function(d) { d.y = d.depth * 180; });
//...