174 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			174 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <!DOCTYPE html>
 | |
| <meta charset="utf-8">
 | |
| <style>
 | |
| 
 | |
| .node circle {
 | |
|   fill: #999;
 | |
| }
 | |
| 
 | |
| .node text {
 | |
|   font: 10px sans-serif;
 | |
| }
 | |
| 
 | |
| .node--internal circle {
 | |
|   fill: #555;
 | |
| }
 | |
| 
 | |
| .node--internal text {
 | |
|   text-shadow: 0 1px 0 #fff, 0 -1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff;
 | |
| }
 | |
| 
 | |
| .link {
 | |
|   fill: none;
 | |
|   stroke: #555;
 | |
|   stroke-opacity: 0.4;
 | |
|   stroke-width: 1.5px;
 | |
| }
 | |
| 
 | |
| </style>
 | |
| <svg width="960" height="512"></svg>
 | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
 | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/fetch/2.0.3/fetch.min.js"></script>
 | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.7.1/d3.min.js"></script>
 | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/acorn/4.0.11/acorn.min.js"></script>
 | |
| <script>
 | |
| 
 | |
| fetch("../apps/loader/js/main.js")
 | |
| 	.then(response => response.text())
 | |
| 	.then(text => {
 | |
| 		const ast = acorn.parse(text, {
 | |
| 			sourceType: "module",
 | |
| 		    // collect ranges for each node
 | |
| 		    ranges: true,
 | |
| 		    // collect comments in Esprima's format
 | |
| 		    onComment: null,
 | |
| 		    // collect token ranges
 | |
| 		    onToken: null
 | |
| 		})
 | |
| 		
 | |
| 		console.info(ast)
 | |
| 
 | |
| 		drawAst(ast)
 | |
| 	})
 | |
| 
 | |
| /*
 | |
|  *
 | |
|  */
 | |
| function drawAst(ast) {
 | |
| 	
 | |
| 	// Create SVG element
 | |
| 	//---------------------------
 | |
| 	let svg = d3.select("svg")
 | |
| 	const width = svg.attr("width")
 | |
| 	const height = svg.attr("height")
 | |
| 	let g = svg.append("g").attr("transform", "translate(40,0)")
 | |
| 	
 | |
| 	// Convert data
 | |
| 	//---------------------------
 | |
| 	const data = acornToHierarchy(ast)
 | |
| 	
 | |
| 	// Create D3 Hierarchy
 | |
| 	//---------------------------
 | |
| 	let root = d3.hierarchy(data).sort((a, b) => {
 | |
| 		return (a.height - b.height) || a.data.name.localeCompare(b.data.name);
 | |
| 	})
 | |
| 
 | |
| 	// Create D3 Cluster
 | |
| 	//---------------------------
 | |
| 	let tree = d3.cluster().size([height, width - 200])
 | |
| 	tree(root)
 | |
| 	
 | |
| 	// Create SVG elements
 | |
| 	//---------------------------
 | |
| 	let link = g.selectAll(".link")
 | |
| 		.data(root.descendants().slice(1))
 | |
| 		.enter().append("path")
 | |
| 			.attr("class", "link")
 | |
| 			.attr("d", d => {
 | |
| 				return `M${d.y},${d.x}C${d.parent.y + 100},${d.x} ${d.parent.y + 100},${d.parent.x} ${d.parent.y},${d.parent.x}`
 | |
| 			})
 | |
| 	
 | |
| 	let node = g.selectAll(".node")
 | |
| 		.data(root.descendants())
 | |
| 		.enter().append("g")
 | |
| 			.attr("class", d => "node" + (d.children ? " node--internal" : " node--leaf"))
 | |
| 			.attr("transform", d => `translate(${d.y},${d.x})`)
 | |
| 	
 | |
| 	node.append("circle")
 | |
| 		.attr("r", 5)
 | |
| 	
 | |
| 	node.append("text")
 | |
| 		.attr("dy", 3)
 | |
| 		.attr("x", d => d.children ? -8 : 8)
 | |
| 		.style("text-anchor", d => d.children ? "end" : "start")
 | |
| 		.text(d => d.data.name)
 | |
| }
 | |
| 
 | |
| /*
 | |
|  *
 | |
|  */
 | |
| function acornToHierarchy(ast) {
 | |
| 	
 | |
| 	console.info(JSON.stringify(ast))
 | |
| 	
 | |
| 	let data = {}
 | |
| 	
 | |
| 	for (const clazz of ast.body) {
 | |
| 		if (clazz.type === "ClassDeclaration") {
 | |
| 			data.name = clazz.id.name
 | |
| 			data.children = []
 | |
| 			
 | |
| 			for (const method of clazz.body.body) {
 | |
| 				if (method.type === "MethodDefinition") {
 | |
| 					data.children.push({
 | |
| 						name: method.key.name,
 | |
| 						children: []
 | |
| 					})
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	
 | |
| 	/*
 | |
| 	const data = {
 | |
| 		"name": "Eve",
 | |
| 		"children": [{
 | |
| 			"name": "Cain"
 | |
| 		}, {
 | |
| 			"name": "Seth",
 | |
| 			"children": [{
 | |
| 				"name": "Enos"
 | |
| 			}, {
 | |
| 				"name": "Noam"
 | |
| 			}]
 | |
| 		}, {
 | |
| 			"name": "Abel"
 | |
| 		}, {
 | |
| 			"name": "Awan",
 | |
| 			"children": [{
 | |
| 				"name": "Enoch"
 | |
| 			}]
 | |
| 		}, {
 | |
| 			"name": "Azura"
 | |
| 		}]
 | |
| 	}
 | |
| 	*/
 | |
| 	
 | |
| 	return data
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| </script> |