Chart.js: uneven distribution of xaxis time scale with 'autoSkip:true' and maxTicksLimit

Created on 8 Sep 2016  路  12Comments  路  Source: chartjs/Chart.js

image

Here initially gap is 5 days but at end it gets increased and data is cluttered at the end of the scale.
Data:

"x_axis": [
            1465084800000,
            1466553600000,
            1467417600000,
            1470096000000,
            1471651200000,
            1472083200000,
            1472688000000,
            1472774400000,
            1473033600000,
            1473120000000,
            1473206400000
        ],
        "y_axis": [
            1,
            2,
            4,
            2,
            3,
            2,
            3,
            2,
            4,
            1.8,
            1.3
        ]

and options set are

ticks: {
                    autoSkip:true,
                    maxTicksLimit:20,
                    maxRotation:30
                }
time scale

Most helpful comment

@etimberg This problem also affects category scale, not just time scale.

This bug is an "emergent behavior" of how the tick skipping is performed. If the number of plot points on the x axis is evenly divisible by the number of labels Chart.js decides to render, then the gap will not appear.

A contributing factor is the insistence on always plotting the last tick mark. Perhaps this should be an option that can be disabled. What I would like is interpolation and nearest neighbor matching for tick placement.

So, maybe there needs to be a config option like:

options.scales.xAxes[].ticks.autoSkipStyle = 'nearest'; //One of: 'fixed', 'nearest', 'skipLast'

I was able to work around it and get a more aesthetically pleasing plot (in my opinion) by making the following change to Chart.js.
Locate the _autoSkip() function and replace:

// Since we always show the last tick,we need may need to hide the last shown one before
shouldSkip = (skipRatio > 1 && i % skipRatio > 0) || (i % skipRatio === 0 && i + skipRatio >= tickCount);
if (shouldSkip && i !== tickCount - 1 || helpers.isNullOrUndef(tick.label)) {
    // leave tick in place but make sure it's not displayed (#4635)
    delete tick.label;
}
result.push(tick);

with

// Last tick is only displayed if number of categories on axis is evenly divisible by skipRatio
shouldSkip = (skipRatio > 1 && i % skipRatio > 0);
if (shouldSkip || helpers.isNullOrUndef(tick.label)) {
    // leave tick in place but make sure it's not displayed (#4635)
    delete tick.label;
}
result.push(tick);

All 12 comments

@nikitaagarwal-limetray do you have time.max set? can you put this in a jsfiddle?

@etimberg https://jsfiddle.net/L3cng59w/ I think the problem is that if number of ticks greater than maxTicksLimit, it doesn't add the penultimate tick.

This still reproduces in v2.5.0 https://jsfiddle.net/z3qwrvds/

I have a quite similar issue. The x-axis is date but it does not distribute evenly. Here is my option setting:
xAxes:[{ ticks:{ autoSkip:true, maxTicksLimit:4, maxRotation: 0, minRotation: 0, } }],
the actual output is:
2017-05-29 15_50_34-longpaddock
@etimberg do you have any suggestions for my case? This a multiple chart and the total number of day is 30. What I expected is displaying the date on x-axis with 10 interval

+1

Penultimate tick missing when reached the maxTicksLimit, should instead evenly space them. Using chartjs v2.6.0

xAxes:[{ ticks:{ autoSkip:true, maxTicksLimit:10 } }]

Still an issue in ChartJS 2.7.0, with the new time series options.
Here's a sample of my options for my time series graph.

xAxes: [{
  distribution: 'linear'
  ticks: {
    autoSkip:true,
    maxTicksLimit:10,
    source: 'auto'
  }
}]

Here's a screenshot of what my graph looks like;
capture4

Penultimate tick still missing here. I would look into submitting a PR with a fix but I don't have the time :(

We fixed a similar issue in 2.7.0 with the time scale but the maxTickLimit behavior is still the same.

@etimberg This problem also affects category scale, not just time scale.

This bug is an "emergent behavior" of how the tick skipping is performed. If the number of plot points on the x axis is evenly divisible by the number of labels Chart.js decides to render, then the gap will not appear.

A contributing factor is the insistence on always plotting the last tick mark. Perhaps this should be an option that can be disabled. What I would like is interpolation and nearest neighbor matching for tick placement.

So, maybe there needs to be a config option like:

options.scales.xAxes[].ticks.autoSkipStyle = 'nearest'; //One of: 'fixed', 'nearest', 'skipLast'

I was able to work around it and get a more aesthetically pleasing plot (in my opinion) by making the following change to Chart.js.
Locate the _autoSkip() function and replace:

// Since we always show the last tick,we need may need to hide the last shown one before
shouldSkip = (skipRatio > 1 && i % skipRatio > 0) || (i % skipRatio === 0 && i + skipRatio >= tickCount);
if (shouldSkip && i !== tickCount - 1 || helpers.isNullOrUndef(tick.label)) {
    // leave tick in place but make sure it's not displayed (#4635)
    delete tick.label;
}
result.push(tick);

with

// Last tick is only displayed if number of categories on axis is evenly divisible by skipRatio
shouldSkip = (skipRatio > 1 && i % skipRatio > 0);
if (shouldSkip || helpers.isNullOrUndef(tick.label)) {
    // leave tick in place but make sure it's not displayed (#4635)
    delete tick.label;
}
result.push(tick);

I quite like the idea of the autoSkipStyle config option. Any Chart.JS maintainers able to comment on the above workaround?

@heyrex think you could turn that workaround into a PR with the autoSkipStyle config option?

I'm not sure about autoSkipStyle since it seems that most people complain about that extra gap. In the time scale, we decided to remove that behavior (though, still an issue with the auto skipper), so I think we should consider it as a bug instead of a feature request and remove all logic about this last tick.

@nikita-ag Hi there, I've experienced the same issue, I've been trying to play with the time scale type and its options but it does not look well, how did you get to manage this.
Thanks and nice job!

Hi there, i'm facing a similar issue (not with a time scale). Is there a way to show the penultimate tick and hide the last one? To prevent showing the gap between last interval values?
Thank you.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

akashrajkn picture akashrajkn  路  3Comments

gabrieldesouza picture gabrieldesouza  路  3Comments

JewelsJLF picture JewelsJLF  路  3Comments

joebirkin picture joebirkin  路  3Comments

frlinw picture frlinw  路  3Comments