AST Visualization with D3.js

Saturday, March 18th 2023

This component takes an AST object as a prop (astData) and renders it as a tree using D3.js. The tree layout is created using d3.tree(), and the nodes and links are added to the SVG using the selectAll() and enter() methods. The nodes are represented as circles, and the links are represented as paths using d3.linkHorizontal(). The useEffect() hook is used to update the visualization whenever the astData prop changes.

const astData = { name: "Program", children: [ { name: "VariableDeclaration", children: [ { name: "VariableDeclarator", children: [ { name: "Identifier" }, { name: "Literal" } ] } ] }, { name: "FunctionDeclaration", children: [ { name: "Identifier" }, { name: "BlockStatement", children: [ { name: "VariableDeclaration", children: [ { name: "VariableDeclarator", children: [ { name: "Identifier" }, { name: "Literal" } ] } ] } ] } ] } ] };
import React, { useEffect, useRef } from 'react'; import * as d3 from 'd3'; const AstVisualization = ({ astData }) => { const svgRef = useRef(null); useEffect(() => { if (astData && svgRef.current) { const svg = d3.select(svgRef.current); svg.selectAll('*').remove(); const width = svg.node().getBoundingClientRect().width; const height = svg.node().getBoundingClientRect().height; const margin = { top: 20, right: 20, bottom: 20, left: 20 }; const treeLayout = d3.tree().size([height - margin.top - margin.bottom, width - margin.left - margin.right]); const rootNode = d3.hierarchy(astData); rootNode.x0 = height / 2; rootNode.y0 = 0; const treeData = treeLayout(rootNode); svg.append('g') .attr('transform', `translate(${margin.left},${margin.top})`) .selectAll('.node') .data(treeData.descendants()) .enter() .append('circle') .attr('class', 'node') .attr('cx', d => d.y) .attr('cy', d => d.x) .attr('r', 5); svg.append('g') .attr('transform', `translate(${margin.left},${margin.top})`) .selectAll('.link') .data(treeData.links()) .enter() .append('path') .attr('class', 'link') .attr('d', d3.linkHorizontal() .x(d => d.y) .y(d => d.x)); } }, [astData]); return <svg ref={svgRef} />; }; export default AstVisualization;