{
const width = 600;
const height = 500;
const radius = Math.min(width, height) / 2 - 20;
const filtered = animal_shelter.filter(d => (d[pieFilterField] ?? "Unknown") === pieFilterValue);
const counts = {};
for (const d of filtered) {
const type = d.movementtype || "Unknown";
counts[type] = (counts[type] || 0) + 1;
}
const pieData = Object.entries(counts).map(([movementtype, count]) => ({
movementtype,
count
}));
const pie = d3.pie().value(d => d.count);
const arc = d3.arc().innerRadius(80).outerRadius(radius);
const arcs = pie(pieData);
const color = d3.scaleOrdinal()
.domain(pieData.map(d => d.movementtype))
.range(d3.schemeCategory10);
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height)
.style("font", "12px sans-serif");
const g = svg.append("g")
.attr("transform", `translate(${radius + 20},${height / 2})`);
g.selectAll("path")
.data(arcs)
.join("path")
.attr("fill", d => color(d.data.movementtype))
.attr("d", arc)
.append("title")
.text(d => `${d.data.movementtype}: ${d.data.count}`);
const legend = svg.append("g")
.attr("transform", `translate(${radius * 2 + 60}, 40)`);
pieData.forEach((d, i) => {
const y = i * 20;
legend.append("rect")
.attr("x", 0)
.attr("y", y)
.attr("width", 12)
.attr("height", 12)
.attr("fill", color(d.movementtype));
legend.append("text")
.attr("x", 18)
.attr("y", y + 10)
.text(d.movementtype);
});
return svg.node();
}