How to set ticks on axes dynamically with chart.js?

Keya Kersting picture Keya Kersting · Aug 21, 2018 · Viewed 10k times · Source

We have values which can vary when the site is loaded and we want to dynamically set the tick step size. We have two datasets with differing units in the same chart and want to have the horizontal gridlines match each other. On one side it's a scale from 0-100% in steps of 20. On the other side we want to have the maximum as a multiple of 10 and set the stepsize as 1/5 of the maximum (ergo the gridlines should match each other). But stepsize unless fix typed as "10" (see id: 'B') or the like will not get loaded. We tried to set it dynamically with a class variable but it's no use. We use Angular5 and the ng2-charts library

public averageOptions: any = {
legend: {
  labels: {
    fontColor: 'rgb(255,255,255)',
    fontSize: 15
  }
},
scales: {
  yAxes: [{
    id: 'A',
    type: 'linear',
    position: 'left',
    ticks: {
      min: 0,
      max: 100,
      stepSize: 20,
      fontColor: 'rgb(255,255,255)',
      fontSize: 15,
      callback: function (value) {
        return value + '%';
      }
    },
    gridLines: {
      zeroLineColor: 'rgb(255,255,255)',
      color: 'rgb(255,255,255)'
    }
  }, {
    id: 'B',
    type: 'linear',
    position: 'right',
    ticks: {
      min: this.totalVotesMin,
      max: this.totalVotesMax,
      fontColor: 'rgb(255,255,255)',
      fontSize: 15,
      stepSize: 10
    },
    gridLines: {
      zeroLineColor: 'rgb(255,255,255)',
      color: 'rgb(255,255,255)'
    }
  }],
  xAxes: [{
    ticks: {
      fontColor: 'rgb(255,255,255)',
      fontSize: 15
    },
    gridLines: {
      zeroLineColor: 'rgb(255,255,255)',
      color: 'rgb(255,255,255)'
    }
  }]
}
  };

We found this somewhat related topic but we have no idea how the tick array looks or how to set it as there is no documentation about it: Chart.js - Setting max Y axis value and keeping steps correct

Answer

Prafulla Kumar Sahu picture Prafulla Kumar Sahu · May 29, 2019

It seems quite a long, but you can use below code to change the steps and max value based on input data.

ticks: {
            min: 0,
            callback: function(value, index, values) {
                if (Math.floor(value) === value) {
                    return value;
                }
            }
      }