Display interactive hierarchical chart
by Rajesh Danabal
HTML
<div id="chart"></div>
CSS
#chart {
width: 100%;
height: 500px;
border: 1px solid #ccc;
}
.resize-handle {
cursor: se-resize;
}
JavaScript
const script1 = document.createElement('script');
script1.src = 'https://cdn.jsdelivr.net/npm/d3@7';
script1.onload = () => {
const script2 = document.createElement('script');
script2.src = 'https://cdn.jsdelivr.net/npm/d3-flextree@2';
script2.onload = initTree;
document.body.appendChild(script2);
};
document.body.appendChild(script1);
function initTree() {
const data = {
name: "Root",
children: [
{ name: "Child 1" },
{
name: "Child 2",
children: [{ name: "Grandchild 1" }, { name: "Grandchild 2" }]
}
]
};
const defaultSize = { width: 100, height: 50 };
const tree = d3.flextree()
.nodeSize(d => [d.data.height || defaultSize.height, d.data.width || defaultSize.width]);
const root = tree(d3.hierarchy(data));
const svg = d3.select("#chart")
.append("svg")
.attr("width", 800)
.attr("height", 500);
const g = svg.append("g")
.attr("transform", "translate(50, 50)");
// Draw links
g.selectAll(".link")
.data(root.links())
.enter().append("line")
.attr("stroke", "#999")
.attr("x1", d => d.source.x)
.attr("y1", d => d.source.y)
.attr("x2", d => d.target.x)
.attr("y2", d => d.target.y);
// Draw nodes
const nodes = g.selectAll(".node")
.data(root.descendants())
.enter().append("g")
.attr("class", "node")
.attr("transform", d => `translate(${d.x},${d.y})`);
nodes.each(function (d) {
const nodeG = d3.select(this);
d.data.width = d.data.width || defaultSize.width;
d.data.height = d.data.height || defaultSize.height;
// Rectangle
const rect = nodeG.append("rect")
.attr("width", d.data.width)
.attr("height", d.data.height)
.attr("fill", "#b3d9ff")
.attr("stroke", "#333");
// Text
const text = nodeG.append("text")
.attr("x", d.data.width / 2)
.attr("y", 25)
.attr("text-anchor", "middle")
.text(d.data.name);
//...