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
  • Bar chart
  • Column chart
  • Grouped bar chart
  • Grouped column chart
  • Stacked bar chart
  • Stacked column chart
  1. Home
  2. Tutorials
  3. D3
  4. Comparison

Bar chart

A bar chart is a chart in which each category is represented by a horizontal rectangle, with the length of the rectangle proportional to the values being plotted. The horizontal axis shows data value, and the vertical axis displays the categories being compared.

More about: Bar chart - Other tutorials: R Matplotlib Plotly Python

                  
                    <!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="bar_container"></div>
                  
                
                  
                                   
                  
                
                  

                    // set the dimensions and margins of the graph
                    const margin = {top: 50, right:20, bottom: 60, left: 120};
                    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("#bar_container")
                    .attr("width", "100%")
                        .append("svg")
                          .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/comparison/bar.csv")
                    .then(function(data) {
                    
                    // set X scale and axis
                    const formater =  d3.format("~s")
                    const xScale = d3.scaleLinear()
                        .domain([0, d3.max(data, d => +d.displaced_number)]).nice()
                        .range([0, width]);
                    svg
                        .append("g")
                            .attr("transform", `translate(0, ${height})`)
                        .call(d3.axisBottom(xScale).tickSize(0).tickPadding(6).tickFormat(formater).ticks(7))
                        .call( d => d.select(".domain").remove());
                    
                    // set Y scale and axis
                    const yScale = d3.scaleBand()
                        .domain(data.map( d => d.country_origin))
                        .range([0, height])
                        .padding(.25);
                    svg
                        .append("g")
                        .call(d3.axisLeft(yScale).tickSize(0).tickPadding(6));

                    // set vertical grid line
                    const GridLine = () => d3.axisBottom().scale(xScale);
                    svg
                      .append("g")
                        .attr("class", "grid")
                      .call(GridLine()
                        .tickSize(height,0,0)
                        .tickFormat("")
                        .ticks(7));  
                    
                    // 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", .9)
                        d3.select(this)
                          .style("opacity", .5)
                    };
                    const mousemove = function(event, d) {
                      const formater =  d3.format(",")
                      tooltip
                          .html(formater(d.displaced_number))
                          .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 group
                    const barGroup = svg.selectAll("rect")
                        .data(data)
                        .join("rect")
                          .attr("class", "bar")
                          .attr("fill", "#0072BC")
                          .attr("x", xScale(0))
                          .attr("y", d => yScale(d.country_origin))
                          .attr("width", d => xScale(d.displaced_number))
                          .attr("height", yScale.bandwidth())
                          .on("mouseover", mouseover)
                          .on("mousemove", mousemove)
                          .on("mouseleave", mouseleave);
                    
                    // set chart title
                    svg
                        .append("text")
                          .attr("class", "chart-title")
                          .attr("x", -(margin.left)*0.9)
                          .attr("y", -(margin.top/2))
                          .attr("text-anchor", "start")
                        .text("People displaced across borders by country of origin | 2020");

                    // set X axis label
                    svg
                      .append("text")
                        .attr("class", "chart-label")
                        .attr("x", width/2)
                        .attr("y", height+margin.bottom*0.5)
                        .attr("text-anchor", "middle")
                      .text("Displaced population (millions)");
                    
                    // set source
                    svg
                      .append("text")
                        .attr("class", "chart-source")
                        .attr("x", -(margin.left)*0.9)
                        .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.9)
                        .attr("y", height + margin.bottom*0.9)
                        .attr("text-anchor", "start")
                      .text("©UNHCR, The UN Refugee Agency")
                    })
                  
                

Column chart

In a column chart, each category is represented by a vertical rectangle, with the height of the rectangle being proportional to the values being plotted.

More about: Column chart - Other tutorials: R Matplotlib Plotly Python

            
              <!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="column_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("#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/comparison/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')
                .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.displaced_number)]).nice()
                  .range([height, 0]);
              svg
                .append('g')
                .call(d3.axisLeft(yScale).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("")
              );  
              
              // create a tooltip
              const tooltip = d3.select("body")
                .append("div")
                  .attr("id", "chart")
                  .attr("class", "tooltip");
              
              // tolltip 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_number))
                    .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)
              }
              
              // Bars
              const barGroup = svg.selectAll("rect")
                .data(data)
                .enter()
                .append("g")
              
              barGroup
                .append("rect")
                  .attr("class", "bar")
                  .attr("fill", "#0072BC")
                  .attr("x", d => xScale(d.year))
                  .attr("y", d => yScale(d.displaced_number))
                  .attr("width", xScale.bandwidth())
                  .attr("height", d => height - yScale(d.displaced_number))
                .on("mouseover", mouseover)
                .on("mousemove", mousemove)
                .on("mouseleave", mouseleave);

              // set title
              svg
                .append("text")
                  .attr("class", "chart-title")
                  .attr("x", -(margin.left)*0.9)
                  .attr("y", -(margin.top)/1.5)
                  .attr("text-anchor", "start")
                .text("Trend of global displaced number | 2011 - 2021")

              // set Y axis label
              svg
                .append("text")
                  .attr("class", "chart-label")
                  .attr("x", -(margin.left)*0.9)
                  .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.9)
                  .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.9)
                  .attr("y", height + margin.bottom*0.9)
                  .attr("text-anchor", "start")
                .text("©UNHCR, The UN Refugee Agency")
              })
            
          

Grouped bar chart

Grouped bar charts are a type of colour-coded bar chart that is used to represent and compare different categories of two or more groups.

More about: Grouped bar chart - Other tutorials: R Matplotlib Plotly Python

            
              <!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="bar_grouped_container"></div>
            
          
            
                             
            
          
            
              
              // set the dimensions and margins of the graph
              const margin = {top: 100, right: 20, bottom: 50, left: 190};
              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("#bar_grouped_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/comparison/bar_grouped.csv")
              .then(function(data){
     
              const sumbyRegionYear = d3.rollups(data, v => d3.sum(v, d => d.asylum_application), d => d.region, d => d.year)
            
              const regionKey = Array.from(sumbyRegionYear).map(d => d[0])
              const yearKeys = Array.from(Array.from(sumbyRegionYear)[0][1]).map(d=>d[0])
              const regionKeys = regionKey.sort(d3.ascending)

              // x scale and Axis
              const xScale = d3.scaleLinear()
                  .domain([0, d3.max(data.map(d => d.asylum_application))]).nice()
                  .range([0, width]);
              svg
                .append('g')
                .attr("transform", "translate(0, "+ height +")")
                .call(d3.axisBottom(xScale).tickSize(0).ticks(5).tickPadding(6).tickFormat(d3.format(".1s")))
                .call(d => d.select(".domain").remove());
            
              // y scale and Axis
              const yScale = d3.scaleBand()
                .domain(regionKeys) 
                .range([0, height])
                .padding(.2); 
              svg
                .append('g')
                .call(d3.axisLeft(yScale).tickSize(0).tickPadding(8));

              // set subgroup sacle
              const ySubgroups = d3.scaleBand()
                .domain(yearKeys)
                .range([0, yScale.bandwidth()])
                .padding([0.05])

              // color palette
              const color = d3.scaleOrdinal()
                .domain(yearKeys)
                .range(['#0072BC','#8EBEFF'])
              
              // set vertical grid line
              const GridLine = () => d3.axisBottom().scale(xScale);
              svg
                .append("g")
                  .attr("class", "grid")
                .call(GridLine()
                  .tickSize(height,0,0)
                  .tickFormat("")
                  .ticks(6)
              ); 

              // 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[1]))
                    .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 bars
              bars = svg.append("g")
                .selectAll("g")
                .data(sumbyRegionYear)
                .join("g")
                   .attr("transform", d => "translate(0, " + yScale(d[0]) +")")
                .selectAll("rect")
                .data(d => { return d[1] })
                .join("rect")
                   .attr("x", xScale(0))
                   .attr("y", d => ySubgroups(d[0]))
                   .attr("width", d => xScale(d[1]))
                   .attr("height", ySubgroups.bandwidth())
                   .attr("fill", d=>color(d[0]))
                .on("mouseover", mouseover)
                .on("mousemove", mousemove)
                .on("mouseleave", mouseleave);

              // 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("Individual asylum applications registred by region | 2019-2020")

              // set Y axis label
              svg
                .append("text")
                  .attr("class", "chart-label")
                  .attr("x", width/2)
                  .attr("y", height+margin.bottom/2)
                  .attr("text-anchor", "middle")
                .text("Displaced population")
              
              // 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
              svg
              .append("rect")
                  .attr("x", -(margin.left)*0.7)
                  .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.7+20)
                      .attr("y", -(margin.top/2.5))
                  .text("2019")
              svg
                  .append("rect")
                      .attr("x", -(margin.left)*0.7+60)
                      .attr("y", -(margin.top/2))
                      .attr("width", 13)
                      .attr("height", 13)
                      .style("fill", "#8EBEFF")
              svg
                  .append("text")
                      .attr("class", "legend")
                      .attr("x", -(margin.left)*0.7+80)
                      .attr("y", -(margin.top/2.5))
                  .text("2020")
              })
            
          

Grouped column chart

Grouped column charts are a type of colour-coded column chart used to represent and compare different categories of two or more groups.

More about: Grouped column chart - Other tutorials: R Matplotlib Plotly Python

            
              <!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="column_grouped_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("#column_grouped_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/comparison/column_grouped.csv").then(function(data){
              
              // data wrangling
              const sumbyYearOffice = d3.rollups(data, v => d3.sum(v, d => +d.refugee_number), d => d.year, d => d.main_office)
              const yearKeys = Array.from(sumbyYearOffice).map(d => d[0])
              const officeKey = Array.from(Array.from(sumbyYearOffice)[0][1]).map(d=>d[0])
              const officeKey_sorted = officeKey.sort(d3.ascending)
            
              // X scale and Axis
              const xScale = d3.scaleBand()
                .domain(yearKeys) 
                .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 formater =  d3.format(".1s")
              const yScale = d3.scaleLinear()
                  .domain([0, d3.max(data.map(d => +d.refugee_number))])
                  .range([height, 0]);
              svg
                .append('g')
                .call(d3.axisLeft(yScale).ticks(5).tickSize(0).tickPadding(6).tickFormat(formater))
                .call(d => d.select(".domain").remove());

              // set subgroup sacle
              const xSubgroups = d3.scaleBand()
                .domain(officeKey_sorted)
                .range([0, xScale.bandwidth()])
                .padding([0.05])

              // color palette
              const color = d3.scaleOrdinal()
                .domain(officeKey_sorted)
                .range(['#18375F','#0072BC','#8EBEFF'])
              
              // 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 mousemove = function(event, d) {
                const formater =  d3.format(",")
                  tooltip
                    .html(formater(d[1]))
                    .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 bars
              bars = svg.append("g")
                .selectAll("g")
                .data(sumbyYearOffice)
                .join("g")
                   .attr("transform", d => "translate(" + xScale(d[0]) +", 0)")
                .selectAll("rect")
                .data(d => { return d[1] })
                .join("rect")
                   .attr("x", d => xSubgroups(d[0]))
                   .attr("y", d => yScale(d[1]))
                   .attr("width", xSubgroups.bandwidth())
                   .attr("height", d => height - yScale(d[1]))
                   .attr("fill", d=>color(d[0]))
                .on("mouseover", mouseover)
                .on("mousemove", mousemove)
                .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("Refugees in Africa region | 2018-2021")

              // set Y axis label
              svg
                .append("text")
                  .attr("class", "chart-label")
                  .attr("x", -(margin.left)*0.6)
                  .attr("y", -(margin.top/15))
                  .attr("text-anchor", "start")
                .text("Displaced population (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("East and Horn of Africa and Great Lakes")
              svg
                  .append("rect")
                      .attr("x", 180)
                      .attr("y", -(margin.top/2))
                      .attr("width", 13)
                      .attr("height", 13)
                      .style("fill", "#0072BC")
              svg
                  .append("text")
                      .attr("class", "legend")
                      .attr("x", 200)
                      .attr("y", -(margin.top/2.5))
                  .text("Southern Africa")
              svg
                  .append("rect")
                      .attr("x", 280)
                      .attr("y", -(margin.top/2))
                      .attr("width", 13)
                      .attr("height", 13)
                      .style("fill", "#8EBEFF")
              svg
                  .append("text")
                      .attr("class", "legend")
                      .attr("x", 300)
                      .attr("y", -(margin.top/2.5))
                  .text("West and Central Africa")
              })
            
          

Stacked bar chart

Stacked bar charts stack horizontal bars that represent different groups one after another. The length of the stacked bar shows the combined value of the groups. They show the cumulative values of data items and compare parts to the whole.

More about: Stacked bar chart - Other tutorials: R Matplotlib Plotly Python

            
              <!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_bar_container"></div>
            
          
            
                             
            
          
            
              
              // set the dimensions and margins of the graph
              const margin = {top: 80, right: 20, bottom: 50, left: 120};
              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_bar_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/comparison/bar_stacked_d3.csv", function(d, i, columns) {
                  for (i = 1, t = 0; i < columns.length; ++i) t += d[columns[i]] = +d[columns[i]];
                  d.total = t;
                  return d;
                  country_origin: d.country_origin;
                  ASY: +d.ASY;
                  REF: +d.REF;
                  VDA: +d.VDA
              }).then(function(data){

              // list of value keys
              const typeKeys = data.columns.slice(1);

              // sort data in descending order by total value
              data.sort((a, b) => b.total - a.total);
     
              // stack the data
              const stack = d3.stack()
                 .keys(typeKeys)
                 .order(d3.stackOrderNone)
                 .offset(d3.stackOffsetNone)
              const stackedData =stack(data)

              // X scale and Axis
              const formater =  d3.format(".1s")
              const xScale = d3.scaleLinear()
                  .domain([0, 7000000])
                  .range([0, width])
              svg
                .append('g')
                .attr("transform", `translate(0, ${height})`)
                .call(d3.axisBottom(xScale).ticks(7).tickSize(0).tickPadding(6).tickFormat(formater))
                .call(d => d.select(".domain").remove());

              // Y scale and Axis
              const yScale = d3.scaleBand()
                .domain(data.map(d => d.country_origin)) 
                .range([0, height])
                .padding(.2); 
              svg
                .append('g')
                .call(d3.axisLeft(yScale).tickSize(0).tickPadding(8));

              // color palette
              const color = d3.scaleOrdinal()
                .domain(typeKeys)
                .range(['#0072BC','#18375F','#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(8)
              ); 

              // 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[1]))
                    .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 bars
              svg.append("g")
                .selectAll("g")
                .data(stackedData)
                .join("g")
                    .attr("fill", d => color(d.key))
                  .selectAll("rect")
                  .data(d => d)
                  .join("rect")
                    .attr("x", d => xScale(d[0]))
                    .attr("y", d => yScale(d.data.country_origin))
                    .attr("width",  d => xScale(d[1])-xScale(d[0]))
                    .attr("height", yScale.bandwidth())
                    .on("mouseover", mouseover)
                    .on("mousemove", mousemove)
                    .on("mouseleave", mouseleave)
              
              // set title
              svg
                .append("text")
                  .attr("class", "chart-title")
                  .attr("x", -(margin.left)*0.8)
                  .attr("y", -(margin.top)/1.5)
                  .attr("text-anchor", "start")
                .text("Resettlement by UNHCR and others | 2010-2020")

              // set Y axis label
              svg
                .append("text")
                  .attr("class", "chart-label")
                  .attr("x", width/2)
                  .attr("y", height+margin.bottom/2)
                  .attr("text-anchor", "middle")
                .text("Number of people (millions)")
              
              // set source
              svg
                .append("text")
                  .attr("class", "chart-source")
                  .attr("x", -(margin.left)*0.8)
                  .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.8)
                  .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.8)
                      .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.8+20)
                      .attr("y", -(margin.top/2.7))
                  .text("Refugees")
              svg
                  .append("rect")
                      .attr("x", 0)
                      .attr("y", -(margin.top/2))
                      .attr("width", 13)
                      .attr("height", 13)
                      .style("fill", "#18375F")
              svg
                  .append("text")
                      .attr("class", "legend")
                      .attr("x", 20)
                      .attr("y", -(margin.top/2.7))
                  .text("Asylum-seekers")
              svg
                  .append("rect")
                      .attr("x", 120)
                      .attr("y", -(margin.top/2))
                      .attr("width", 13)
                      .attr("height", 13)
                      .style("fill", "#EF4A60")
              svg
                  .append("text")
                      .attr("class", "legend")
                      .attr("x", 140)
                      .attr("y", -(margin.top/2.7))
                  .text("Venezuelans displaced abroad")
              })
            
          

Stacked column chart

The stacked column chart stacks vertical bars that represent different groups on top of each other. The height of the stacked bar shows the combined value of the groups. They show the cumulative values of a data item and compare parts to the whole.

More about: Stacked column chart - Other tutorials: R Matplotlib Plotly Python

            
              <!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_column_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_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/comparison/column_stacked_d3.csv")
              .then(function(data){

              // list of value keys
              const typeKeys = data.columns.slice(1);
     
              // 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.scaleBand()
                .domain(data.map(d => d.year)) 
                .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, 180])
                  .range([height, 0]);
              svg
                .append('g')
                .call(d3.axisLeft(yScale).ticks(9).tickSize(0).tickPadding(6))
                .call(function(d) { return d.select(".domain").remove()});

              // color palette
              const color = d3.scaleOrdinal()
                .domain(typeKeys)
                .range(['#0072BC','#8EBEFF'])
              
              // set horizontal grid line
              const GridLine = function() {return 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");

              // Three function that change the tooltip when user hover / move / leave a cell
              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[1]))
                    .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 bars
              svg.append("g")
                .selectAll("g")
                .data(stackedData)
                .enter()
                .append("g")
                    .attr("fill", d => color(d.key) )
                  .selectAll("rect")
                  .data(d => d)
                  .join("rect")
                    .attr("x",d => xScale(d.data.year))
                    .attr("y",d => yScale(d[1]))
                    .attr("width", xScale.bandwidth())
                    .attr("height", d => yScale(d[0]) - 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.6)
                  .attr("y", -(margin.top)/1.5)
                  .attr("text-anchor", "start")
                .text("Resettlement by UNHCR and others | 2010-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("Number of people (thousands)")
              
              // 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", 15)
                      .attr("height", 15)
                      .style("fill", "#0072BC")
              svg
                  .append("text")
                      .attr("class", "legend")
                      .attr("x", -(margin.left)*0.6+20)
                      .attr("y", -(margin.top/2.5))
                  .text("UNHCR resettlement")
              svg
                  .append("rect")
                      .attr("x", 130)
                      .attr("y", -(margin.top/2))
                      .attr("width", 15)
                      .attr("height", 15)
                      .style("fill", "#8EBEFF")
              svg
                  .append("text")
                      .attr("class", "legend")
                      .attr("x", 150)
                      .attr("y", -(margin.top/2.5))
                  .text("Other resettlement")
              })
            
          
Contact us
  • Guidance
  • Chart types
  • Resources
  • Tutorials
  • Product gallery

© UNHCR