124

I want to display all of the points on my chart from the data I get, but I don't want to display all the labels for them, because then the chart is not very readable. I was looking for it in the docs, but couldn't find any parameter that would limit this.

I don't want to take only three labels for example, because then the chart is also limited to three points. Is it possible?

I have something like that right now:

enter image description here

If I could just leave every third-fourth label, it would be great. But I found absolutely nothing about labels options.

Tot Zam
  • 8,406
  • 10
  • 51
  • 76
mmmm
  • 3,768
  • 9
  • 36
  • 63

15 Answers15

217

Try adding the options.scales.xAxes.ticks.maxTicksLimit option:

xAxes: [{
    type: 'time',
    ticks: {
        autoSkip: true,
        maxTicksLimit: 20
    }
}]
reformed
  • 4,505
  • 11
  • 62
  • 88
Nikita Ag
  • 2,336
  • 1
  • 10
  • 10
  • 4
    The answer above plus this answer here http://stackoverflow.com/a/37257056/558094, is the bomb. – Vinayak Garg Dec 01 '16 at 07:11
  • @Nikita your solution is working but when i set chart have maxTicksLimit 7 but load chart and chart data length 8 then it will display maxTicksLimit 8. have you idea please suggest me ? thanks – VjyV Dec 09 '16 at 13:45
  • 3
    Something is wrong here. I'm getting a huge gap between the last two ticks: https://jsfiddle.net/askhflajsf/xzk6sh1q/ – Mark Boulder Jun 08 '17 at 18:59
  • 1
    The link to the docs does not work anymore. Couldn't find this information in the docs at all but it works :) – Daniel W. Aug 18 '17 at 14:50
  • 3
    Where do you get this info from? A lot of unswers i'm reading for Chart.js - i'm unable to find in their docs http://www.chartjs.org/docs/latest/ , am i missing some place where i may actually find all those little properties and overridable callbacks documented? – Max Yari Mar 09 '18 at 16:28
  • 2
    You can also add `maxRotation: 0` if you want it not to rotate before start dropping the labels. – Caio Cunha Nov 29 '18 at 06:33
22

For concreteness, let's say your original list of labels looks like:

["0", "1", "2", "3", "4", "5", "6", "7", "8"]

If you only want to display every 4th label, filter your list of labels so that every 4th label is filled in, and all others are the empty string (e.g. ["0", "", "", "", "4", "", "", "", "8"]).

ben
  • 269
  • 2
  • 3
  • This is a great hack, thanks! I added it [here](https://github.com/nnnick/Chart.js/issues/12). – Trufa Nov 04 '14 at 18:12
  • 46
    Mind that passing `""` also removes corresponding tooltips on the graph! – Haywire Nov 05 '14 at 01:40
  • 3
    Unless I am wrong this can be easily done with a list comprehension if you want e.g. to show every 10th label: `my_labels = [my_labels[i] if i % 10 == 0 else "" for i in range(len(my_list))]`. The number 10 can of course be declared as a constant at the beginning of the file for easier parameterization of the process. – pkaramol Apr 06 '16 at 11:03
  • 1
    it also could be done without **`""`**, as in the answer to this question [vertical gird line issue with chart.js](http://stackoverflow.com/questions/39135489/vertical-gird-line-issue-with-chart-js) where the OP had an issue with black line appears on the first occurrence of this double quote, in such case it helped, again as @haywire mentioned it removes the label from the tooltip – Mi-Creativity Aug 25 '16 at 03:33
17

For anyone looking to achieve this on Chart JS V2 the following will work:

 var options =  {  
         scales: {
            xAxes: [{
                afterTickToLabelConversion: function(data){


                    var xLabels = data.ticks;

                    xLabels.forEach(function (labels, i) {
                        if (i % 2 == 1){
                            xLabels[i] = '';
                        }
                    });
                } 
            }]   
        }
}

Then pass the options variable as usual into a:

myLineChart = new Chart(ctx, {
    type: 'line',
    data: data,
    options: options
});`
George D
  • 421
  • 5
  • 6
15

UPDATE:

I'v updated my fork with the latest pull (as of Jan 27, 2014) from NNick's Chart.js master branch. https://github.com/hay-wire/Chart.js/tree/showXLabels

ORIGINAL ANSWER:

For those still facing this issue, I forked Chart.js a while back to solve the same problem. You can check it out on: https://github.com/hay-wire/Chart.js/tree/skip-xlabels => Older branch! Check showXLabels branch for latest pull.

How to use:

Applicable to bar chart and line chart.

User can now pass a { showXLabels: 10 } to display only 10 labels (actual displayed labels count might be a bit different depending on the number of total labels present on x axis, but it will still remain close to 10 however)

Helps a lot when there is a very large amount of data. Earlier, the graph used to look devastated due to x axis labels drawn over each other in the cramped space. With showXLabels, user now has the control to reduce the number of labels to whatever number of labels fit good into the space available to him.

See the attached images for a comparison.

Without showXLabels option: enter image description here

With { showXLabels: 10 } passed into option: enter image description here

Here's some discussion on it: https://github.com/nnnick/Chart.js/pull/521#issuecomment-60469304

Haywire
  • 858
  • 3
  • 14
  • 30
  • Would love to use this but I must be doing something wrong. I referenced https://github.com/hay-wire/Chart.js/blob/showXLabels/Chart.js but (as of Oct 30, 2015) it doesn't work and doesn't even contain the phrase "showXLabels". The older one, at https://github.com/hay-wire/Chart.js/blob/skip-xlabels/Chart.js, works just fine. Would love to get a working, tagged version of the latest so I can safely CDN-link it from RawGit. This Fiddle (while not distilled to just the issue) shows what I mean: https://jsfiddle.net/45cLcxdh/14/ – rkagerer Oct 30 '15 at 07:44
  • Tried using this but it looks like 'Chart.Line.js' doesn't get used, thus nothing changes. I used "new Chart(ctx).Line(data, options);" to create a chart. – FlyingNimbus Mar 23 '16 at 16:47
  • Using Chart JS 2.6.0 and the option does not work. Eventually I had to use @ben's answer https://stackoverflow.com/a/26183983/3319454 – 3bdalla Oct 26 '17 at 07:20
  • 1
    I think this is part of a previous version – alexalejandroem Dec 12 '19 at 18:14
  • @alexalejandroem Yes it was answered in 2014! ;-) – Haywire Dec 13 '19 at 03:55
10

For Chart.js 3.3.2, you can use @Nikita Ag's approach with a few changes. You can check the documentation. Put ticks in xAxis in scales. Example:

...
options: {
    scales: {
        xAxis: {
            ticks: {
                maxTicksLimit: 10
            }
        }
    }
}
...
busterroni
  • 591
  • 8
  • 17
8

for axis rotation

use this:

          scales: {
        xAxes: [
          {
            // aqui controlas la cantidad de elementos en el eje horizontal con autoSkip
            ticks: {
              autoSkip: true,
              maxRotation: 0,
              minRotation: 0
            }
          }
        ]
      }
Edgar Olivar
  • 1,348
  • 13
  • 13
8

In Chart.js 3.2.0:

options: {
    scales: {
        x: {
            ticks: {
                maxTicksLimit: 10
            }
        }
    }
}
mfluehr
  • 2,832
  • 2
  • 23
  • 31
Vyshnav MK
  • 131
  • 1
  • 5
2

According to the chart.js github issue #12. Current solutions include:

  1. Use 2.0 alpha (not production)
  2. Hide x-axis at all when it becames too crowd (cannot accept at all)
  3. manually control label skip of x-axis (not in responsive page)

However, after a few minutes, I thinks there's a better solution.

The following snippet will hide labels automatically. By modify xLabels with empty string before invoke draw() and restore them after then. Even more, re-rotating x labels can be applied as there's more space after hiding.

var axisFixedDrawFn = function() {
    var self = this
    var widthPerXLabel = (self.width - self.xScalePaddingLeft - self.xScalePaddingRight) / self.xLabels.length
    var xLabelPerFontSize = self.fontSize / widthPerXLabel
    var xLabelStep = Math.ceil(xLabelPerFontSize)
    var xLabelRotationOld = null
    var xLabelsOld = null
    if (xLabelStep > 1) {
        var widthPerSkipedXLabel = (self.width - self.xScalePaddingLeft - self.xScalePaddingRight) / (self.xLabels.length / xLabelStep)
        xLabelRotationOld = self.xLabelRotation
        xLabelsOld = clone(self.xLabels)
        self.xLabelRotation = Math.asin(self.fontSize / widthPerSkipedXLabel) / Math.PI * 180
        for (var i = 0; i < self.xLabels.length; ++i) {
            if (i % xLabelStep != 0) {
                self.xLabels[i] = ''
            }
        }
    }
    Chart.Scale.prototype.draw.apply(self, arguments);
    if (xLabelRotationOld != null) {
        self.xLabelRotation = xLabelRotationOld
    }
    if (xLabelsOld != null) {
        self.xLabels = xLabelsOld
    }
};

Chart.types.Bar.extend({
    name : "AxisFixedBar",
    initialize : function(data) {
        Chart.types.Bar.prototype.initialize.apply(this, arguments);
        this.scale.draw = axisFixedDrawFn;
    }
});

Chart.types.Line.extend({
    name : "AxisFixedLine",
    initialize : function(data) {
        Chart.types.Line.prototype.initialize.apply(this, arguments);
        this.scale.draw = axisFixedDrawFn;
    }
});

Please notice that clone is an external dependency.

yegong
  • 739
  • 1
  • 7
  • 15
1

i had a similar type of issue, and was given a nice solution to my specific issue show label in tooltip but not in x axis for chartjs line chart. See if this helps you

Community
  • 1
  • 1
vsank7787
  • 224
  • 2
  • 4
  • 10
1

you can limit at as

scales: {
                x: {
                  ticks: {
                    // For a category axis, the val is the index so the lookup via getLabelForValue is needed
                    callback: function(val, index) {
                    // Hide the label of every 2nd dataset
                    return index % 5 === 0 ? this.getLabelForValue(val) : '';
                    },
                  }
                }
              }

this will skip 4 labels and set the 5th one only.

enter image description here

Muhammad Zakaria
  • 1,269
  • 6
  • 14
1

you can use the following code:

xAxes: [{
    ticks: {
        autoSkip: true,
        maxRotation: 90
    }
}]
Federico klez Culloca
  • 26,308
  • 17
  • 56
  • 95
1

You may well not need anything with this new built-in feature.

A built-in label auto-skip feature detects would-be overlapping ticks and labels and removes every nth label to keep things displaying normally. https://www.chartjs.org/docs/latest/axes/

Al Martins
  • 431
  • 5
  • 13
0

To set a custom number of ticks regardless of your chartsjs version:

yAxes: [{
    ticks: {
        stepSize: Math.round((Math.max.apply(Math, myListOfyValues) / 10)/5)*5,
        beginAtZero: true,
        precision: 0
    }
}]

10 = the number of ticks

5 = rounds tick values to the nearest 5. All your y values will have the same step size.

Similar will work for xAxes too.

Collin
  • 394
  • 5
  • 14
-1

This answer works like a charm.

If you are wondering about the clone function, try this one:

var clone = function(el){ return el.slice(0); }
reformed
  • 4,505
  • 11
  • 62
  • 88
Lackneets
  • 21
  • 2
  • 5
-2

In the Chart.js file, you should find (on line 884 for me)

var Line = function(...
    ...
    function drawScale(){
        ...
        ctx.fillText(data.labels[i], 0,0);
        ...

If you just wrap that one line call to fillText with if ( i % config.xFreq === 0){ ... } and then in chart.Line.defaults add something line xFreq : 1 you should be able to start using xFreq in your options when you call new Chart(ctx).Line(data, options).

Mind you this is pretty hacky.

Jake
  • 13
  • 3