chart = {
const width = 928;
const height = width;
var tree = d3.hierarchy(categoryJson)
.sum(d => 1)
.sort((a, b) => Math.random() - 0.5)
const packing = d3.pack()
.size([width, height])
.padding(3)
const root = packing(tree);
const svg = d3.create("svg")
.attr("viewBox", `-${width / 2} -${height / 2} ${width} ${height}`)
.attr("width", width)
.attr("height", height)
.attr("style", `max-width: 100%; height: auto; display: block; margin: 0 -14px; background: ${"white"}; cursor: pointer;`);
const node = svg.append("g")
.selectAll("circle")
.data(root.descendants().slice(1))
.join("circle")
.attr("fill", d => {
console.log('HERE', d);
return getColor(d)
})
.attr("pointer-events", d => !d.children ? "none" : null)
.on("mouseover", function() { d3.select(this).attr("stroke", "#111"); })
.on("mouseout", function() { d3.select(this).attr("stroke", null); })
.on("click", (event, d) => (focus !== d) && (zoom(event, d), event.stopPropagation()));
const label = svg.append("g")
.style("font", "12px sans-serif")
.style("color", "white")
.style("font-weight", "bold")
.style("text-shadow", "1px 1px 0px white, -1px -1px 0px white, 1px -1px 0px white, -1px 1px 0px white")
.attr("pointer-events", "none")
.attr("text-anchor", "middle")
.selectAll("text")
.data(root.descendants())
.join("text")
.style("fill-opacity", d => (d.parent === root) ? 1 : 0)
.style("display", d => (d.parent === root) ? "inline" : "none")
.text(d => d.data.Name);
svg.on("click", (event) => zoom(event, root));
let focus = root;
let view;
zoomTo([focus.x, focus.y, focus.r * 2]);
function zoomTo(v) {
const k = width / v[2];
view = v;
label.attr("transform", d => `translate(${(d.x - v[0]) * k},${(d.y - v[1]) * k})`);
node.attr("transform", d => `translate(${(d.x - v[0]) * k},${(d.y - v[1]) * k})`);
node.attr("r", d => d.r * k);
}
function zoom(event, d) {
const focus0 = focus;
focus = d;
const transition = svg.transition()
.duration(event.altKey ? 7500 : 2000)
.tween("zoom", d => {
const i = d3.interpolateZoom(view, [focus.x, focus.y, focus.r * 2]);
return t => zoomTo(i(t));
});
label
.filter(function(d) { return d.parent === focus || this.style.display === "inline"; })
.transition(transition)
.style("fill-opacity", d => d.parent === focus ? 1 : 0)
.on("start", function(d) { if (d.parent === focus) this.style.display = "inline"; })
.on("end", function(d) { if (d.parent !== focus) this.style.display = "none"; });
}
return svg.node();
}