JSFiddle - React, Tailwind, and code Playground

by Rajesh Danabal

JavaScript

// Include D3.js and d3-flextree via script tags in JSFiddle's External Resources:
// https://d3js.org/d3.v7.min.js
// https://cdn.jsdelivr.net/npm/[email protected]/build/d3-flextree.min.js

// Sample flat data with variable node sizes
const data = [
  { id: 'root', parentId: null, width: 100, height: 60 },
  { id: 'child1', parentId: 'root', width: 80, height: 40 },
  { id: 'child2', parentId: 'root', width: 120, height: 50 },
  { id: 'grandchild1', parentId: 'child1', width: 70, height: 30 },
  { id: 'grandchild2', parentId: 'child1', width: 90, height: 35 },
  { id: 'grandchild3', parentId: 'child2', width: 110, height: 45 }
];

// Convert flat data to hierarchical structure
const stratify = d3.stratify()
  .id(d => d.id)
  .parentId(d => d.parentId);

const root = stratify(data);

// Assign size to each node
root.each(d => {
  d.data.size = [d.data.width, d.data.height];
});

// Create a flextree layout
const layout = d3.flextree()
  .nodeSize(d => d.data.size)
  .spacing((a, b) => 20); // spacing between nodes

layout(root);

// Set up SVG
const svg = d3.select("#treeSvg");
const g = svg.append("g")
  .attr("transform", "translate(50,50)");

// Draw links
g.selectAll(".link")
  .data(root.links())
  .enter()
  .append("line")
  .attr("class", "link")
  .attr("x1", d => d.source.x)
  .attr("y1", d => d.source.y)
  .attr("x2", d => d.target.x)
  .attr("y2", d => d.target.y)
  .attr("stroke", "#999")
  .attr("stroke-width", 1.5);

// Draw nodes
const node = g.selectAll(".node")
  .data(root.descendants())
  .enter()
  .append("g")
  .attr("class", "node")
  .attr("transform", d => `translate(${d.x - d.data.width / 2}, ${d.y - d.data.height / 2})`);

// Draw rectangles
node.append("rect")
  .attr("width", d => d.data.width)
  .attr("height", d => d.data.height)
  .attr("fill", "#4b9cd3")
  .attr("stroke", "#333");

// Add text labels
node.append("text")
  .attr("x", d => d.data.width / 2)
  .attr("y", d => d.data.height / 2)
  .attr("dy", "0.35em")
 ...