chart.js

Fill chart with n bars but calculate the width of the bars to always keep the same gap


In ChartJS, I would like to distribute bars n over the length of the x axis. We can ignore the y axis for now as everything works as expected.

What I would like to achieve is, that the gap of the bars stays also the same, but the amount of bars determines how the width of each bar is.

So let's say I have 20 bars. Then considering the gap should be always the same, the bars have a width of 20 each. When I then reduce the amount of bars to let's say 5, I would like to keep the width of the gap the same but the remaining space created will be the bars width.

How can I do this?


Solution

  • If you want to set the width of the gaps between bars and adapt everything else to that, there is no specific option, you'll have to compute the bar width using a formula based on the total width (that can be obtained through the x scale, chart.scales.x), the number of bars and the intended gap.

    If there is only one dataset, the formula is as simple as: barThickness <-- totalWidth / nBars - gap. Demo snippet:

    const nBars = 10,
       gap = 15; //px
    const data = {
       labels: Array.from({length: nBars}, (_, i)=>String.fromCharCode('A'.charCodeAt(0)+i)),
       datasets: [
          {
             label: 'Dataset 1',
             data: Array.from({length: nBars}, () => Math.random()*10),
          }
       ]
    };
    
    const config = {
       type: 'bar',
       data: data,
       options: {
          responsive: true,
          maintainAspectRatio: false,
          barThickness: function(context){
             const totalWidth = context.chart.scales.x.width;
             // there are nBars-1 gaps + half gap left + half gap right.
             return totalWidth / nBars - gap;
             // fun fact: if the result is negative, the option is ignored
          }
       },
    };
    
    new Chart("myChart", config);
    <div style="height: 300px">
       <canvas id="myChart"></canvas>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>