chart = (data) => {
const svg = d3
.create("svg")
.attr("width", width)
.attr("height", height)
.attr("viewBox", [-margin, -margin, width, height])
.attr("style", "width: 100%; height: auto; font: 10px sans-serif;")
.attr("text-anchor", "middle");
const node = svg
.append("g")
.selectAll()
.data(root.descendants())
.join("g")
.attr("transform", (d) => `translate(${d.x},${d.y})`);
node.append("title").text(
(d) =>
`${d
.ancestors()
.map((d) => d.data.name)
.reverse()
.join("/")}\n\n${d.data.description}`
);
node
.append("circle")
.attr("stroke", (d) => colorMap[d.data.language])
.attr("stroke-width", 3)
.attr("fill", (d) => colorMap[d.data.language])
.attr("fill-opacity", 0.3)
.attr("r", (d) => d.r);
const leaf = node.filter((d) => !d.children);
leaf
.append("text")
.selectAll("tspan")
.data((d) => d.data.name.split(/\s+/g))
.join("tspan")
.attr("x", 0)
.attr("y", (d, i, nodes) => `${i - nodes.length / 2 + 0.8}em`)
.attr("fill", "#40081C")
.text((d) => d)
.clone(true)
.lower()
.attr("aria-hidden", "true")
.attr("fill", "none")
.attr("stroke", "#FAEBF0")
.attr("stroke-width", 2)
.attr("stroke-linecap", "round")
.attr("stroke-linejoin", "round");
const groupLabel = svg
.append("g")
.attr("pointer-events", "none")
.attr("text-anchor", "middle")
.selectAll("text")
.data(root.descendants().filter((d) => d.children))
.join("text")
.text((d) => d.data.name);
groupLabel
.attr("transform", (d) => `translate(${d.x}, ${d.y - d.r})`)
.attr("dy", "-0.25em")
.attr("fill", "#fff")
.clone(true)
.lower()
.attr("aria-hidden", "true")
.attr("fill", "none")
.attr("stroke", "black")
.attr("stroke-width", 2)
.attr("stroke-linecap", "round")
.attr("stroke-linejoin", "round");
return svg.node();
}