radialTree = {
const colours = { views: "coral", table: "green", "": "steelblue" };
let newnodes;
let allnodes;
const svg = d3
.select(DOM.svg(width, width))
.style("width", "100%")
.style("height", "auto")
.style("padding", "10px")
.style("box-sizing", "border-box")
.style("font", "12px sans-serif");
var g = svg.append("g");
const linkgroup = g
.append("g")
.attr("fill", "none")
.attr("stroke", "#555")
.attr("stroke-opacity", 0.4)
.attr("stroke-width", 1.5);
const nodegroup = g
.append("g")
.attr("stroke-linejoin", "round")
.attr("stroke-width", 3);
function newdata(animate = true) {
let root = tree(data);
let links_data = root.links();
let links = linkgroup
.selectAll("path")
.data(links_data, (d) => d.source.data.name + "_" + d.target.data.name);
links.exit().remove();
let newlinks = links
.enter()
.append("path")
.attr(
"d",
d3
.linkRadial()
.angle((d) => d.x)
.radius(0.1)
);
let t = d3
.transition()
.duration(animate ? 400 : 0)
.ease(d3.easeLinear)
.on("end", function () {
const box = g.node().getBBox();
d3.select("svg")
.transition()
.duration(1000)
.attr("viewBox", `${box.x} ${box.y} ${box.width} ${box.height}`);
});
let alllinks = linkgroup.selectAll("path");
alllinks.transition(t).attr(
"d",
d3
.linkRadial()
.angle((d) => d.x)
.radius((d) => d.y)
);
let nodes_data = root.descendants().reverse();
let nodes = nodegroup.selectAll("g").data(nodes_data, function (d) {
if (d.parent) {
return d.parent.data.name + d.data.name;
}
return d.data.name;
});
nodes.exit().remove();
newnodes = nodes.enter().append("g");
allnodes = animate
? nodegroup.selectAll("g").transition(t)
: nodegroup.selectAll("g");
allnodes.attr(
"transform",
(d) => `
rotate(${(d.x * 180) / Math.PI - 90})
translate(${d.y},0)
`
);
newnodes
.append("circle")
.attr("r", 4.5)
.attr("stroke", (d) => colours[d.data.opt] || "black")
.on("click", function (d) {
let altChildren = d.data.altChildren || [];
let children = d.data.children;
d.data.children = altChildren;
d.data.altChildren = children;
newdata();
});
// newnodes.each(function (d) {
// if (d.data.opt == "") {
// // console.log(d.data);
// // d.data.children = d.data.children;
// d.data.altChildren = null;
// }
// });
// newdata();
// nodegroup.selectAll("g circle").attr("fill", function (d) {
// let altChildren = d.data.altChildren || [];
// let children = d.data.children;
// return d.children ||
// (children && (children.length > 0 || altChildren.length > 0))
// ? "#555"
// : "#999";
// });
newnodes
.append("text")
.attr("dy", "0.451em")
.text((d) => d.data.name)
.clone(true)
.lower()
.attr("stroke", "white");
nodegroup
.selectAll("g text")
.attr("x", (d) => (d.x < Math.PI === !d.children ? 6 : -6))
.attr("text-anchor", (d) =>
d.x < Math.PI === !d.children ? "start" : "end"
)
.attr("transform", (d) => (d.x >= Math.PI ? "rotate(180)" : null));
}
newdata(false);
document.body.appendChild(svg.node());
const box = g.node().getBBox();
//box.width = box.height = Math.max(box.width, box.height)*1.2;
svg
.remove()
.attr("width", box.width)
.attr("height", box.height)
.attr("viewBox", `${box.x} ${box.y} ${box.width} ${box.height}`);
const zoom = d3.zoom().scaleExtent([1, 40]).on("zoom", zoomed);
svg.call(zoom);
function random() {
const [x, y] = data[Math.floor(Math.random() * data.length)];
svg
.transition()
.duration(2500)
.call(
zoom.transform,
d3.zoomIdentity
.translate(width / 2, width / 2)
.scale(40)
.translate(-x, -y)
);
}
function reset() {
svg
.transition()
.duration(750)
.call(
zoom.transform,
d3.zoomIdentity,
d3.zoomTransform(svg.node()).invert([width / 2, width / 2])
);
}
// return svg.node();
function zoomed({ transform }) {
g.attr("transform", transform);
}
return Object.assign(svg.node(), {
zoomIn: () => svg.transition().call(zoom.scaleBy, 2),
zoomOut: () => svg.transition().call(zoom.scaleBy, 0.5),
zoomRandom: random,
zoomReset: reset
});
}