2

I'm trying to duplicate the X axis ticks on both sides of the chart (Bottom and Top).

I have seen older questions of this asked but this was during chartjs 2.x -- They have changed the scale section of the options since then. You used to be able to do something similar to this:

xAxes: [
      {
        position: 'top',
      },
      {
        position: 'bottom',
      }
    ]

But in Chartjs 3.x you can't supply an array for xAxes. You need to now add an ID to your dataset then in the scale options reference that ID. But I can't reference 1 dataset in 2 scale objects when one says position: top and the other position: bottom. It will only use the last scale object.

So my question is, with ONE dataset. How can I have it so the X axis is on the bottom of the chart AND the top of a horizontal bar chart? That way in case the chart is big I don't have to always scroll down to see what the value is.

Edit: Based on feedback I now have the following result, which is closer to what I'm looking for, but what's going on with the ticks on the top. Why aren't they matching the numbers on the bottom?

new Chart('myChart', {
  type: 'line',
  data: {
    labels: ['A', 'B', 'C', 'D', 'E', 'F'],
    datasets: [{    
      data: [1, 3, 6, 2, 8, 9],
      borderColor: '#00D',
    }]
  },
  options: {
    indexAxis: "y",
    scales: {
      x: {
      },
      x1: {
        position: 'top'
      }
    }
  }
});
canvas {
  max-height: 180px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.1/chart.min.js"></script>
<canvas id="myChart"></canvas>

2 Answers2

1

In case you want the see the same ticks at the top of the chart, simply define a second x-axis as follows:

x1: {
  position: 'top'
}

Please take a look at below runnable code and see how it works:

new Chart('myChart', {
  type: 'line',
  data: {
    labels: ['A', 'B', 'C', 'D', 'E', 'F'],
    datasets: [{    
      data: [1, 3, 6, 2, 8, 9],
      borderColor: '#00D',
    }]
  },
  options: {
    scales: {
      x: {
      },
      x1: {
        position: 'top'
      }
    }
  }
});
canvas {
  max-height: 180px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.1/chart.min.js"></script>
<canvas id="myChart"></canvas>
uminder
  • 23,831
  • 5
  • 37
  • 72
  • 1
    Interesting, so it seems what makes my scenario special is that I'm using horizontal bar charts via ```indexAxis: "y",```. Your solution works if I was using a normal bar chart, I have updated my question to be specifically for a horizontal bar chart. With a horizontal bar chart, the labels of ```['A', 'B', 'C', 'D', 'E', 'F']``` show up on the Y axis and the X axis is ```[0, 2, 4, 6, 8, 10]```. So the X ticks are on the bottom by default and when I try what you suggested I get ticks on the top, but the values are not the same as the ones on the bottom. What is on top is ```[0, 0.1,..,1]``` – intrepiddrain Oct 22 '21 at 13:26
  • 1
    I have also added a runnable code snippet for what I'm experiencing in the original post. – intrepiddrain Oct 22 '21 at 13:38
0

In case you want to produce a horizontal bar chart, you could define the x-axes as follows:

scales: {
  x: {
    min: 0
  },
  x1: {
    position: 'top',
    min: 0,
    max: 9
  }
}

Please take a look at the runnable sample below and see how it works when the data is dynamic:

var data = [3, 6, 8, 9, 31];

new Chart('myChart', {
  type: 'bar',
  data: {
    labels: ['A', 'B', 'C', 'D', 'E'],
    datasets: [{
      data: data,
      borderColor: '#00D',
    }]
  },
  options: {
    indexAxis: 'y',
    plugins: {
      legend: {
        display: false
      }
    },
    scales: {
      x: {
        min: 0
      },
      x1: {
        position: 'top',
        min: 0,
        suggestedMax: Math.max(...data)
      }
    }
  }
});
canvas {
  max-height: 180px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.1/chart.min.js"></script>
<canvas id="myChart"></canvas>
uminder
  • 23,831
  • 5
  • 37
  • 72
  • Thanks so much for the responses! That seems like an option, but look at what happens when you change your dataset to ```[1, 3, 6, 8, 31]``` (The original numbers were just an example, but I plan to have dynamic data sets in here so something like this is possible) and set your x1.max to 31. You will then have to define your x.max as well since the bottom will be 35 and your top will be 31. But with 31 being the max for both, it makes the last box be distorted since the max in this case should be 31. I would not like to avoid defining the maxes for this reason. – intrepiddrain Oct 22 '21 at 18:19
  • I just slightly updated my answer to show how you could deal with dynamic data. – uminder Oct 22 '21 at 18:27
  • Thanks, update the data variable to be [1, 3, 6, 8, 31], then you'll see an issue and adjust the x.max to fix the issue. But then you'll see another issue of the last box being distorted, because the max should really be 35 and not 31. Just doesn't seem like chartjs has a good solution for this. – intrepiddrain Oct 22 '21 at 20:05
  • Adding `max: Math.max(...data)` on both x-axes should solve this problem. – uminder Oct 23 '21 at 05:31
  • I updated may answer, now using `suggestedMax: Math.max(...data)` on the `x1` scale. This should produce the expected result. – uminder Aug 14 '22 at 13:54