Sélection de la langue

Manuel de conception de l'Infobase Santé

  Table des matières


Diagramme à barres

Un diagramme à barres est une représentation visuelle des données qui utilise des barres pour montrer les valeurs relatives de différents points de données.

Les diagrammes à barres peuvent être orientés horizontalement ou verticalement.

Quand utiliser cette composante

  • Pour montrer la taille ou la valeur relative de différents points de données.
  • Pour comparer les valeurs de différents points de données.
  • Pour montrer la distribution des données sur une plage de valeurs.

Exemples

  • Un diagramme à barres comparant les taux de vaccination de différents groupes d'âge dans une population.
  • Un diagramme à barres montrant le nombre de personnes ayant été évaluées pour une condition de santé spécifique, en fonction du sexe.

Quand utiliser un diagramme à barres verticales

  • Vous avez un grand nombre de points de données ou de catégories.
  • Vous voulez mettre en évidence les valeurs de l'axe Y.
  • Vous voulez montrer les données de manière compacte et économique en termes d'espace.

Quand utiliser un diagramme à barres horizontales

  • Vous avez de longues étiquettes de catégories.
  • Vous voulez mettre en évidence les valeurs de l'axe X.
  • Vous voulez montrer les données d'une manière qui est facile à lire et comparable.

Quand utiliser un diagramme à barres superposées

  • La somme des valeurs des différentes catégories est importante.
  • Pour montrer à la fois la valeur totale et la distribution des catégories qui composent cette valeur.

Quand utiliser un diagramme à barres groupées

  • Pour montrer la taille relative de différentes catégories sur le même axe X.
  • Lorsque la somme des valeurs n'est pas au centre de l'attention.

Quoi éviter

  • N'utilisez pas de graphiques à barres pour montrer des données sans valeur numérique claire.
  • N'utilisez pas de graphiques à barres pour montrer des données ayant des unités ou des échelles différentes.

Design et code

Choisissez un type:

Quantité de fruits

HTML
<!-- Ajouter la bibliothèque D3 dans la section head -->
<script src="https://d3js.org/d3.v7.min.js"></script>
   
<!-- Ajouter ce div dans la section où vous voulez ajouter le graphique -->

<div id="vertical"></div>
JS
<script>
    var language = document.documentElement.lang;
    //1. load data
    var csvfiles = ['/src/design-manual/data/fr/bar-graphs/vertical_data.csv', // 0
    ]
    var promises = [];
    csvfiles.forEach(function(url) {
      promises.push(d3.csv(url))
    });
    //Request + response + and then...
    Promise.all(promises).then(function(datasets) {
      processData(datasets[0]);
    })
    const createGraph = (graphID, svgID, width, height) => conditionalAppend(d3.select(svgID), "svg", `#svg-${graphID}`).attr("preserveAspectRatio", "xMinYMin meet").attr("viewBox", "0 0 " + (width) + " " + (height)).attr("id", `svg-${graphID}`)
    // Append an element if no match is found, otherwise select the existing one
    function conditionalAppend(parent, type, additionalSelector = "") {
      const existing = parent.select(`${type}${additionalSelector}`)
      return !existing.empty() ? existing : parent.append(type);
    }
    // Insert an element if no match is found, otherwise select the existing one
    function conditionalInsert(parent, type, before, additionalSelector = "") {
      const existing = parent.select(`${type}${additionalSelector}`)
      return !existing.empty() ? existing : parent.insert(type, before);
    }
    class Visual {
      constructor(draw) {
        this._draw = draw
      }
      draw(data, ...args) {
        this._draw(data, ...args)
      }
    }
    const palette = {
      Yellow: "#FBDD69",
      Orange: "#FF9258",
      LightBlue: "#93D9FF",
      Teal: "#2C93B4",
      Green: "#00727D"
    }
    //2.
    function processData(data) {
      verticalGraph.draw(data, `#vertical`, 330, 250);
    }
    //4.2
    let verticalGraph = new Visual(function(data, svgID, svgWidth, svgHeight) {
      // 		const formatValueWithUnit = (d) => data[d]
      const dataGrouped = d3.group(data, d => d.fruit);
      const svg = createGraph("vertical", svgID, svgWidth, svgHeight)
      const margin = {
          top: 20,
          right: 20,
          bottom: 90,
          left: 30
        },
        width = svgWidth - (margin.left + margin.right),
        height = svgHeight - (margin.top + margin.bottom),
        g = conditionalAppend(svg, "g").attr("transform", `translate(${margin.left}, ${margin.top})`)
      let domainArr = d3.map(data, d => d.fruit);
      const colour = d3.scaleOrdinal().domain(domainArr).range([palette.Orange, palette.Teal, palette.Yellow, palette.Orange, palette.Teal, palette.Yellow, palette.Orange, palette.Yellow])
      /* SEX GRAPH */
      // axis
      let xArray = {
        "en": ["Apples", "Oranges", "Pears", "Bananas"],
        "fr": ["Pommes", "Oranges", "Poires", "Bananes"]
      };
      let x = d3.scaleBand().domain(domainArr).range([0, width]).padding(0.4);
      const maxY = d3.max(data, function(d) {
        console.log(+d.quantity);
        return +d.quantity;
      });
      let y = d3.scaleLinear().domain([0, maxY + 1]).range([height, 0]);
      let axis = conditionalAppend(g, "g", ".axis").classed("axis", true)
      let x_axis = conditionalAppend(axis, "g", ".x_axis").classed("x_axis", true)
      x_axis.attr("transform", "translate(0," + (height) + ")").call(d3.axisBottom(x)).selectAll("text")
        // .attr("transform", "rotate(-35)")
        .classed("x_axisText", true).attr("font-size", "0.9rem")
        // .style("text-anchor", "end")
        .text(function(d, i) {
          return xArray[language][i];
        })
      // 			.call(wrapHori,75);
      let y_axis = conditionalAppend(axis, "g", ".y_axis").classed("y_axis", true)
      y_axis.attr("id", "y_axis").attr("transform", "translate(0,0)").call(d3.axisLeft(y).ticks(5).tickFormat(function(d) {
        return d;
      })).selectAll("text").attr("class", "axisText").attr("font-size", "0.9rem")
      svg.append("text").attr("class", "x-axis-text").text(function(d, i) {
        if (language == "en") {
          return 'Fruits';
        } else {
          return 'Fruits';
        }
      }).attr("x", width / 1.6).attr("y", height + 65).attr("font-size", "1.2rem")
      // 			.call(wrap, 350)
      // bars
      let rectGroup = conditionalAppend(g, "g", "#mainChartAreaGender").attr("id", "mainChartAreaGender").selectAll("g").data(domainArr).join("g").attr("id", d => d.replace(/\s/g, ''))
      const rects = rectGroup.selectAll("rect").data(d => [d]).join("rect").attr("fill", "#008080") //d => colour(d))
        .attr("x", d => x(d)).attr("width", x.bandwidth()).each(function(d) {
          conditionalAppend(d3.select(this), "title").text(d)
        }).transition().duration(1000).attr("height", d => y(0) - y(dataGrouped.get(d)[0].quantity)).attr("y", d => y(dataGrouped.get(d)[0].quantity))
      rectGroup.selectAll("text").data(d => [d]).join("text").style("text-anchor", "middle").classed("rectText", true).attr("font-size", "1rem").attr("font-weight", "bold").attr("x", d => x(d) + x.bandwidth() / 2).transition().duration(1000).attr("y", d => y(dataGrouped.get(d)[0].quantity) - 5).tween("text", function(d) {
        let item = d3.select(this);
        if (item.property("previousValue") === undefined) item.property("previousValue", dataGrouped.get(d)[0].quantity);
        let i = d3.interpolateNumber(item.property("previousValue"), dataGrouped.get(d)[0].quantity);
        if (dataGrouped.get(d)[0].quantity === "" || dataGrouped.get(d)[0].quantity === 0) {
          item.text("N/A");
          item.property("previousValue", 0);
        } else {
          item.property("previousValue", dataGrouped.get(d)[0].quantity);
          return function(t) {
            return item.text(d3.format(".0f")(i(t)));
          };
        }
      }).on("end", () => {
        // d3.selectAll(".rectText").call(wrap,100);
      })
    })
</script>

Quantité de fruits

HTML
<!-- Ajouter la bibliothèque D3 dans la section head -->
<script src="https://d3js.org/d3.v7.min.js"></script>
   
<!-- Ajouter ce div dans la section où vous voulez ajouter le graphique -->

<div id="horizontal"></div>
JS
<script>
    var languageHori = document.documentElement.lang;
  
  //1. load data
  var csvfilesHori = [
    '/src/design-manual/data/fr/bar-graphs/vertical_data.csv', // 0
  ]
  var promisesHori = [];
  csvfilesHori.forEach(function(url) {
    promisesHori.push(d3.csv(url))
  });
  
  //Request + response + and then...
  Promise.all(promisesHori)
  .then(function(datasets) {
    processDataHori(datasets[0]);
  })

  const createGraphHori = (graphID, svgID, width, height) => conditionalAppendHori(d3.select(svgID), "svg", `#svg-${graphID}`)
    .attr("preserveAspectRatio", "xMinYMin meet")
    .attr("viewBox", "0 0 " + (width) + " " + (height))
    .attr("id", `svg-${graphID}`)
  
  // Append an element if no match is found, otherwise select the existing one
  function conditionalAppendHori(parent, type, additionalSelector = "") {
    const existing = parent.select(`${type}${additionalSelector}`)
  
    return !existing.empty() ? existing : parent.append(type);
  }
  // Insert an element if no match is found, otherwise select the existing one
  function conditionalInsertHori(parent, type, before, additionalSelector = "") {
    const existing = parent.select(`${type}${additionalSelector}`)
    return !existing.empty() ? existing : parent.insert(type, before);
  }
  
  class VisualHori {
    constructor(draw) {
      this._draw = draw
    }
  
    draw(data, ...args) {
      this._draw(data, ...args)
    }
  }
  
  const paletteHori = {
    Yellow: "#FBDD69",
    Orange: "#FF9258",
    LightBlue: "#93D9FF",
    Teal: "#2C93B4",
    Green: "#00727D"
  }
  
  //2.
  function processDataHori(data){
      horizontalGraph.draw(data, `#horizontal`, 430, 250);
  }


  //4.2
  let horizontalGraph = new VisualHori(
    function(data, svgID, svgWidth, svgHeight) {
      
  // 		const formatValueWithUnit = (d) => data[d]
          const dataGrouped = d3.group(data, d => d.fruit);
  
      const svg = createGraphHori("horiical", svgID, svgWidth, svgHeight)
  
      const margin = { top: 20, right: 20, bottom: 70, left: 110 },
        width = svgWidth - (margin.left + margin.right),
        height = svgHeight - (margin.top + margin.bottom),
        gHori = conditionalAppendHori(svg, "g").attr("transform", `translate(${margin.left}, ${margin.top})`)
      
      let domainArr = d3.map(data, d => d.fruit);
      const colour = d3.scaleOrdinal().domain(domainArr).range([palette.Orange, palette.Teal, palette.Yellow, palette.Orange, palette.Teal, palette.Yellow, palette.Orange, palette.Yellow])
  
      /* SEX GRAPH */
      let xArray = {"en":	["Apples", "Oranges", "Pears", "Bananas"], "fr": ["Pommes", "Oranges", "Poires", "Bananes"]};
      let x = d3.scaleBand().domain(domainArr).range([0, height]).padding(0.4);
      
      const maxY = d3.max(data, function(d) { console.log(+d.quantity); return +d.quantity;} );
      let y = d3.scaleLinear().domain([0, maxY + 1]).range([0,height]);
  
      let axisHori = conditionalAppendHori(gHori, "g", ".axisHori")
        .classed("axisHori", true)
  
      let x_axisHori = conditionalAppendHori(axisHori, "g", ".x_axisHori")
        .classed("x_axisHori", true)
  
      x_axisHori
        .attr("transform", "translate(0,0)")
        .call(d3.axisLeft(x))
        .selectAll("text")
        // .attr("transform", "rotate(-35)")
        .classed("x_axisText", true)
        .attr("font-size", "0.9rem")
        // .style("text-anchor", "end")
        .text(function(d,i){
          return xArray[language][i];
        })
  // 			.call(wrapHori,75);
        
      let y_axisHori = conditionalAppendHori(axisHori, "g", ".y_axisHori")
        .classed("y_axisHori", true)	
        
      y_axisHori
        .attr("id", "y_axisHori")
        .attr("transform", "translate(0," + (height) + ")")
        .call(d3.axisBottom(y).ticks(5).tickFormat(function(d) {
          return d;
        }))
        .selectAll("text")
        .attr("class", "axisTextHori")
        .attr("font-size", "0.9rem")
  
      svg.append("text")
        .attr("class", "y-axis-text-hori")
        .text(function(d,i){
            if(language == "en"){
                return 'Quantity';
            }else{
                return 'Quantité';
            }
        })
        .attr("x", 10)
  // 			.attr("y", height/3)
        .attr("font-size", "1.2rem")
        .attr("transform", "translate(" + (width / 2) + "," + ((height + margin.top ) + (margin.bottom / 1.5)) +")")
  // 			.call(wrap, 350)	
  
      svg.append("text")
        .attr("class", "x-axis-text-hori")
        .text(function(d,i){
            if(language == "en"){
                return 'Fruits';
            }else{
                return 'Fruits';
            }
        })
        .attr("transform", "translate(20,"+(height/1.1)+")rotate(-90)")
        .attr("x", 10)
        .attr("y", 10)
        .attr("font-size", "1.2rem")
  // 			.call(wrap, 350)
  
      // bars
      let rectGroup = conditionalAppendHori(gHori, "g", "#mainChartAreaHori")
        .attr("id", "mainChartAreaHori")
        .selectAll("g")
        .data(domainArr)
        .join("g")
        .attr("id", d => d.replace(/\s/g, ''))
  
      const rects = rectGroup.selectAll("rect")
        .data(d => [d])
        .join("rect")
        .attr("fill", "#008080") //d => colour(d))
        .attr("y", d => x(d))
        .attr("height", x.bandwidth())
        .each(function(d) {
          conditionalAppendHori(d3.select(this), "title")
            .text(d)
        })
        .transition().duration(1000)
        .attr("x", d => y(0.05))
        .attr("width", d => y(dataGrouped.get(d)[0].quantity))
  
      rectGroup.selectAll("text")
        .data(d => [d])
        .join("text")
        .style("text-anchor", "middle")
        .classed("rectTextHori", true)
        .attr("font-size", "1rem")
        .attr("font-weight", "bold")
        .attr("y", d => x(d) + x.bandwidth() / 1.5)
        .transition().duration(1000)
        .attr("x", d => y(dataGrouped.get(d)[0].quantity) + 15)
        .tween("text", function(d) {
          let item = d3.select(this);
          if (item.property("previousValue") === undefined)
            item.property("previousValue", dataGrouped.get(d)[0].quantity);
          let i = d3.interpolateNumber(item.property("previousValue"), dataGrouped.get(d)[0].quantity);
          if (dataGrouped.get(d)[0].quantity === "" || dataGrouped.get(d)[0].quantity === 0) {
            item.text("N/A");
            item.property("previousValue", 0);
          }
          else {
            item.property("previousValue", dataGrouped.get(d)[0].quantity);
            return function(t) { return item.text(d3.format(".1f")(i(t))); };
          }
        })
        .on("end",()=>{
          // d3.selectAll(".rectText").call(wrap,100);
        })
    }
  )
</script>
HTML
<!-- Ajouter la bibliothèque D3 dans la section head -->
<script src="https://d3js.org/d3.v7.min.js"></script>
    
<!-- Ajouter ce div dans la section où vous voulez ajouter le graphique -->

<div id="grouped"></div>
JS
<script>
      // set the dimensions and margins of the graph
var margin = {top: 10, right: 30, bottom: 20, left: 50},
  width = 460 - margin.left - margin.right,
  height = 400 - margin.top - margin.bottom;

// append the svg object to the body of the page
var svg = d3.select("#grouped")
.append("svg")
  .attr("width", width + margin.left + margin.right)
  .attr("height", height + margin.top + margin.bottom)
.append("g")
  .attr("transform",
        "translate(" + margin.left + "," + margin.top + ")");

var csvfilesGrouped = [
    '/src/design-manual/data/fr/bar-graphs/grouped-data.csv', // 0
  ]
  var promisesGrouped = [];
  csvfilesGrouped.forEach(function(url) {
    promisesGrouped.push(d3.csv(url))
  });
  
  //Request + response + and then...
  Promise.all(promisesGrouped)
  .then(function(datasets) {
    drawGraph(datasets[0]);
  })

// Parse the Data
function drawGraph(data) {

// List of subgroups = header of the csv files = soil condition here
var subgroups = data.columns.slice(1)

// List of groups = species here = value of the first column called group -> I show them on the X axis
var groups = d3.map(data, function(d){return(d.group)})

console.log(d3.map(data, function(d){return(d.group)}))
// Add X axis
var x = d3.scaleBand()
    .domain(groups)
    .range([0, width])
    .padding([0.2])
svg.append("g")
  .attr("transform", "translate(0," + height + ")")
  .call(d3.axisBottom(x).tickSize(0));

// Add Y axis
var y = d3.scaleLinear()
  .domain([0, 40])
  .range([ height, 0 ]);
svg.append("g")
  .call(d3.axisLeft(y));

// Another scale for subgroup position?
var xSubgroup = d3.scaleBand()
  .domain(subgroups)
  .range([0, x.bandwidth()])
  .padding([0.05])

// color palette = one color per subgroup
var color = d3.scaleOrdinal()
  .domain(subgroups)
  .range(['#e41a1c','#377eb8','#4daf4a'])

// Show the bars
svg.append("g")
  .selectAll("g")
  // Enter in data = loop group per group
  .data(data)
  .enter()
  .append("g")
    .attr("transform", function(d) { return "translate(" + x(d.group) + ",0)"; })
  .selectAll("rect")
  .data(function(d) { return subgroups.map(function(key) { return {key: key, value: d[key]}; }); })
  .enter().append("rect")
    .attr("x", function(d) { return xSubgroup(d.key); })
    .attr("y", function(d) { return y(d.value); })
    .attr("width", xSubgroup.bandwidth())
    .attr("height", function(d) { return height - y(d.value); })
    .attr("fill", function(d) { return color(d.key); });

}
      </script>
HTML
<!-- Ajouter la bibliothèque D3 dans la section head -->
    <script src="https://d3js.org/d3.v7.min.js"></script>
         
    <!-- Ajouter ce div dans la section où vous voulez ajouter le graphique -->
    <div id="stackedBars"></div>
JS
<script>
// dimensions and margins
const marginstacked = {top: 10, right: 30, bottom: 50, left: 100},
    widthstacked = 640 - marginstacked.left - marginstacked.right,
    heightstacked = 550 - marginstacked.top - marginstacked.bottom;

// append svg
const svgstacked = d3.select("#stackedBars")
  .append("svg")
    .attr("width", widthstacked + marginstacked.left + marginstacked.right)
    .attr("height", heightstacked + marginstacked.top + marginstacked.bottom)
    .append("g")
        .attr("transform", `translate(${marginstacked.left},${marginstacked.top})`);

d3.csv("/src/design-manual/data/fr/bar-graphs/stacked-data-fr-utf9.csv").then( function(data) {
    // subgroups
  const subgroups = data.columns.slice(1);

  // main groups
  const groups = data.map(d => (d.month));
  
  // Add X axis
  const x = d3.scaleBand()
      .domain(groups)
      .range([0, width])
      .padding([0.2]);
      
  svgstacked.append("g")
    .attr("transform", `translate(0, ${height})`)
    .call(d3.axisBottom(x).tickSizeOuter(0))
    .style("font-size","16px");

  // Add Y axis
  const y = d3.scaleLinear()
    .domain([0, 800])
    .range([ height, 0]);
    
  svgstacked.append("g")
    .call(d3.axisLeft(y).tickFormat((d)=> "$"+d))
    .style("font-size","16px");
    
    // xAxis label 
  svgstacked.append("text")
      .attr("text-anchor", "end")
      .attr("x", width/2 + margin.left - 40)
      .attr("y", height + margin.top + 35)
      .style("font-weight","bold")
      .style("font-size", "23px")
      .text("Mois");

  // yAxis label
  svgstacked.append("text")
      .attr("text-anchor", "end")
      .attr("transform", "rotate(-90)")
      .attr("y", -margin.left - 10)
      .attr("x", -margin.top - height/2 + 60)
      .style("font-weight","bold")
      .style("font-size", "23px")
      .text("Prix");
    
  // palette
  const color = d3.scaleOrdinal()
    .domain(subgroups)
    .range(['#e41a1c','#377eb8','#4daf4a'])

  //stacked data
  const stackedData = d3.stack()
    .keys(subgroups)(data);

  svgstacked.append("g")
    .selectAll("g")
    .data(stackedData)
    .join("g")
      .attr("fill", d => color(d.key))
      .selectAll("rect")
      .data(d => d)
      .join("rect")
        .attr("height", d => y(d[0]) - y(d[1]))
        .attr("width",x.bandwidth())
          .attr("x", d => x(d.data.month))
        .attr("y", d => y(d[1]));
    
    //append legend
    let legend = svgstacked.append("g")
        .attr("class", "legendG")
        .attr("font-family", "sans-serif")
        .style("font-size", "19px")
        .attr("text-anchor", "start")
        .attr("transform", "translate(-465,0)")
        .selectAll("g")
        .data(stackedData.slice())
        .enter()
        .append("g")
        .attr("transform", function(d, i) { return "translate(" + 450 + "," + -(325 + (30* i)) + ")"; });

    legend.append("rect")
        .attr("x", 430)
        .attr("y", 400)
        .attr("width", 19)
        .attr("height", 19)
        .attr("fill", function(d) { return color(d); })
        .style("stroke-width", "0.5px")
        .style("stroke", "black");
        
    legend.append("text")
        .attr("x", 455)
        .attr("y", 410)
        .attr("dy", "0.4em")
        .attr("class","legendText")
        .text(function(d) { return d.key; });
})  
      </script>

Documentation D3.js complète pour les diagrammes à barres

Lignes directrices sur le contenu et le design

  • Commencez toujours l'axe Y à 0.
  • Considérez la possibilité d'ordonner les barres en fonction de la valeur.
  • Utilisez la couleur judicieusement – en général, utilisez la même couleur pour toutes les barres et utilisez une autre couleur pour mettre en évidence une barre spécifique.
  • Considérez la possibilité d'inscrire la valeur directement à l'intérieur des barres.
  • Concevez les barres de manière à ce qu'elles soient plus larges que l'espace entre les barres.
  • Suivez les lignes directrices générales sur le design.

Lignes directrices sur l'accessibilité

  • Fournissez un tableau de données avec le graphique.
  • Si le graphique à barres raconte une histoire claire, incluez cette histoire dans le texte alternatif. Par exemple, si le graphique montre qu'une catégorie a une valeur beaucoup plus élevée que les autres, préciser cela dans le texte alternatif.
  • Suivez les lignes directrices générales sur l'accessibilité.
Date de modification :