Logarithmic axes do not respect maxTicksLimit

Expected Behavior

Only the number of tick lines specified should show, or at least something readable should render.

Current Behavior

Every increment of 1eX, 2eX, and 5ex are shown between the min and max. This can be exceptionally hard to read.

The codepen linked below shows the issue, but using my actual data which has a much larger range the axis looks even worse.
image

Possible Solution

Don’t allow the logarithmic ticks to be so close together.

Based on the current behavior, it seems that 1eX, 2eX, and 5ex are always shown on the grid, no matter the range.

it seems like if the numbers are that large, basically only the exponent should be considered. For example, if the values are 1e1, 1e2, 1e3, …, 1e100, the axis ticks would be similar to a linear graph with points 1, 2, 3, …, 100.

Steps to Reproduce (for bugs)

https://codepen.io/anon/pen/dzrPzO

Context

I’m unable to use chart.js because of this bug as I’m plotting only logarithmic graphs.

Environment

  • Chart.js version: 2.6.0
  • Browser name and version: Chrome
  • Link to your project: N/A, See codepen link above for details

Author: Fantashit

1 thought on “Logarithmic axes do not respect maxTicksLimit

  1. @dfederm I agree that the default tick formatter code could be improved on. You could obtain the result you’ve described by overriding the default ticks callback by setting ticks.userCallback example.
    The formatter function in the example accepts a new option ticks.labels, in which you are able to config which ticks should be displayed and if empty gridlines should be display or not.

    labels: {
      index:  ['min', 'max'], // Show ticks for min and max value, or whatever numeric index
      significand:  [1], // Show ticks with significand number, default [1, 2, 5]
      removeEmptyLines: true // hide empty gridlines, default is false
    }
    var helpers = Chart.helpers;
    /* logarithmic formatter function */
    var logarithmicFormatter = function(tickValue, index, ticks) {
        var me = this;
        var labelOpts =  me.options.ticks.labels || {};
        var labelIndex = labelOpts.index || ['min', 'max'];
        var labelSignificand = labelOpts.significand || [1, 2, 5];
        var significand = tickValue / (Math.pow(10, Math.floor(helpers.log10(tickValue))));
        var emptyTick = labelOpts.removeEmptyLines === true ? undefined : '';
        var namedIndex = '';
    
        if (index === 0) {
            namedIndex = 'min';
        } else if (index === ticks.length - 1) {
            namedIndex = 'max';
        }
    
        if (labelOpts === 'all'
            || labelSignificand.indexOf(significand) !== -1
            || labelIndex.indexOf(index) !== -1
            || labelIndex.indexOf(namedIndex) !== -1
        ) {
            if (tickValue === 0) {
                return '0';
            } else {
                return tickValue.toExponential();
            }
        }
        return emptyTick;
    };
    var ctx = document.getElementById("myChart");
    var myChart = new Chart(ctx, {
        type: 'line',
        data: {
            labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
            datasets: [
              {
                label: 'dataset 1',
                data: [1e12, 1e19, 1e3, 1e5, 1e2, 1e3]
              },
              {
                label: 'dataset 2',
                data: [1e0, 1e1, 1e2, 1e1, 1e1, 1e1]
              }
            ]
        },
        options: {
            scales: {
                yAxes: [{
                    type: "logarithmic",
                    ticks: {
                        labels: {
                            index:  ['min', 'max'],
                            significand:  [1],
                            removeEmptyLines: true,
                        },
                        userCallback: logarithmicFormatter
                    }
                }]
            }
        }
    });

Comments are closed.