[Chartjs]-Datalabels of Chart JS can not display full values

0๐Ÿ‘

โœ…

You can write a custom plugin that mimics the grace option that got introduced in v3, with this you can make sure your datalabels are always visible:

Chart.plugins.register(ChartDataLabels);

var options = {
  type: 'horizontalBar',
  data: {
    labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
    datasets: [{
        label: '# of Votes',
        data: [12, 20, 3, 5, 2, 3],
        borderWidth: 1
      },
      {
        label: '# of Points',
        data: [7, 11, 5, 8, 3, 7],
        borderWidth: 1
      }
    ]
  },
  options: {
    title: {
      display: false
    },
    legend: {
      position: 'right',
      display: false
    },
    scales: {
      xAxes: [{
        ticks: {
          beginAtZero: true,
        },
        //display: false,
      }],
      yAxes: [{
        display: false
      }]
    },
    responsive: true,
    plugins: {
      grace: {
        // grace: '10%', // add percentage of max and min to scale
        grace: 2, // add fixed number to min and max of scale
        hardMax: true // set suggestedMin/max or hard min/max
      },
      datalabels: {
        anchor: 'end',
        align: 'end',
        clamp: true,
        rotation: 0,
        padding: 12,
        labels: {

          clamp: true,
          value: {
            color: '#000'
          }
        },
        font: {
          size: '12',
          weight: 'bold'
        }
      },
    }
  },
  plugins: [{
    id: "grace",
    beforeLayout: (chart, options, c) => {
      let max = Number.MIN_VALUE;
      let min = Number.MAX_VALUE;
      let grace = options.grace || 0;
      let hardMax = options.hardMax || false;

      chart.data.datasets.forEach((dataset) => {
        max = Math.max(max, Math.max(...dataset.data));
        min = Math.min(min, Math.min(...dataset.data));
      })

      if (typeof grace === 'string' && grace.includes('%')) {
        grace = Number(grace.replace('%', '')) / 100;

        chart.options.scales.xAxes.forEach((axe) => {
          if (hardMax) {
            axe.ticks.max = max + (max * grace);
            axe.ticks.min = min - (min * grace);
          } else {
            axe.ticks.suggestedMax = max + (max * grace);
            axe.ticks.suggestedMin = min - (min * grace);
          }
        })

      } else if (typeof grace === 'number') {

        chart.options.scales.xAxes.forEach((axe) => {
          if (hardMax) {
            axe.ticks.max = max + grace;
            axe.ticks.min = min - grace;
          } else {
            axe.ticks.suggestedMax = max + grace;
            axe.ticks.suggestedMin = min - grace;
          }
        })

      }

    }
  }]
}

var ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
  <canvas id="chartJSContainer" width="600" height="400"></canvas>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-datalabels/1.0.0/chartjs-plugin-datalabels.js"></script>
</body>

Setting the hardMax option for the custom plugin to false will result in bigger white space in the end since it will prioritze nice tick spacement, set this to option to true and the bars have more space but the last tick space is a little off

1๐Ÿ‘

The easiest way is to put some padding in your ChartOptions:

ChartOptions = {
    layout: {
      padding: {
        right: 25,
      },
    },
   }

Leave a comment