Published
Edited
Jul 6, 2020
Importers
Insert cell
Insert cell
import { Lexer } from "@joelsunny/lexer"
Insert cell
// Parse Tree data structure definition
class TreeNode {
constructor(label, value, id) {
this.label = label
this.value = value
this.id = id
this.children = []
this.parent = null
}

addChild(child) {
child.parent = this
this.children.push(child)
}

to_object() {
let o = new Object()
o.label = this.label
o.value = this.value
o.id = this.id
o.children = []
o.parent = this.parent
if (this.children.length != 0) {
this.children
.forEach(n => {
// console.log("to object");
// console.log(n);
o.children.push(n.to_object());
});
}
return o;
}
}
Insert cell
class Tree {
constructor(label, value) {
this.root = new TreeNode(label, value, 0)
this.node_count = 1
}

addChild(node, label, value) {
let n = new TreeNode(label, value, this.node_count);
node.addChild(n)
this.node_count = this.node_count + 1
}
addSubTree(node, treeRoot) {
node.addChild(treeRoot.root);
}
delSubTree(node) {
node.children = []
}
to_json() {
return this.root.to_object()
}
}
Insert cell
vgraph = function(data) {
const width = 300;
const height = 500;
let tree = data => {
const root = d3.hierarchy(data);
root.dx = 20;
//root.dy = height / (root.height + 1);
root.dy = 30;
return d3.tree().nodeSize([root.dx, root.dy])(root);
}
// data -> json data
const root = tree(data);
// find both extremes along the x axis
let x0 = Infinity;
let x1 = -x0;
root.each(d => {
//console.log(d);
if (d.x > x1) x1 = d.x;
if (d.x < x0) x0 = d.x;
});
console.log(x0, x1);
let h = root.dy*(root.height+1) + 20
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, h]);
// create a grouping and translate so that all elements are fully visible
const g = svg.append("g")
.attr("font-family", "sans-serif")
.attr("font-size", 10)
.attr("overflow", "scroll")
.attr("transform", `translate(${(x1-x0)/2 + root.dx},${root.dx})`);
// add links of the graph
const link = g.append("g")
.attr("fill", "none")
.attr("stroke", "rgba(49, 130, 180, 0.34)")
.attr("stroke-opacity", 0.4)
.attr("stroke-width", 1.5)
.selectAll("path")
.data(root.links())
.join("path")
.attr("d", d3.linkHorizontal()
.y(d => d.y-2)
.x(d => d.x));
// add groups corresponding to each node
const node = g.append("g")
.attr("stroke-linejoin", "round")
.attr("stroke-width", 3)
.style("font", "6px courier")
.selectAll("g")
.data(root.descendants())
.join("g")
.attr("transform", d => `translate(${d.x},${d.y})`);
// mark nodes as circles
node.append("circle")
.attr("fill", d => d.children ? "rgba(244, 35, 35, 0.36)" : "rgba(70, 204, 60, 0.4)")
.attr("r", 4.5);
// add text to each node
node.append("text")
.attr("dy", "0.1em")
.attr("x", d => d.children ? 0 : 0)
.attr("y", d => d.children ? 1 : 10)
.attr("text-anchor", "middle")
.text(d => d.data.value)
.clone(true).lower()
.attr("stroke", "white");
return svg.node();
}
Insert cell
hgraph({"value" : "10"})
Insert cell
hgraph = function(data) {
const width = 700;
const height = 300;
let tree = data => {
const root = d3.hierarchy(data);
root.dx = 30;
root.dy = height / (root.height + 1);
return d3.tree().nodeSize([root.dx, root.dy])(root);
}
const root = tree(data);

let x0 = Infinity;
let x1 = -x0;
root.each(d => {
//console.log(d);
if (d.x > x1) x1 = d.x;
if (d.x < x0) x0 = d.x;
});
console.log(x0, x1);
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height]);
const g = svg.append("g")
.attr("font-family", "sans-serif")
.attr("font-size", 10)
.attr("transform", `translate(${root.dy / 3},${height/2})`);
const link = g.append("g")
.attr("fill", "none")
.attr("stroke", "#555")
.attr("stroke-opacity", 0.4)
.attr("stroke-width", 1.5)
.selectAll("path")
.data(root.links())
.join("path")
.attr("d", d3.linkHorizontal()
.x(d => d.y)
.y(d => d.x));
const node = g.append("g")
.attr("stroke-linejoin", "round")
.attr("stroke-width", 3)
.style("font", "10px courier")
.selectAll("g")
.data(root.descendants())
.join("g")
.attr("transform", d => `translate(${d.y},${d.x})`);

node.append("circle")
.attr("fill", d => d.children ? "rgba(244, 35, 35, 0.36)" : "rgba(70, 204, 60, 0.4)")
.attr("r", 6.5);

node.append("text")
.attr("dy", "0.31em")
.attr("x", d => d.children ? 0 : 15)
.attr("text-anchor", d => d.children ? "middle" : "end")
.text(d => d.data.value)
.clone(true).lower()
.attr("stroke", "white");
return svg.node();
}
Insert cell
d3 = require("d3@5")
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more