chart = {
const nodes = root.descendants();
const svg = d3.create("svg")
.attr("viewBox", [-nodeWidth / 2, -nodeHeight * 3 / 2, width, (root.maxIndex+1) * nodeHeight])
.attr("font-family", "sans-serif")
.attr("font-size", 12)
.style("overflow", "visible");
const link = svg.append("g")
.attr("fill", "none")
.attr('stroke-width', 2)
.selectAll("path")
.data(root.links())
.join("path")
.attr("d", d => {
let p1 = {x: d.source.depth * 2 * nodeWidth, y: d.source.index * nodeHeight}
let pc = {x: (d.source.depth*2 + 1.25) * nodeWidth, y: (d.target.index-1) * nodeHeight}
let p2 = {x: (d.source.depth+1) * 2 * nodeWidth, y: d.target.index * nodeHeight}
return rounded(p1, pc, {corner_radius: 16}).toString() + rounded(pc, p2, {sweep: false, corner_radius: 16}).toString()
})
.attr('stroke', d => (colors ? color(d.source.index) : '#999'));
const node = svg.append("g")
.selectAll("g")
.data(nodes)
.join("g")
.attr("transform", d => `translate(0,${d.index * nodeHeight})`);
node.append("circle")
.attr("cx", d => d.depth * 2 * nodeWidth)
.attr("r", 4.5)
.attr('stroke', d => d.children ? 'black' : (colors ? color(d.parent.index) : '#999'))
.attr('stroke-width', d => d.children ? 2.5 : 1.75)
.attr("fill", d => d.children ? 'white' : (colors ? color(d.parent.index) : '#999'));
node.append("text")
.attr("dy", d => d.children ? "-0.6em" : "0.32em")
.attr("x", d => d.depth * 2 * nodeWidth + (d.children ? 4 : 10))
.style("font-size", 14)
.style("font-weight", d => d.children ? 'bold' : 'normal')
.text(d => d.data.name);
node.append("title")
.text(d => d.ancestors().reverse().map(d => d.data.name).join("/"));
return svg.node();
}