[Chartjs]-Spacing out stacked bars in chart.js

1👍

Regarding adding spaces between the bars, I wasn’t either able to find any direct configuration that allowed such behavior.

My first thought was to add borders and make them invisible, however you wouldn’t see the effect of borderRadius.

Then, I come to another approach that interleaves the dataset object with a ‘fake’ data with transparent color, which has customizable length acting as the gap. With the use of flatMap, you can construct such interleaved array.

Also putting everything in the outer object, you can avoid redundant code.

 datasets: {
      bar: {
        barThickness: 50,
        borderSkipped: false,
        borderRadius: {
          topLeft: 3,
          topRight: 3,
          bottomLeft: 3,
          bottomRight: 3
        }
      }
    },

That corresponds to:

var len_one = 0.02;
var len_two = 0.05;
var len_three = 0.72;
var len_four = 0.16;
var len_five = 0.05;

// Change this to adjust gap size
var len_separator = 0.05

const separator = {
  label: 'sepataror',
  data: [len_separator],
  backgroundColor: ['transparent'],
}

let data = [{
    label: 'red-low',
    data: [len_one],
    backgroundColor: ['#ab3025']
  },
  {
    label: 'rose-low',
    data: [len_two],
    backgroundColor: ['#d59792'],
  }, {
    label: 'Target',
    data: [len_three],
    backgroundColor: ['#44c973'],
  }, {
    label: 'high-yellow',
    data: [len_four],
    backgroundColor: ['#f9c63d'],
  }, {
    label: 'high-orange',
    data: [len_five],
    backgroundColor: ['#f5a000'],
  }
].flatMap(x => [x, { ...separator}])

const ctx = document.getElementById("myChart").getContext('2d');
const myChart = new Chart(ctx, {
  type: 'bar',
  data: {
    labels: [0],
    datasets: data,
  },
  options: {
    datasets: {
      bar: {
        barThickness: 50,
        borderSkipped: false,
        borderRadius: {
          topLeft: 3,
          topRight: 3,
          bottomLeft: 3,
          bottomRight: 3
        }
      }
    },
    indexAxis: 'y',
    events: [],
    maintainAspectRatio: false,
    layout: {
      padding: 20
    },
    plugins: {
      legend: {
        display: false
      }
    },
    scales: {
      x: {
        stacked: true,
        display: false
      },
      y: {
        beginAtZero: true,
        stacked: true,
        display: false,
      },
    },
  },

});
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">
  <link rel="stylesheet" href="style.css">
</head>

<body>
  <!-- Chart that displays the time in ranges-->
  <div class="col-6 offset-3 my-5" id="time_in_range">
    <canvas id="myChart"></canvas>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.0.0"></script>
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-pprn3073KE6tl6bjs2QrFaJGz5/SUsLqktiwsUTF55Jfv3qYSDhgCecCxMW52nD2" crossorigin="anonymous"></script>

</body>

</html>

About the grouped labels with brackets, I’m not sure it is possible without a plugin or something fancier.

0👍

The answer above was a correct solution to my problem, but that answer had been posted I figured out a different way to do it. I made 0.01 size bars in between each colored bar and made the color the same as the background of the webpage I was working on. That fixed my issue as well.

Leave a comment