vgraph = function(data) {
const width = 300;
const height = 500;
let tree = data => {
const root = d3.hierarchy(data);
root.dx = 20;
root.dy = 30;
return d3.tree().nodeSize([root.dx, root.dy])(root);
}
const root = tree(data);
let x0 = Infinity;
let x1 = -x0;
root.each(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]);
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})`);
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));
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})`);
node.append("circle")
.attr("fill", d => d.children ? "rgba(244, 35, 35, 0.36)" : "rgba(70, 204, 60, 0.4)")
.attr("r", 4.5);
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();
}