[Chartjs]-React ChartJS — Scale Bar Chart Vertically With More Datasets

1👍

First you could wrap the canvas in a div.

<div id="chartWrapper">
  <canvas id="myChart"></canvas>
</div>

You can make use of the Plugin Core API and compute the chart height in the beforeRender hook depending on the defined data.barThickness and the visible datasets.

plugins: [{
  beforeRender : chart => {        
    if (!chart.config.options.nonChartAreaHeight) {
      var yAxis = chart.scales.y;
      chart.config.options.nonChartAreaHeight = chart.height - (yAxis.bottom - yAxis.top);
    }      
    const labelCount = chart.data.labels.length;
    const datasetCount = chart.data.datasets.map((ds, i) => chart.getDatasetMeta(i)).filter(m => !m.hidden).length;
    const chartAreaHeight = labelCount * datasetCount * chart.data.barThickness * 1.2;
      document.getElementById("chartWrapper").style.height = (chartAreaHeight + chart.config.options.nonChartAreaHeight) + 'px';      
  }
}],

Then you also need to define option.maintainAspectRatio: false to prevent Chart.js from resizing the canvas.

Please take a look at below runnable code and see how it works.

new Chart('myChart', {
  type: 'bar',
  plugins: [{
    beforeRender : chart => {        
      if (!chart.config.options.nonChartAreaHeight) {
        var yAxis = chart.scales.y;
        chart.config.options.nonChartAreaHeight = chart.height - (yAxis.bottom - yAxis.top);
      }      
      const labelCount = chart.data.labels.length;
      const datasetCount = chart.data.datasets.map((ds, i) => chart.getDatasetMeta(i)).filter(m => !m.hidden).length;
      const chartAreaHeight = labelCount * datasetCount * chart.data.barThickness * 1.2;
      document.getElementById("chartWrapper").style.height = (chartAreaHeight + chart.config.options.nonChartAreaHeight) + 'px';      
    }
  }],
  data: {
    labels: ['1', '2', '3', '4'], 
    barThickness: 30, // change this to adapt the bar thickness
    datasets: [{          
      label: 'Dataset 1',
      data: [40, 50, 60, 80],
      backgroundColor: 'red'       
    },
    { 
      label: 'Dataset 2',
      data: [100, 90, 80, 70],
      backgroundColor: 'blue' 
    },
    {   
      label: 'Dataset 3',
      data: [60, 80, 70, 90],
      backgroundColor: 'green'  
    }]
  },
  options: {
    indexAxis: 'y',
    maintainAspectRatio: false
  }
});
div {  
  width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.8.0/chart.min.js"></script>
<div id="chartWrapper">
  <canvas id="myChart"></canvas>
</div>

Leave a comment