[Chartjs]-ChartJS – Show values in the center of each bar

1👍

This can be done with the Plugin Core API. The API offers different hooks that may be used for executing custom code (that’s probably what you already do). In your case, you can use the afterDraw hook as follows to draw text at the desired positions.

afterDraw: chart => {
  let ctx = chart.chart.ctx;
  ctx.save();
  ctx.textAlign = 'center';
  ctx.textBaseline = 'middle';
  ctx.font = "12px Arial";
  let xAxis = chart.scales['x-axis-0'];
  let yAxis = chart.scales['y-axis-0'];
  let datasets = chart.chart.data.datasets.filter(ds => !ds._meta[0].hidden);
  xAxis.ticks.forEach((value, xIndex) => {
    let x = xAxis.getPixelForTick(xIndex);
    datasets.forEach((dataset, iDataset) => {
      if (dataset.data[xIndex] > 3) {
        let yValue = datasets.slice(0, iDataset)
          .map(ds => ds.data[xIndex])
          .reduce((a, b) => a + b, 0) +
          dataset.data[xIndex] / 2;
        let y = yAxis.getPixelForValue(yValue);
        ctx.fillStyle = dataset.textColor;
        ctx.fillText(dataset.data[xIndex] + '%', x, y);
      }
    });
  });
  ctx.restore();
}

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

const chart = new Chart('myChart', {
  type: 'bar',
  plugins: [{
    afterDraw: chart => {
      let ctx = chart.chart.ctx;
      ctx.save();
      ctx.textAlign = 'center';
      ctx.textBaseline = 'middle';
      ctx.font = "12px Arial";
      let xAxis = chart.scales['x-axis-0'];
      let yAxis = chart.scales['y-axis-0'];
      let datasets = chart.chart.data.datasets.filter(ds => !ds._meta[0].hidden);
      xAxis.ticks.forEach((value, xIndex) => {
        let x = xAxis.getPixelForTick(xIndex);
        datasets.forEach((dataset, iDataset) => {
          if (dataset.data[xIndex] > 3) {
            let yValue = datasets.slice(0, iDataset)
              .map(ds => ds.data[xIndex])
              .reduce((a, b) => a + b, 0) +
              dataset.data[xIndex] / 2;
            let y = yAxis.getPixelForValue(yValue);
            ctx.fillStyle = dataset.textColor;
            ctx.fillText(dataset.data[xIndex] + '%', x, y);
          }
        });
      });
      ctx.restore();
    }
  }],
  data: {
    labels: ['A', 'B', 'C', 'D', 'E'],
    datasets: [{
      label: 'Dataset 1',
      data: [2.5, 48, 9, 17, 23],
      backgroundColor: 'red',
      textColor: 'white'
    }, {
      label: 'Dataset 2',
      data: [2.5, 4, 4, 11, 11],
      backgroundColor: 'orange',
      textColor: 'black'
    }, {
      label: 'Dataset 3',
      data: [95, 48, 87, 72, 66],
      backgroundColor: 'green',
      textColor: 'white'
    }]
  },
  options: {
    scales: {
      xAxes: [{
        stacked: true
      }],
      yAxes: [{
        stacked: true,
        ticks: {
          beginAtZero: true
        }
      }]
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
<canvas id="myChart" height="160"></canvas>

Leave a comment