next.jschartschart.jsbar-chartreact-chartjs

ChartJS / react-chartjs-2 divide bar in to two data points


I am creating a barchart with ChartJS / react-chartjs-2. The barchart is displaying allright so far, nothing special:

just a normal barchart

My data looks like this:

    {
      Name: "De Regenboog",
      Patients: "7546",
      Year1Total: "34",
      Year1Pos: "4",
      Year2Total: "51",
      Year2Pos: "1",
      Year3Total: "43",
      Year3Pos: "0",
    },
    {
      Name: "George Michael",
      Patients: "2644",
      Year1Total: "20",
      Year1Pos: "0",
      Year2Total: "18",
      Year2Pos: "0",
      Year3Total: "64",
      Year3Pos: "0",
    },
   etc
  ]

I want the positives to display as a part of the total bar of that year for that Name. So for 'De Regenboog' in the year 2021 it would show the total bar to be 34 and 4 would be coloured in differently to be the positive tests that year. I am not sure what to search for or how to approach this. Would it be possible at all ? Maybe anyone has an idea?

Update for clarity, this is how I want the data for 1 practice for 1 year to stack. But I want to have three years per practice displayed. I also cant get it to work in Google Sheets so im uncertain if it is possible:

example with one year of data and 6 practices


Solution

  • You can set a backgroundColor for each dataset entry to create a visual distinction between the positive cases and the rest of the totals within the same bar, so if your data looks like this:

    const dataSet = [
        {
          Name: "De Regenboog",
          Patients: "7546",
          Year1Total: "34",
          Year1Pos: "4",
          Year2Total: "51",
          Year2Pos: "1",
          Year3Total: "43",
          Year3Pos: "0",
        },
        {
          Name: "George Michael",
          Patients: "2644",
          Year1Total: "20",
          Year1Pos: "0",
          Year2Total: "18",
          Year2Pos: "0",
          Year3Total: "64",
          Year3Pos: "0",
        },
       etc
      ];
    

    You can label dataSets entries in different colors like this:

    const data = {
      labels: dataSet.map(entry => entry.Name),
      datasets: [
        {
          label: 'Year1 Positives',
          data: dataSet.map(entry => parseInt(entry.Year1Pos)),
          backgroundColor: 'rgba(255, 99, 132, 0.5)',
        },
        {
          label: 'Year1 Total Minus Positives',
          data: dataSet.map(entry => parseInt(entry.Year1Total) - parseInt(entry.Year1Pos)),
          backgroundColor: 'rgba(54, 162, 235, 0.5)',
        },
        {
          label: 'Year2 Positives',
          data: dataSet.map(entry => parseInt(entry.Year2Pos)),
          backgroundColor: 'rgba(255, 206, 86, 0.5)',
        },
        {
          label: 'Year2 Total Minus Positives',
          data: dataSet.map(entry => parseInt(entry.Year2Total) - parseInt(entry.Year2Pos)),
          backgroundColor: 'rgba(75, 192, 192, 0.5)',
        },
        {
          label: 'Year3 Positives',
          data: dataSet.map(entry => parseInt(entry.Year3Pos)),
          backgroundColor: 'rgba(153, 102, 255, 0.5)',
        },
        {
          label: 'Year3 Total Minus Positives',
          data: dataSet.map(entry => parseInt(entry.Year3Total) - parseInt(entry.Year3Pos)),
          backgroundColor: 'rgba(255, 159, 64, 0.5)',
        },
      ],
    };
    

    NOTE: Make sure you change 'dataSet' to your dataset name, if named differently.

    *** UPDATE

    The following code should provide your requirements:

    const data = {
      labels: dataSet.map(entry => entry.Name),
      datasets: [
        {
          label: '2021 Positives',
          data: dataSet.map(entry => parseInt(entry.Year1Pos)),
          backgroundColor: 'rgba(255, 99, 132, 0.5)',
          stack: '2021'
        },
        {
          label: '2021 Non-Positives',
          data: dataSet.map(entry => parseInt(entry.Year1Total) - parseInt(entry.Year1Pos)),
          backgroundColor: 'rgba(54, 162, 235, 0.5)',
          stack: '2021'
        },
        {
          label: '2022 Positives',
          data: dataSet.map(entry => parseInt(entry.Year2Pos)),
          backgroundColor: 'rgba(255, 206, 86, 0.5)',
          stack: '2022'
        },
        {
          label: '2022 Non-Positives',
          data: dataSet.map(entry => parseInt(entry.Year2Total) - parseInt(entry.Year2Pos)),
          backgroundColor: 'rgba(75, 192, 192, 0.5)',
          stack: '2022'
        },
        {
          label: '2023 Positives',
          data: dataSet.map(entry => parseInt(entry.Year3Pos)),
          backgroundColor: 'rgba(153, 102, 255, 0.5)',
          stack: '2023'
        },
        {
          label: '2023 Non-Positives',
          data: dataSet.map(entry => parseInt(entry.Year3Total) - parseInt(entry.Year3Pos)),
          backgroundColor: 'rgba(255, 159, 64, 0.5)',
          stack: '2023'
        }
      ],
    };
    
    const options = {
      scales: {
        x: {
          stacked: true,
        },
        y: {
          stacked: true,
        }
      },
      plugins: {
        legend: {
          display: true,
          position: 'top'
        }
      }
    };
    

    And, here is a link to a working example:

    https://codesandbox.io/p/sandbox/santi-chart-m672m2