chart = {
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height])
.attr("stroke-width", 2);
const points = d3.range(50).map(i => ({
x: Math.random() * (width - 32 * 2) + 32,
y: Math.random() * (height - 32 * 2) + 32,
}));
let voronoi = d3.Delaunay
.from(points, d => d.x, d => d.y)
.voronoi([0, 0, width, height]);
console.log([...voronoi.cellPolygons()][0])
const circles = [...voronoi.cellPolygons()].map((polygon) => {
const [x, y] = d3.polygonCentroid(polygon);
const [cx,cy] = findIncenter(polygon);
const radius = 0.7 * Math.sqrt(Math.abs(d3.polygonArea(polygon)) / Math.PI);
return {
x: Number(x.toFixed(2)),
y: Number(y.toFixed(2)),
r: Number(radius.toFixed(2)),
cx,
cy
};
});
const circle = svg.append("g")
.selectAll("circle")
.data(circles)
.join("circle")
.attr("cx", d => d.cx)
.attr("cy", d => d.cy)
.attr("r", d=>d.r)
.attr("fill", (d, i) => d3.schemeCategory10[i % 10]).call(
d3.drag()
.on("start", (event, d) => {
circle.filter(p => p === d).raise().attr("stroke", "black");
})
.on("drag", (event, d) => {
d.x = event.x;
d.y = event.y;
update(d);
})
.on("end", (event, d) => {
circle.filter(p => p === d).attr("stroke", null);
})
);
const mesh = svg.append("path")
.attr("fill", "none")
.attr("stroke", "#ccc")
.attr("stroke-width", 1)
.attr("d", voronoi.render());
function update(dragalbeCircle) {
voronoi = d3.Delaunay.from(circles, d => d.x, d => d.y).voronoi([0, 0, width, height]);
circle.each((d, i, nodes) => {
const polygon = voronoi.cellPolygon(i);
const [x, y] = d3.polygonCentroid(polygon);
const [cx,cy] = findIncenter(polygon);
const radius = 0.7 * Math.sqrt(Math.abs(d3.polygonArea(polygon)) / Math.PI);
d.r = Number(radius.toFixed(2));
d.cx=cx;
d.cy=cy;
if (dragalbeCircle === d){
d.x = x;
d.y = y;
}
})
.attr("r", d => d.r)
.attr("cx", d => d.cx)
.attr("cy", d => d.cy);
mesh.attr("d", voronoi.render());
}
return svg.node();
}