UNHCR Logo
  • Guidance
  • Chart types
  • Resources
  • Tutorials
  • Product gallery
Tutorials
  • R
    • Change over time
    • Comparison
    • Correlation
    • Distribution
    • Geospatial
    • Part-to-a-whole
    • Ranking
  • Matplotlib
    • Change over time
    • Comparison
    • Correlation
    • Distribution
    • Part-to-a-whole
    • Ranking
  • Plotly Python
    • Comparison
  • D3
    • Change over time
    • Comparison
    • Correlation
    • Distribution
    • Geospatial
    • Part-to-a-whole
On this page
  • Area chart
  • Line chart
  • Line column chart
  • Stacked area chart
  • Streamgraph
  1. Home
  2. Tutorials
  3. D3
  4. Change over time

Area chart

An area chart, like a line chart, displays the evolution of numeric variables over a continuous period of time. However, in an area chart, the area between the line and x-axis is filled with colour or texture.

More about: Area chart - Other tutorials: R Matplotlib

            
              <!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="area_container"></div>
            
          
            
                             
            
          
            
              
              // set the dimensions and margins of the graph
              const margin = {top: 50, 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("#area_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/area_d3.csv").
              then(function(data){

              // X scale and Axis
              const parseTime = d3.timeParse("%Y")
              const xScale = d3.scaleTime()
                .domain(d3.extent(data, d => parseTime(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 formater =  d3.format("~s")
              const yScale = d3.scaleLinear()
              .domain([0, d3.max(data, d => +d.refugee_number)])
              .range([height, 0]);
              svg
                .append('g')
                .call(d3.axisLeft(yScale).ticks(6).tickSize(0).tickPadding(6).tickFormat(formater))
                .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)
              );

              // draw graph
              svg
                .append("path")
                .datum(data)
                    .attr("fill", "#0072BC")
                    .attr("d", d3.area()
                        .x(d => xScale(parseTime(d.year)))
                        .y0(yScale(0))
                        .y1(d => yScale(+d.refugee_number))
                        );
                                      
              // 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 refugees | 1991-2021")

              // set Y axis label
              svg
                .append("text")
                  .attr("class", "chart-label")
                  .attr("x", -(margin.left)*0.7)
                  .attr("y", -(margin.top/4))
                  .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")
              })
            
          

Line chart

A line chart is a type of chart that displays the evolution of one or several numeric variables over a continuous interval or time period. Typically, the x-axis is used for a timescale or a sequence of intervals, while the y-axis reports values across that progression.

More about: Line chart - Other tutorials: R Matplotlib

            
              <!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="line_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("#line_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")
              
              })
            
          

Line column chart

A line column chart is a type of visualization that combines both line and column charts together, using dual axes displayed on the left and right sides of the chart. It allows us to show the relationship of two variables with different magnitudes and scales.

More about: Line column chart - Other tutorials: R Matplotlib

            
              <!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="line_column_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("#line_column_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_column.csv")
              .then(function(data){

              // X scale and Axis
              const xScale = d3.scaleBand()
                .domain(data.map(d => d.year)) 
                .range([0, width])
                .padding(.2);  
              svg
                .append('g')
                .style("color", "#666666")
                .attr("transform", "translate(0," + height + ")")
                .call(d3.axisBottom(xScale).tickSize(0).tickPadding(8));
              
              // Y scale and Axis
              const yScale1 = d3.scaleLinear()
                  .domain([0, 90])
                  .range([height, 0]);
              svg
                .append('g')
                .call(d3.axisLeft(yScale1).ticks(10).tickSize(0).tickPadding(6))
                .call(d => d.select(".domain").remove());
              
              const yScale2 = d3.scaleLinear()
                .domain([0, 9])
                .range([height, 0]);
              svg
                .append('g')
                .attr("transform", `translate(${width}, 0)`)
                .call(d3.axisRight(yScale2).ticks(10).tickSize(0).tickPadding(6))
                .call(d => d.select(".domain").remove());

              // set horizontal grid line
              const GridLine = () => d3.axisLeft().scale(yScale1);
              svg
                .append("g")
                  .attr("class", "grid")
                .call(GridLine()
                  .tickSize(-width,0,0)
                  .tickFormat("")
              );

              // create a tooltip
              const tooltip = d3.select("body")
                .append("div")
                  .attr("id", "chart")
                  .attr("class", "tooltip");

              // tooltip events
              const mouseover = function(d) {
                  tooltip
                    .style("opacity", .8)
                  d3.select(this)
                    .style("opacity", .5)
              }
              const mousemove = function(event, d) {
                const formater =  d3.format(",")
                  tooltip
                    .html(formater(+d.displaced_population))
                    .style("top", event.pageY - 10 + "px")
                    .style("left", event.pageX + 10 + "px");
              }
              const mouseleave = function(d) {
                  tooltip
                    .style("opacity", 0)
                  d3.select(this)
                    .style("opacity", 1)
              }
              
              // create bar
              const bar = svg 
                  .selectAll("rect")
                  .data(data)
                  .join("g")
                  .append("rect")
                    .attr("class", "bar")
                    .style("fill", "#0072BC")
                    .attr("x", d => xScale(d.year))
                    .attr("y", d => yScale1(+d.displaced_population))
                    .attr("width", xScale.bandwidth())
                    .attr("height", d => height - yScale1(+d.displaced_population))
                  .on("mouseover", mouseover)
                  .on("mousemove", mousemove)
                  .on("mouseleave", mouseleave);
              
              // create line
              svg
                  .append("path")
                  .datum(data)
                      .attr("class", "line")
                      .attr("fill", "none")
                      .attr("stroke", "#18375F")
                      .attr("stroke-width", 2)
                      .attr("d", d3.line()
                          .x(d => xScale(d.year) + xScale.bandwidth() / 2)
                          .y(d => yScale2(d.displaced_proportion))
                          );
              
              // set title
              svg
                .append("text")
                  .attr("class", "chart-title")
                  .attr("x", -(margin.left)*0.5)
                  .attr("y", -(margin.top)/1.5)
                  .attr("text-anchor", "start")
                .text("Trend of global displacement | 2007-2016")

                // set Y axis 1 label
                svg
                  .append("text")
                    .attr("class", "label_left")
                    .attr("x", -(margin.left)*0.5)
                    .attr("y", -(margin.top/4))
                    .attr("text-anchor", "start")
                    .style("fill", "#0072BC")
                  .text("Displaced population (millions)")
                
                // set Y axis 2 label
                svg
                 .append("text")
                   .attr("class", "label_right")
                   .attr("x", width+15)
                   .attr("y", -(margin.top/2.7))
                   .attr("text-anchor", "end")
                   .style("fill", "#18375F")
                 .text("Proportion displaced")
                svg
                  .append("text")
                    .attr("class", "label_right")
                    .attr("x", width+15)
                    .attr("y", -(margin.top/4))
                    .attr("text-anchor", "end")
                    .style("fill", "#18375F")
                  .text("(Number displaced per 1,000 world population)")
              
              // set source
              svg
                .append("text")
                  .attr("class", "chart-source")
                  .attr("x", -(margin.left)*0.5)
                  .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.5)
                  .attr("y", height + margin.bottom*0.9)
                  .attr("text-anchor", "start")
                .text("©UNHCR, The UN Refugee Agency")
              
              })
            
          

Stacked area chart

As a variation of a simple area chart, a stacked area chart displays the changes of value of multiple data series over a period of time. The values of each data series are plotted on top of each other, which allows tracking not only the evolution of total value but also the breakdown of that total by groups.

More about: Stacked area chart - Other tutorials: R Matplotlib

            
              <!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="stacked_area_container"></div>
            
          
            
                             
            
          
            
              
              // set the dimensions and margins of the graph
              const margin = {top: 100, 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("#stacked_area_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/area_stacked_d3.csv")
              .then(function(data){

              // list of value keys
              const typeKeys = data.columns.slice(1);
              const monthKeys = data.map(d => d.months)
     
              // stack the data
              const stack = d3.stack()
                 .keys(typeKeys)
                 .order(d3.stackOrderNone)
                 .offset(d3.stackOffsetNone)
              const stackedData = stack(data)

              // X scale and Axis
              const xScale = d3.scalePoint()
                .domain(monthKeys)
                .range([0, width])
                .padding(.2);
              svg
                .append('g')
                .attr("transform", `translate(0, ${height})`)
                .call(d3.axisBottom(xScale).tickSize(0).tickPadding(8));
              
              // Y scale and Axis
              const yScale = d3.scaleLinear()
                  .domain([0, 500])
                  .range([height, 0]);
              svg
                .append('g')
                .call(d3.axisLeft(yScale).ticks(9).tickSize(0).tickPadding(6))
                .call(d => d.select(".domain").remove());

              // color palette
              const color = d3.scaleOrdinal()
                .domain(typeKeys)
                .range(["#18375F", "#0072BC", "#8EBEFF", "#00B398"])
              
              // set horizontal grid line
              const GridLine = () => d3.axisLeft().scale(yScale);
              svg
                .append("g")
                  .attr("class", "grid")
                .call(GridLine()
                  .tickSize(-width,0,0)
                  .tickFormat("")
              ); 

              // create a tooltip
              const tooltip = d3.select("body")
                .append("div")
                  .attr("id", "chart")
                  .attr("class", "tooltip");

              // tooltip events
              const mouseover = function(d) {
                  tooltip
                    .style("opacity", .8)
                  d3.select(this)
                    .style("opacity", .5)
              }
              const mouseleave = function(d) {
                  tooltip
                    .style("opacity", 0)
                  d3.select(this)
                    .style("opacity", 1)}
              
              svg
              .append("g")
              .selectAll("g")
              .data(stackedData)
              .join("path")
                  .attr("fill", d => color(d.key))
                  .attr("d", d3.area()
                      .x(d => xScale(d.data.months))
                      .y0(d => yScale(+d[0]))
                      .y1(d => yScale(+d[1]))
                  )
                  .attr("width", xScale.bandwidth())
                  .attr("height", d => yScale(d[0]) - yScale(d[1]))
                  .on("mouseover", mouseover)
                  .on("mouseleave", mouseleave)
              
              // set title
              svg
                .append("text")
                  .attr("class", "chart-title")
                  .attr("x", -(margin.left)*0.6)
                  .attr("y", -(margin.top)/1.5)
                  .attr("text-anchor", "start")
                .text("Evolution of funding in West Africa region | 2020")

              // set Y axis label
              svg
                .append("text")
                  .attr("class", "chart-label")
                  .attr("x", -(margin.left)*0.6)
                  .attr("y", -(margin.top/8))
                  .attr("text-anchor", "start")
                .text("USD millions")
              
              // set source
              svg
                .append("text")
                  .attr("class", "chart-source")
                  .attr("x", -(margin.left)*0.6)
                  .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.6)
                  .attr("y", height + margin.bottom*0.9)
                  .attr("text-anchor", "start")
                .text("©UNHCR, The UN Refugee Agency")
              
              //set legend
              svg
                  .append("rect")
                      .attr("x", -(margin.left)*0.6)
                      .attr("y", -(margin.top/2))
                      .attr("width", 13)
                      .attr("height", 13)
                      .style("fill", "#18375F")
              svg
                  .append("text")
                      .attr("class", "legend")
                      .attr("x", -(margin.left)*0.6+20)
                      .attr("y", -(margin.top/2.5))
                  .text("Earmarked")
              svg
                  .append("rect")
                      .attr("x", 60)
                      .attr("y", -(margin.top/2))
                      .attr("width", 13)
                      .attr("height", 13)
                      .style("fill", "#0072BC")
              svg
                  .append("text")
                      .attr("class", "legend")
                      .attr("x", 80)
                      .attr("y", -(margin.top/2.5))
                  .text("Softly earmarked")
              svg
                  .append("rect")
                      .attr("x", 170)
                      .attr("y", -(margin.top/2))
                      .attr("width", 13)
                      .attr("height", 13)
                      .style("fill", "#8EBEFF")
              svg
                  .append("text")
                      .attr("class", "legend")
                      .attr("x", 190)
                      .attr("y", -(margin.top/2.5))
                  .text("Tightly earmarked")
              svg
                  .append("rect")
                      .attr("x", 290)
                      .attr("y", -(margin.top/2))
                      .attr("width", 13)
                      .attr("height", 13)
                      .style("fill", "#00B398")
              svg
                  .append("text")
                      .attr("class", "legend")
                      .attr("x", 310)
                      .attr("y", -(margin.top/2.5))
                  .text("Unearmarked")
              })
            
          

Streamgraph

A streamgraph is a variation of a stacked area chart. Instead of displaying values on top of a fixed, straight baseline at the bottom of the stack, the values of the streamgraph are displaced around a central baseline. This results in a flowing, organic-shaped “stream” displaying the change over time.

More about: Streamgraph - Other tutorials: R Matplotlib

              
                <!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="streamgraph_container"></div>
              
            
              
                               
              
            
              
                
                // set the dimensions and margins of the graph
                const margin = {top: 130, 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("#streamgraph_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/streamgraph_d3.csv", function(d) {
                    const parseTime = d3.timeParse("%Y")
                    return{
                        year: parseTime(d.year),
                        ["Refugees"]: +d.REF,
                        ["Asylum-seekers"]: +d.ASY,
                        ["IDPs"]: +d.IDPs,
                        ["Stateless persons"]: +d.STA,
                        ["Others of concern"]: +d.OOC,
                        ["Venezuelans displaced abroad"]: +d.VDA
                    }
                })
                .then(function(data){

                // list of value keys
                const typeKeys = ["Refugees", "Asylum-seekers", "IDPs", "Stateless persons", "Others of concern", "Venezuelans displaced abroad"]
       
                // stack the data
                const stack = d3.stack()
                   .keys(typeKeys)
                   .order(d3.stackOrderNone)
                   .offset(d3.stackOffsetSilhouette)
                const stackedData = stack(data)

                // 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))
                  .call(d => d.select(".domain").remove());
                
                // Y scale and Axis
                const formatter =  d3.format("~s")
                const yScale = d3.scaleLinear()
                    .domain([-60000000, 60000000])
                    .range([height, 0]);
                svg
                  .append('g')
                  .call(d3.axisLeft(yScale).ticks(9).ticks(7).tickSize(0).tickPadding(6).tickFormat(formatter))
                  .call(d => d.select(".domain").remove());


                // color palette
                const color = d3.scaleOrdinal()
                  .domain(typeKeys)
                  .range(["#0072BC", "#18375F", "#00B398", "#E1CC0D","#999999","#EF4A60"])
                
                // set vertical grid line
                const GridLine = function() { return d3.axisBottom().scale(xScale)};
                svg
                  .append("g")
                    .attr("class", "grid")
                  .call(GridLine()
                    .tickSize(height,0,0)
                    .tickFormat("")
                    .ticks(7)
                );  
                
                const tooltip = svg
                .append("text")
                .attr("x", 3)
                .attr("y", 10)
                .style("opacity", 0)
                .style("font-size", 11)
              
                const mouseover = function(event,d) {
                  tooltip.style("opacity", 1)
                  d3.selectAll(".stackedArea").style("opacity", .2)
                  d3.select(this)
                    .style("opacity", 1)
                }
                const mousemove = function(event,d,i) {
                  grp = d.key
                  tooltip.text(grp)
                }
                const mouseleave = function(event,d) {
                  tooltip.style("opacity", 0)
                  d3.selectAll(".stackedArea").style("opacity", 1).style("stroke", "none")
                 }
              
                // create the areas
                svg
                  .selectAll("alllayer")
                  .data(stackedData)
                  .join("path")
                    .attr("class", "stackedArea")
                    .style("fill", d => color(d.key))
                    .attr("d", d3.area()
                       .x(d => xScale(d.data.year))
                       .y0(d => yScale(d[0]))
                       .y1(d => yScale(d[1]))
                    )
                    .on("mouseover", mouseover)
                    .on("mousemove", mousemove)
                    .on("mouseleave", mouseleave);
                
                // set title
                svg
                  .append("text")
                    .attr("class", "chart-title")
                    .attr("x", -(margin.left)*0.65)
                    .attr("y", -(margin.top)/1.5)
                    .attr("text-anchor", "start")
                  .text("Evolution of people of concern to UNHCR | 1991-2020")

                // set Y axis label
                svg
                  .append("text")
                    .attr("class", "chart-label")
                    .attr("x", -(margin.left)*0.65)
                    .attr("y", -(margin.top/8))
                    .attr("text-anchor", "start")
                  .text("Number of people (millions)")
                
                // set source
                svg
                  .append("text")
                    .attr("class", "chart-source")
                    .attr("x", -(margin.left)*0.65)
                    .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.65)
                    .attr("y", height + margin.bottom*0.9)
                    .attr("text-anchor", "start")
                  .text("©UNHCR, The UN Refugee Agency")
                
                //set legend
                svg
                    .append("rect")
                        .attr("x", -(margin.left)*0.6)
                        .attr("y", -(margin.top/2))
                        .attr("width", 13)
                        .attr("height", 13)
                        .style("fill", "#0072BC")
                svg
                    .append("text")
                        .attr("class", "legend")
                        .attr("x", -(margin.left)*0.6+20)
                        .attr("y", -(margin.top/2.4))
                    .text("Refugees")
                svg
                    .append("rect")
                        .attr("x", 100)
                        .attr("y", -(margin.top/2))
                        .attr("width", 13)
                        .attr("height", 13)
                        .style("fill", "#18375F")
                svg
                    .append("text")
                        .attr("class", "legend")
                        .attr("x", 120)
                        .attr("y", -(margin.top/2.4))
                    .text("Asylum-seekers")
                svg
                    .append("rect")
                        .attr("x", 230)
                        .attr("y", -(margin.top/2))
                        .attr("width", 13)
                        .attr("height", 13)
                        .style("fill", "#00B398")
                svg
                    .append("text")
                        .attr("class", "legend")
                        .attr("x", 250)
                        .attr("y", -(margin.top/2.4))
                    .text("IDPs")
                svg
                    .append("rect")
                        .attr("x", 100)
                        .attr("y", -(margin.top/2.8))
                        .attr("width", 13)
                        .attr("height", 13)
                        .style("fill", "#999999")
                svg
                    .append("text")
                        .attr("class", "legend")
                        .attr("x", -(margin.left)*0.6+20)
                        .attr("y", -(margin.top/3.5))
                    .text("Stateless persons")
                svg
                    .append("rect")
                        .attr("x", -(margin.left)*0.6)
                        .attr("y", -(margin.top/2.8))
                        .attr("width", 13)
                        .attr("height", 13)
                        .style("fill", "#E1CC0D")
                svg
                    .append("text")
                        .attr("class", "legend")
                        .attr("x", 120)
                        .attr("y", -(margin.top/3.5))
                    .text("Others of concern")
                svg
                    .append("rect")
                        .attr("x", 230)
                        .attr("y", -(margin.top/2.8))
                        .attr("width", 13)
                        .attr("height", 13)
                        .style("fill", "#EF4A60")
                svg
                    .append("text")
                        .attr("class", "legend")
                        .attr("x", 250)
                        .attr("y", -(margin.top/3.5))
                    .text("Venezuelans displaced abroad")
                })
              
            
Contact us
  • Guidance
  • Chart types
  • Resources
  • Tutorials
  • Product gallery

© UNHCR