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);

  //...