Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

ChartJS : How to display two "y axis" scales on a chart

I have a chart that shows various data points.
Some of these data points are high numbers and some are low numbers.

The low numbers (visits) I can scale to a different scale and this new scale can be put on the "X" axis (It’s the "Y" axis and then rotated 90degrees). But the problem is:

  • The grid remains even when removed
  • The

How can I extrapolate the poistion on the graph without adjusting the label data on hover?2 I have search Stackoverflow and ChartJS documentation but can’t see how this can be done.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel


I was trying to use the "other" axis (in this case the top horizontal bar of the chart) so that the scale would be relative and raw data editing would not be needed but I can’t get that to work and can’t find documentation on this. I’m sure it’s possible but I can’t see how where.

I have found this question but this related only to ChartJS V2 .

Current version used is ChartJS 3.2.1

Original Version:

    var ctx = document.getElementById("historicChart");
    var historicChart = new Chart(ctx, {
            type: "horizontalBar",
            data: {
                labels: [2022,2021,2020,2019,2018,2017,2016],
                datasets: [
                    {
                        type: 'line',
                        label: 'Visits',
                        data: ["1","7","493","163","467","88","48"],
                        backgroundColor: '#FFC900',
                        pointBackgroundColor: '#FFC900',
                        pointRadius: 8,
                        pointStyle: 'circle',
                        showLine: false,
                        order: 1,
                        hoverRadius: 10
                    },
                    {
                        type: 'bar',
                        label: 'Applied',
                        data: ["486","800","704","1084","532","618","543"],
                        backgroundColor: '#436BFF',
                        borderWidth: 0,
                        order: 2,
                        barPercentage: 0.9,
                        stack: 'stack 0',
                    },
                    {
                        type: 'bar',
                        label: 'Accepted',
                        data: ["1","147","290","521","233","306","271"],
                        backgroundColor: '#C40500',
                        borderWidth: 0,
                        barPercentage: 0.9,
                        stack: 'stack 1',
                        order: 4
                    },
                    {
                        type: 'bar',
                        label: 'Declined',
                        data: ["616","4273","3998","3400","922","1225","1184"],
                        /*backgroundColor: '#03570c', /* emerald */
                        backgroundColor: '#006545', /* jade */
                        borderWidth: 0,
                        barPercentage: 0.9,
                        stack: 'stack 0',
                        order: 5
                    },
                    {
                        type: 'bar',
                        label: 'Processing',
                        data: ["6","13","22","1","34","2","1"],
                        backgroundColor: '#65ccD3', /* aqua + blue */
                        borderWidth: 0,
                        barPercentage: 0.9,
                        stack: 'stack 0',
                        order: 3
                    },
                ]
            },
            options: {
                responsive: true,
                interaction: {
                    intersect: false,
                    mode: 'index',
                    axis: 'y'
                },
                indexAxis: 'y',
                scales: {
                    xAxes: [{
                        stacked: true,
                        ticks: {
                            stepSize: 1
                        },
                        beginAtZero: true
                    }],
                    yAxes: [{
                        stacked: true
                    }]
                }
            }
        }
    );
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.2.1/chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

   <canvas id="historicChart"></canvas>

UPDATE:

I have tried to add a custom secondary axis as per this example from the CHartJS documentation, but it doesn’t quite do as I need; the grid lines remain and the axis scale is on the "wrong" side (two scales on one size (bottom) and zero scales on the other side (top)

var ctx = document.getElementById("historicChart");
    var historicChart = new Chart(ctx, {
            type: "horizontalBar",
            data: {
                labels: [2022,2021,2020,2019,2018,2017,2016],
                datasets: [
                    {
                        type: 'line',
                        label: 'Visits',
                        data: ["1","7","493","163","467","88","48"],
                        backgroundColor: '#FFC900',
                        pointBackgroundColor: '#FFC900',
                        pointRadius: 8,
                        pointStyle: 'circle',
                        showLine: false,
                        order: 1,
                        hoverRadius: 10,
                        xAxisID:'xTwo'
                    },
                    {
                        type: 'bar',
                        label: 'Applied',
                        data: ["486","900","724","1084","532","618","543"],
                        backgroundColor: '#436BFF',
                        borderWidth: 0,
                        order: 2,
                        barPercentage: 0.9,
                        stack: 'stack 0',
                    },
                    {
                        type: 'bar',
                        label: 'Accepted',
                        data: ["1","147","290","511","253","306","271"],
                        backgroundColor: '#C40500',
                        borderWidth: 0,
                        barPercentage: 0.9,
                        stack: 'stack 1',
                        order: 4
                    },
                    {
                        type: 'bar',
                        label: 'Declined',
                        data: ["616","4373","3998","3400","922","1205","1184"],
                        /*backgroundColor: '#03570c', /* emerald */
                        backgroundColor: '#006545', /* jade */
                        borderWidth: 0,
                        barPercentage: 0.9,
                        stack: 'stack 0',
                        order: 5
                    },
                    {
                        type: 'bar',
                        label: 'Processing',
                        data: ["6","23","22","1","4","2","1"],
                        backgroundColor: '#65ccD3', /* aqua + blue */
                        borderWidth: 0,
                        barPercentage: 0.9,
                        stack: 'stack 0',
                        order: 3
                    },
                ]
            },
            options: {
                responsive: true,
                interaction: {
                    intersect: false,
                    mode: 'index',
                    axis: 'y'
                },
                indexAxis: 'y',
                scales: {
                    xAxes: [{
                        stacked: true,
                        ticks: {
                            stepSize: 1
                        },
                        beginAtZero: true
                    }],
                    yAxes: [{
                        stacked: true
                    }],
                    xTwo: [{
                        type: 'linear',
                        display: true,
                        position: 'top',
                        grid: {
                            display: false,
                            drawOnChartArea: false,
                            ticks: {
                                display: false
                            }
                        }
                    }]
                }
            }
        }
    );
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.2.1/chart.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

       <canvas id="historicChart"></canvas>

The issue appears to be with the scale; "xTwo";

     xTwo: [{
           type: 'linear',
           display: true,
           position: 'top',
           grid: {
                 display: false,
                 drawOnChartArea: false,
                 ticks: {
                 /* trying to even just hide the ticks here fails */
                         display: false,
                 }
           }
     }]

How can I fix this to hide the grid lines and put the scale on the correct side of the graph?

>Solution :

You can use a custom label callback for this in the tooltip config, also your scale config was wrong. It was in V2 style. For all changes please read the migration guide

var ctx = document.getElementById("historicChart");
var historicChart = new Chart(ctx, {
  type: "horizontalBar",
  data: {
    labels: [2022, 2021, 2020, 2019, 2018, 2017, 2016],
    datasets: [{
        type: 'line',
        label: 'Visits',
        data: ["5", "35", "2465", "815", "2335", "440", "240"],
        backgroundColor: '#FFC900',
        pointBackgroundColor: '#FFC900',
        pointRadius: 8,
        pointStyle: 'circle',
        showLine: false,
        order: 1,
        hoverRadius: 10
      },
      {
        type: 'bar',
        label: 'Applied',
        data: ["486", "800", "704", "1084", "532", "618", "543"],
        backgroundColor: '#436BFF',
        borderWidth: 0,
        order: 2,
        barPercentage: 0.9,
        stack: 'stack 0',
      },
      {
        type: 'bar',
        label: 'Accepted',
        data: ["1", "147", "290", "521", "233", "306", "271"],
        backgroundColor: '#C40500',
        borderWidth: 0,
        barPercentage: 0.9,
        stack: 'stack 1',
        order: 4
      },
      {
        type: 'bar',
        label: 'Declined',
        data: ["616", "4273", "3998", "3400", "922", "1225", "1184"],
        /*backgroundColor: '#03570c', /* emerald */
        backgroundColor: '#006545',
        /* jade */
        borderWidth: 0,
        barPercentage: 0.9,
        stack: 'stack 0',
        order: 5
      },
      {
        type: 'bar',
        label: 'Processing',
        data: ["6", "13", "22", "1", "34", "2", "1"],
        backgroundColor: '#65ccD3',
        /* aqua + blue */
        borderWidth: 0,
        barPercentage: 0.9,
        stack: 'stack 0',
        order: 3
      },
    ]
  },
  options: {
    responsive: true,
    interaction: {
      intersect: false,
      mode: 'index',
      axis: 'y'
    },
    indexAxis: 'y',
    plugins: {
      tooltip: {
        callbacks: {
          label: (ttItem) => {
            const label = ttItem.dataset.label;
            const val = Number(ttItem.raw);

            let res = `${label}: ${label === 'Visits' ? val / 5 : val}`;
            return res
          }
        }
      }
    },
    scales: {
      x: {
        stacked: true,
        ticks: {
          stepSize: 1
        },
        beginAtZero: true
      },
      y: {
        stacked: true
      }
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.2.1/chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<canvas id="historicChart"></canvas>

UPDATE:
You tried adding a second scale, in chart.js V3 all scales are their own objects and not arrays anymore, for all changes see migration guide linked above. Changing the scales to objects fixes your issue in your updated approach without needing to multiply values :

var ctx = document.getElementById("historicChart");
var historicChart = new Chart(ctx, {
  type: "horizontalBar",
  data: {
    labels: [2022, 2021, 2020, 2019, 2018, 2017, 2016],
    datasets: [{
        type: 'line',
        label: 'Visits',
        data: ["1", "7", "493", "163", "467", "88", "48"],
        backgroundColor: '#FFC900',
        pointBackgroundColor: '#FFC900',
        pointRadius: 8,
        pointStyle: 'circle',
        showLine: false,
        order: 1,
        hoverRadius: 10,
        xAxisID: 'xTwo'
      },
      {
        type: 'bar',
        label: 'Applied',
        data: ["486", "900", "724", "1084", "532", "618", "543"],
        backgroundColor: '#436BFF',
        borderWidth: 0,
        order: 2,
        barPercentage: 0.9,
        stack: 'stack 0',
      },
      {
        type: 'bar',
        label: 'Accepted',
        data: ["1", "147", "290", "511", "253", "306", "271"],
        backgroundColor: '#C40500',
        borderWidth: 0,
        barPercentage: 0.9,
        stack: 'stack 1',
        order: 4
      },
      {
        type: 'bar',
        label: 'Declined',
        data: ["616", "4373", "3998", "3400", "922", "1205", "1184"],
        /*backgroundColor: '#03570c', /* emerald */
        backgroundColor: '#006545',
        /* jade */
        borderWidth: 0,
        barPercentage: 0.9,
        stack: 'stack 0',
        order: 5
      },
      {
        type: 'bar',
        label: 'Processing',
        data: ["6", "23", "22", "1", "4", "2", "1"],
        backgroundColor: '#65ccD3',
        /* aqua + blue */
        borderWidth: 0,
        barPercentage: 0.9,
        stack: 'stack 0',
        order: 3
      },
    ]
  },
  options: {
    responsive: true,
    interaction: {
      intersect: false,
      mode: 'index',
      axis: 'y'
    },
    indexAxis: 'y',
    scales: {
      x: {
        stacked: true,
        ticks: {
          stepSize: 1000
        },
        beginAtZero: true
      },
      y: {
        stacked: true
      },
      xTwo: {
        type: 'linear',
        display: true,
        position: 'top',
        grid: {
          display: false,
          ticks: {
            display: false
          }
        }
      }
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.2.1/chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<canvas id="historicChart"></canvas>
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading