javascriptreactjschart.jsreact-chartjs

Stacked bar chart starting from 0 - ChartJS React


I am building a simple horizontal bar chart. For each label, there are two data. One with duplicates, the other without duplicates. I want to create a horizontal stacked bar with both bars starts from 0.

I managed to create a stacked bar but the second bar starts from the end of the first. I want it to start from 0.

What I have enter image description here

For example: In banking, I have the two data, one is Banking categories with value 30. The other is Banking with duplicates 43. The bars are added together, 30+43. However, I just want that the both starts from 0, so that only 13 (43-30) appears after the 30. So that the total is 43, not 43+30

What I would like to have

enter image description here

My component

function CategoriesCard({coming_props}){
const data = {
  labels: [
      'Email',
      'DoB',
      'Credit Card',
      'Passport Number',
      'Driver Licence',
      'National Insurance',
      'Banking',
      'Phone',
      'Address',
      'Postcode',
      'Social Media',
      'Organisation',
      'Location',
      'Nationality / belief',
      'Financial',
      'Ethnicity'
  ],
  datasets: [
      {
          label: 'Categories',
          stack: 'stack1',
          backgroundColor: '#04A9F5',
          borderColor: '#04A9F5',
          borderWidth: 1,
          hoverBackgroundColor: '#04A9F5',
          hoverBorderColor: '#04A9F5',
          data: [25, 21, 25, 25, 25, 28, 30,22, 21, 25, 25, 25, 28, 30,30,29],
    },
    {
        label: 'With duplicates',
        stack: 'stack1',
        backgroundColor: '#A8C6F5',
        borderColor: '#A8C6F5',
        borderWidth: 1,
        hoverBackgroundColor: '#A8C6F5',
        hoverBorderColor: '#A8C6F5',
        data: [34, 43, 12, 32, 42, 43, 43,22, 21, 25, 25, 25, 28, 30, 30, 29],
    }
  ],
};

const options = {
    maintainAspectRatio: false,
    scales: {
            xAxes: [{
                ticks: {
                    min: 0,
                    beginAtZero: true
                }
            }]
    }
}



return (
  <div style={{margin: '2%', height:'100%'}}>
    <Paper style={{height: '100%'}}>
      <h3>CATEGORIES</h3>
        <div style={{height: '90%', width:'90%'}}>
            <HorizontalBar
            data={data}
            options={options}
            height={500}
            width={200}
            />
        </div>
    </Paper>
  </div>
  )
}

export default CategoriesCard

What I did

I calculated the difference between the two data array (categories and with duplicates) and assigned it to my second data.

Example:

let data_categories = [25, 21, 25]
let data_duplicates = [34, 43, 35]

let final_data = [(34-35), (43-21), (35-25)]

It does work to fix the bar dimensions, but if i hover on it, it display the difference not the initial real number.


Solution

  • Your solution to create a dataset with the difference between the lower value and upper value was how I had to resolve this problem as well. As for the tooltip on hover, I created a label callback within options.tooltips.callbacks like so:

    options: {
      tooltips: {
        callbacks: {
          label: function(tooltipItem, data) {
            var label = data.datasets[tooltipItem.datasetIndex].label;
            if (label === 'With duplicates') {
              var total = tooltipItem.xLabel + data.datasets[0].data[tooltipItem.datasetIndex];
              return label + ': ' + total;
            }
            return label + ': ' + tooltipItem.xLabel;
          }
        }
      }
    }
    

    The parameters tooltipItem and data are automatically populated for you using the dataset sent to the <canvas> tag (I suggest logging those objects within the callback during testing just to peek at what they include). You can find all kinds of interesting things you can do with the tooltips here: https://www.chartjs.org/docs/latest/configuration/tooltip.html