chart = {
const radiusScale = 0.8;
const chartOffsetY = 500;
const root = tree(d3.hierarchy(data)
.sort((a, b) => d3.descending(a.data.value, b.data.value))
);
setColor(root);
const svg = d3.create("svg");
const titleGroup = svg.append("g")
.attr("font-family", "sans-serif")
.attr("font-size", 14)
.attr("text-anchor", "middle")
.attr("transform", `translate(0, 20)`);
const metadata = [
"Mapping the Web of Seattle Nightlife: A Network View of Bars, Lounges, and Social Hubs",
"Data Source: Author-collected data (2025)",
"Author: Fatimah Abanur hassan",
"Date of Creation: May 2025"
];
titleGroup.selectAll("text")
.data(metadata)
.join("text")
.attr("x", 0)
.attr("y", (d, i) => i * 18)
.text(d => d);
const g = svg.append("g")
.attr("transform", `translate(0, ${chartOffsetY})`);
g.append("g")
.attr("fill", "none")
.attr("stroke", "grey")
.attr("stroke-opacity", 0.4)
.attr("stroke-width", 1.5)
.selectAll("path")
.data(root.links())
.join("path")
.attr("d", d3.linkRadial()
.angle(d => d.x)
.radius(d => d.y * radiusScale))
.each(function(d) { d.target.linkNode = this; })
.attr("stroke", d => d.target.color);
g.append("g")
.selectAll("circle")
.data(root.descendants())
.join("circle")
.attr("transform", d => `
rotate(${d.x * 180 / Math.PI - 90})
translate(${d.y * radiusScale},0)
`)
.attr("fill", d => d.children ? color(d.data.name) : color(d.data.group))
.attr("fill-opacity", d => d.children ? 1 : CircleAlpha(d.data.value))
.attr("r", d => d.children ? 4 : CirSize(d.data.value));
g.append("g")
.attr("font-family", "sans-serif")
.attr("stroke-linejoin", "round")
.attr("stroke-width", 3)
.selectAll("text")
.data(root.descendants())
.join("text")
.attr("font-size", d => d.children ? 8 : 10)
.attr("transform", d => `
rotate(${d.x * 180 / Math.PI - 90})
translate(${d.y * radiusScale},0)
rotate(${d.x >= Math.PI ? 180 : 0})
`)
.attr("dy", "0.31em")
.attr("x", d => d.x < Math.PI === !d.children ? 6 : -6)
.attr("text-anchor", d => d.x < Math.PI === !d.children ? "start" : "end")
.text(d => shortenText(d.data.name, 15))
.clone(true).lower()
.attr("stroke", "white");
return svg.attr("viewBox", autoBox).node();
}