Built with blockbuilder.org
xxxxxxxxxx
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body {
margin:0;
position:fixed;
top:0;
right:0;
bottom:0;
left:0;
font-family:Franklin Gothic Medium;
font-size:20px;
}
#container{
display:inline-block;
}
#left{
display:inline-block;
vertical-align:top;
}
#right{
display:inline-block;
vertical-align:top;
width:400px;
}
#addDiv{
width:100%;
display:block;
}
#addDiv:hover{
background:rgb(220,220,220);
}
.node circle {
stroke-width: 1.5px;
}
.node text {
font: 13px Franklin Gothic Book;
}
.link {
fill: none;
stroke: #ccc;
stroke-width: 1px;
}
</style>
</head>
<div id="container">
<div id="left">
</div>
<div id="right">
<div id="divisionCont">
<div id="addDiv">+ Add a Division</div>
</div>
</div>
</div>
<body>
<script>
var counter = 0;
d3.select("#addDiv").on("click",function(d){
var cont = d3.select("#divisionCont")
.append("div")
.attr("class","divisionDiv")
.style("display","block")
var divisionCont = cont.append("div")
.attr("class","divisionControls")
counter = counter + 1
divisionCont.append("input")
.attr("class","divInput")
.attr("type","text")
.property("value","New Division" + counter)
divisionCont.append("span")
.text(" - ")
.on("click",function(d){
d3.select(this.parentNode).remove()
})
divisionCont.append("span")
.text(" Add Person ")
.on("click",function(d){
var roleDiv = d3.select(this.parentNode)
.append("div")
.attr("class","divRoles")
.style("display","block")
.style("position","relative")
var roleTree = roleDiv.append("div")
.attr("class","roleTree")
.style("display","inline-block")
.style("width","20px")
.style("height","auto")
.style("display","absolute")
.style("top","15px")
.style("background","yellow")
counter = counter + 1
roleDiv.append("input")
.attr("type","text")
.style("height","20px")
.property("value","New Role" + counter)
getTree()
})
getTree()
})
function getTree(){
var treelinks = [{"parent":null,"name":"main"}]
d3.selectAll(".divisionControls").each(function(){
var divisionName = d3.select(this).select(".divInput").property("value");
treelinks.push({"parent":"main","name":divisionName})
console.log(d3.select(this).selectAll(".divRoles"))
if(d3.select(this).selectAll(".divRoles").empty()){
treelinks.push({"parent":divisionName,"name":"foo"})
}
else{
//get children of division. If there arent any, create a null child to store process
d3.select(this).selectAll(".divRoles").each(function(){
var roleName = d3.select(this).select("input").property("value")
treelinks.push({"parent":divisionName,"name":roleName})
})
}
})
var dataMap = treelinks.reduce(function(map, node) {
map[node.name] = node;
return map;
}, {});
var treeData1 = [];
treelinks.forEach(function(node) {
var parent = dataMap[node.parent];
if (parent) {
(parent.children || (parent.children = []))
.push(node);
} else {
treeData1.push(node);
}
});
var i = 0,
duration = 1000,
root;
var treemap = d3.tree()
.size([svgWidth,200])
.separation(function(a, b) { return (a.parent == b.parent ? 5:25) ; })
//console.log(treeData1)
var treeData = treeData1[0]
root = d3.hierarchy(treeData, function(d) { return d.children; });
root.x0 = svgWidth;
root.y0 = 0;
var treeData = treemap(root);
var nodes = treeData.descendants(),
links = treeData.descendants().slice(1);
console.log(nodes)
nodes.forEach(function(d){ d.y = (d.depth)* 200/3});
var node = chart.selectAll('.node').data(nodes, function(d) {return d.data.id; });
var nodeEnter = node.enter()
.append('g')
.attr('class', 'node')
.attr("transform", function(d) {return "translate(" + d.x + "," + d.y + ")";})
.on('click', click);
svg.selectAll(".node")
.append('circle')
.attr('class', 'node')
.attr('r', 6)
.style("fill","white");
// Add labels for the nodes
nodeEnter.append('text')
.attr("dy", ".35em")
.attr("x", function(d) {return d.children || d._children ? -11 : 11;})
.attr("text-anchor", function(d) {
return d.children || d._children ? "end" : "start";
})
.style("font-size","10px")
.text(function(d){return d.data.name; });
// UPDATE
var nodeUpdate = nodeEnter.merge(node);
// Transition to the proper position for the node
nodeUpdate
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
nodeUpdate.select('text').text(function(d){return d.data.name; })
// Update the node attributes and style
nodeUpdate.selectAll('circle')
.attr('r', 6)
.style("fill", function(d) {
return d._children ? "lightsteelblue" : "#fff";
})
.attr('cursor', 'pointer')
.style("stroke", function(d) {
return "black"
// return colors(d.data.depth)
})
var nodeExit = node.exit()
.remove();
var link = chart.selectAll('path.link')
.data(links, function(d) {return d.data.name + "-" + d.data.parent; });
var linkEnter = link.enter().insert('path', "g")
.attr("class", "link")
.attr('d', function(d){
var o = {x: d.x, y: d.y}
return diagonal(o, o)
});
// UPDATE
var linkUpdate = linkEnter.merge(link);
linkUpdate.attr("d", function(d) {
return "M" + d.x + "," + d.y
+ "C" + d.x + "," + (d.y + d.parent.y) / 2
+ " " + d.parent.x + "," + (d.y + d.parent.y) / 2
+ " " + d.parent.x + "," + d.parent.y;
})
var linkExit = link.exit()
.attr("d", function(d) {
return "M" + d.x + "," + d.y
+ "C" + d.x + "," + (d.y + d.parent.y) / 2
+ " " + d.parent.x + "," + (d.y + d.parent.y) / 2
+ " " + d.parent.x + "," + d.parent.y;
})
.remove();
nodes.forEach(function(d){
d.x0 = d.x;
d.y0 = d.y;
});
// Creates a curved (diagonal) path from parent to the child nodes
function diagonal(s, d) {
path = `M ${s.x} ${s.y}
C ${(s.x + d.x) / 2} ${s.y},
${(s.x + d.x) / 2} ${d.y},
${d.x} ${d.y}`
return path
}
// Toggle children on click.
function click(d) {
if (d.children) {
d._children = d.children;
d.children = null;
} else {
d.children = d._children;
d._children = null;
}
update(d);
}
}
var svgHeight = 800;
var svgWidth = 500;
var margin = {top: 20, right: 10, bottom: 20, left: 10};
var svg = d3.select("#left").append("svg")
.attr("width", svgWidth + margin.left + margin.right)
.attr("height", svgHeight + margin.top + margin.bottom)
.style("border","1px solid black")
var chart = svg.append("g")
.attr("transform","translate("+margin.top+"," + margin.left + ")")
</script>
</body>
https://d3js.org/d3.v4.min.js