Search code examples
reactjschart.jsbar-chartcodepen

Two Y axis Barchart in ChartJS


I have create a two Y-axis barchart, the data and axis display correctly, however, the two axis are both positioned to the left of the plot. I put the position for the two Y axes but I don't know why it doesn't work. Here is the chart component in Codepen.

https://codepen.io/benmhamed/pen/mdzJKaq?editors=0010

 yAxes: [
                    {
                        id: "y-axis-1",
                        position: "left",
                        ticks: {
                            maxTicksLimit: 5,
                            callback: (value) => formatValue(value)/1000 + "K (units)",
                        },
                    },
                    {
                        id: "y-axis-2",
                        position: "right",
                        ticks: {
                            maxTicksLimit: 5,
                            callback: (value) => formatValue(value) + "M ($)",
                        },
                    },

Solution

  • Your axes configuration seems to follow the format from an older version of charts.js. The main change has to be that the in the options, scales is an object (not an array), and each individual axis will appear under its id as a key:

    {
       options:{
          scales:{
             "y-axis-1": {
             // ...........
             },
             "y-axis-2": {
             // ...........
             },
             x: {
             // ...........
             }
          }
       }
    }
    

    Here's a simplified version of your code for illustration purposes, non-react, with function that were not defined excluded, with invented data and category x axis rather than time:

    const ctx = document.getElementById('myChart'),
        container = ctx.parentElement;
    
    new Chart(ctx, {
        type: 'bar',
        data: {
            labels: ['q','w','e','r'],
            datasets: [
                {
                    label: 'Sales (in units)',
                    data: [1100, 2200, 3300, 4400],
                    yAxisID: "y-axis-1",
                    //backgroundColor: tailwindConfig().theme.colors.blue[400],
                    //hoverBackgroundColor: tailwindConfig().theme.colors.blue[500],
                    barPercentage: 0.66,
                    categoryPercentage: 0.66,
                },
                {
                    label: 'Spend (million USD)',
                    data: [3, 2, 4, 1],
                    yAxisID: "y-axis-2",
                    //backgroundColor: tailwindConfig().theme.colors.indigo[500],
                    //hoverBackgroundColor: tailwindConfig().theme.colors.indigo[600],
                    barPercentage: 0.66,
                    categoryPercentage: 0.66,
                }
            ]
        },
        options: {
            layout: {
                padding: {
                    top: 12,
                    bottom: 16,
                    left: 70,
                    right: 70
                },
            },
            scales: {
                "y-axis-1": {
                    //id: "y-axis-1",
                    type: "linear",
                    position: "left",
                    ticks: {
                        maxTicksLimit: 5,
                        callback: (value) => /*formatValue*/(value)/1000 + "K (units)",
                    },
                },
                "y-axis-2": {
                    //id: "y-axis-2",
                    type: "linear",
                    position: "right",
                    ticks: {
                        maxTicksLimit: 5,
                        callback: (value) =>  /*formatValue*/(value) + "M ($)",
                    },
                },
                x: {
                    /*  type: 'time',
                     time: {
                         parser: 'MM-DD-YYYY',
                         unit: 'month',
                         displayFormats: {
                             month: 'MMM YY',
                         },
                     }, */
                    grid: {
                        display: false,
                        drawBorder: false,
                    },
                    position: 'bottom'
                },
            },
            plugins: {
                legend: {
                    display: true,
                },
                tooltip: {
                    callbacks: {
                        title: () => false, // Disable tooltip title
                        label: (context) => /*formatValue*/(context.parsed.y),
                    },
                },
            },
            interaction: {
                intersect: false,
                mode: 'nearest'
            },
            animation: {
                duration: 500
            },
            maintainAspectRatio: false,
            resizeDelay: 200,
        },
    });
    <div style="position: relative; min-height:300px; width: 90vw" >
        <canvas id="myChart"></canvas>
    </div>
    
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>