<!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 = {top: 80, right: 20, bottom: 50, left: 40};
const width = 450 - margin.left - margin.right;
const height = 350 - margin.top - margin.bottom;
// 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 350")
.attr("preserveAspectRatio", "xMinYMin")
.append("g")
.attr("transform", `translate(${margin.left}, ${margin.top})`);
// parse the data
d3.csv("https://raw.githubusercontent.com/GDS-ODSSS/unhcr-dataviz-platform/master/data/change_over_time/line.csv", function(d) {
const parseTime = d3.timeParse("%Y")
return {
year: parseTime(d.year),
popType: d.population_type,
popNumber: +d.population_number
};
}).then(function(data){
//pivot the data
const dataGrouped = d3.group(data, d => d.popType)
// list of value keys
const typeKeys = ["Refugees", "IDPs"];
// X scale and Axis
const xScale = d3.scaleTime()
.domain(d3.extent(data, d => d.year)).nice()
.range([0, width]);
svg
.append('g')
.attr("transform", `translate(0, ${height})`)
.call(d3.axisBottom(xScale).tickSize(0).tickPadding(8));
// Y scale and Axis
const formatter = d3.format("~s")
const yScale = d3.scaleLinear()
.domain([0, d3.max(data, d => d.popNumber)])
.range([height, 0]);
svg
.append('g')
.call(d3.axisLeft(yScale).ticks(6).tickSize(0).tickPadding(6).tickFormat(formatter))
.call(d => d.select(".domain").remove());
// set horizontal grid line
const GridLine = () => d3.axisLeft().scale(yScale);
svg
.append("g")
.attr("class", "grid")
.call(GridLine()
.tickSize(-width,0,0)
.tickFormat("")
.ticks(6)
);
// color palette
const color = d3.scaleOrdinal()
.range(["#0072BC","#00B398"])
// create line
const lines = svg
.selectAll("lines")
.data(dataGrouped)
.join("path")
.attr("fill", "none")
.attr("stroke", d => color(d[0]))
.attr("stroke-width", 2)
.attr("d", function(d){
return d3.line()
.curve(d3.curveCardinal)
.x(d => xScale(d.year))
.y(d => yScale(d.popNumber))
(d[1])
});
// set title
svg
.append("text")
.attr("class", "chart-title")
.attr("x", -(margin.left)*0.7)
.attr("y", -(margin.top)/1.5)
.attr("text-anchor", "start")
.text("Number of refugee and IDPs of concern to UNHCR | 1991-2021")
// set Y axis label
svg
.append("text")
.attr("class", "chart-label")
.attr("x", -(margin.left)*0.7)
.attr("y", -(margin.top/9))
.attr("text-anchor", "start")
.text("Displaced population (millions)")
// set source
svg
.append("text")
.attr("class", "chart-source")
.attr("x", -(margin.left)*0.7)
.attr("y", height + margin.bottom*0.7)
.attr("text-anchor", "start")
.text("Source: UNHCR Refugee Data Finder")
// set copyright
svg
.append("text")
.attr("class", "copyright")
.attr("x", -(margin.left)*0.7)
.attr("y", height + margin.bottom*0.9)
.attr("text-anchor", "start")
.text("©UNHCR, The UN Refugee Agency")
// set legend manually
svg
.append("circle")
.attr("cx", -(margin.left)*0.6)
.attr("cy", -(margin.top/2.5))
.attr("r", 5)
.style("fill", "#0072BC");
svg
.append("text")
.attr("class", "legend")
.attr("x", -(margin.left)*0.6+10)
.attr("y", -(margin.top/2.5))
.attr("alignment-baseline","middle")
.text("Refugees")
svg
.append("circle")
.attr("cx", 60)
.attr("cy", -(margin.top/2.5))
.attr("r", 5)
.style("fill", "#00B398")
svg
.append("text")
.attr("class", "legend")
.attr("x", 70)
.attr("y", -(margin.top/2.5))
.attr("alignment-baseline","middle")
.text("IDPs")
})