[Chartjs]-Using ChartJS to create a multiple grouped bar chart โ€“ see picture below

4๐Ÿ‘

You can make use of the Plugin Core API. It offers different hooks that may be used for executing custom code. In below code, I use the afterDraw hook to draw the category labels and the delimiter lines.

new Chart('myChart', {
  type: 'bar',
  plugins: [{
    afterDraw: chart => {
      let ctx = chart.chart.ctx;
      ctx.save();    
      let xAxis = chart.scales['x-axis-0'];
      let xCenter = (xAxis.left + xAxis.right) / 2;
      let yBottom = chart.scales['y-axis-0'].bottom;
      ctx.textAlign = 'center';
      ctx.font = '12px Arial';
      ctx.fillText(chart.data.categories[0], (xAxis.left + xCenter) / 2, yBottom + 40);
      ctx.fillText(chart.data.categories[1], (xCenter + xAxis.right) / 2, yBottom + 40);
      ctx.strokeStyle  = 'lightgray';
      [xAxis.left, xCenter, xAxis.right].forEach(x => {
        ctx.beginPath();
        ctx.moveTo(x, yBottom);
        ctx.lineTo(x, yBottom + 40);
        ctx.stroke();
      });
      ctx.restore();
    }
  }],
  data: {
    labels: ['2004', '2008', '2012', '2016', '2004', '2008', '2012', '2016'],
    categories: ['Total', 'Lower than 2.50'],
    datasets: [{
        label: 'Male',
        data: [42.4, 43.0, 43.0, 50.3, 49.4, 48.4, 51.2, 51.8],
        backgroundColor: 'rgba(124, 181, 236, 0.9)',
        borderColor: 'rgb(124, 181, 236)',
        borderWidth: 1
      },
      {
        label: 'Female',
        data: [57.6, 57.0, 57.0, 49.7, 50.6, 51.6, 53.7, 54.6],
        backgroundColor: 'rgba(67, 67, 72, 0.9)',
        borderColor: 'rgb(67, 67, 72)',
        borderWidth: 1
      }
    ]
  },
  options: {
    legend: {
      position: 'bottom',
      labels: {
        padding: 30,
        usePointStyle: true
      }
    },
    scales: {
      yAxes: [{
        ticks: {
          min: 0,
          max: 80,
          stepSize: 20
        },
        scaleLabel: {
          display: true,
          labelString: 'Percent (%)'
        }
      }],
      xAxes: [{
        gridLines: {
          drawOnChartArea: false
        }
      }]
    }
  }
});
canvas {
  max-width: 400px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
<canvas id="myChart" height="200"></canvas>

1๐Ÿ‘

You have to define a second x-axis and play around with the many ticks and gridLines options.

Please take a look at below runnable code and see how it could be done. This is obviously only a draft and needs to optimized and made more generic.

new Chart(document.getElementById('myChart'), {
  type: 'bar',
  data: {
    labels: ['2004', '2008', '2012', '2004', '2008', '2012'],    
    datasets: [{
        label: 'Male',
        data: [42.4, 43.0, 43.0, 50.3, 49.4, 48.4],
        backgroundColor: 'rgba(124, 181, 236, 0.9)',
        borderColor: 'rgb(124, 181, 236)',
        borderWidth: 1
      },
      {
        label: 'Female',
        data: [57.6, 57.0, 57.0, 49.7, 50.6, 51.6],
        backgroundColor: 'rgba(67, 67, 72, 0.9)',
        borderColor: 'rgb(67, 67, 72)',
        borderWidth: 1
      }
    ]
  },
  options: {
    legend: {
      position: 'bottom',
      labels: {
        usePointStyle: true
      }
    },
    scales: {
      yAxes: [{
        ticks: {
          min: 0,
          max: 80,
          stepSize: 20
        },
        scaleLabel: {
          display: true,
          labelString: 'Percent (%)'
        }
      }],
      xAxes: [{
          gridLines: {
            drawOnChartArea: false
          }
        },
        {
          offset: true,
          ticks: {
            autoSkip: false,
            maxRotation: 0,
            padding: -15,
            callback: (v, i) => {
              if (i == 1) {
                return 'Total';
              } else if (i == 4) {
                return 'Lower than 2.50';
              } else {
                return '';
              }
            }
          },
          gridLines: {
            drawOnChartArea: false,
            offsetGridLines: true,
            tickMarkLength: 20,
            color: ['white', 'white', 'white', 'lightgray', 'white', 'white', 'lightgray']
          }
        }
      ]
    }
  }
});
canvas {
  max-width: 400px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
<canvas id="myChart" height="200"></canvas>

Leave a comment