<!DOCTYPE html>
<meta charset="utf-8">
<!-- Include d3 library -->
<script src="https://d3js.org/d3.v7.min.js"></script>
<!-- Create a container to host the chart -->
<div id="viz_container"></div>
// set the dimensions and margins of the graph
const margin = 80,
height = 450,
width = 450
// append the svg object to the body of the page
const svg = d3.select("#viz_container")
.append("svg")
.attr("width", "100%")
.attr("height", "100%")
.attr("viewBox", "0 0 450 450")
.attr("preserveAspectRatio", "xMinYMin")
.append("g")
.attr("transform", `translate(${width / 2}, ${height / 2})`);
const radius = Math.min(width, height) / 2 - margin
// parse the Data
d3.csv("https://raw.githubusercontent.com/GDS-ODSSS/unhcr-dataviz-platform/master/data/part_to_a_whole/pie.csv")
.then(function(data){
// color palette
const color = d3.scaleOrdinal()
.domain(data)
.range(["#0072BC","#8EBEFF"])
const pie = d3.pie()
.value(d => +d.funding_value)
.sort(null)
const dataPrepared = pie(data)
arc = d3.arc()
.innerRadius(radius/2.3)
.outerRadius(radius)
data.forEach(function(d) {
d.funding_value = +d.funding_value;
d.enabled = true;
});
const total = d3.sum(data.map(function(d) {
return (d.enabled) ? d.funding_value : 0; }));
// create a tooltip
const tooltip = d3.select("body")
.append("div")
.attr("class", "tooltip")
.attr("font-size", "20px");
// tooltip events
const mouseover = function(d) {
tooltip
.style("opacity", 1)
d3.select(this)
.style("opacity", .5)
};
const f = d3.format(",.0f");
const mousemove = function(event,d) {
const percent = Math.round(1000 * d.data.funding_value / total) / 10;
tooltip
.html(`<b>${d.data.funding_type}</b>: `+ percent + '%')
.style("top", event.pageY - 10 + "px")
.style("left", event.pageX + 10 + "px")
};
const mouseleave = function(d) {
tooltip
.style("opacity", 0)
d3.select(this)
.style("stroke", "none")
.style("opacity", 1)
};
svg
.selectAll('path')
.data(dataPrepared)
.join('path')
.attr('d', arc)
.attr('fill', d => color(d.data.funding_type))
.attr("stroke", "#ffffff")
.style("stroke-width", "2px")
.each(function(d) { this._current - d; })
.on("mouseover", mouseover)
.on("mousemove", mousemove)
.on("mouseleave", mouseleave);
svg
.append("g")
.attr("text-anchor", "middle")
.selectAll("text")
.data(dataPrepared)
.join("text")
.attr("transform", d => `translate(${arc.centroid(d)})`)
.call(text => text.append("tspan")
.attr("x", "0.2em")
.attr("y", "-0.6em")
.attr("fill", "#ffffff")
.text(d => d.data.funding_type))
.call(text => text.filter(d => (d.endAngle - d.startAngle) > 0.25).append("tspan")
.attr("x", 0)
.attr("y", "0.7em")
.attr("fill", "#ffffff")
.text(d => "$" + d.data.funding_value.toLocaleString()))
// set title
svg
.append("text")
.attr("class", "chart-title")
.attr("x", -(margin/2+radius))
.attr("y", -(margin/2+radius))
.attr("text-anchor", "start")
.text("2021 UNHCR's funding")
//data label for total
svg
.append("text")
.attr("dy", "-1em")
.style("font-size", "12px")
.style("text-anchor", "middle")
.attr("class", "inner-circle")
.attr("fill", "#222222")
.text("Total required");
svg
.append("text")
.attr("dy", "0.5em")
.style("font-size", "16px")
.style("text-anchor", "middle")
.attr("class", "inner-circle")
.attr("fill", "#222222")
.text("$" + f(total));
// set source
svg
.append("text")
.attr("class", "chart-source")
.attr("x", -(margin/2+radius))
.attr("y", margin/3+radius)
.attr("text-anchor", "start")
.text("Source: UNHCR")
// set copyright
svg
.append("text")
.attr("class", "copyright")
.attr("x", -(margin/2+radius))
.attr("y", margin/2.2+radius)
.attr("text-anchor", "start")
.text("©UNHCR, The UN Refugee Agency")
})