Jeff Froula
Jeff Froula

Reputation: 13

how to get multiple x-axis labels for a react-chartjs-2 chart

Does anyone know how to get multiple x-Axes labels in a react-chartjs-2 chart? I see several examples where people are using chart.js but not react-chartjs-2. I suspect react-chartjs-2 may behave slightly differently when it comes to options.scales.xAxes.

I'm using chart.js v3.6.1 & react-chartjs-2 v4.0.0

I found an example using chart.js, but not react-chartjs-2, that represents what I want. The below code I adapted to use react-chartjs-2. The label's don't display properly even though I didn't alter the "options" or "dataset" from the original working example.

import React from 'react'
import { Bar } from 'react-chartjs-2';
import 'chart.js/auto';
import { Chart } from 'react-chartjs-2';

const TaskProgress3 = () => {
    const data = {
      labels: ["January;2015", "February;2015", "March;2015", "January;2016", "February;2016", "March;2016"],
      datasets: [{
        id: 1,
        label: '# of Votes',
        xAxisID:'xAxis1',
        data: [12, 19, 3, 5, 2, 3]
      }]
    };

    const options = {
      scales:{
        xAxes:[
          {
            id:'xAxis1',
            type:"category",
            ticks:{
              callback:function(label){
                var month = label.split(";")[0];
                return month;
              }
            }
          },
          {
            id:'xAxis2',
            type:"category",
            gridLines: {
              drawOnChartArea: false,
            },
            ticks:{
              callback:function(label){
                var month = label.split(";")[0];
                var year = label.split(";")[1];
                if(month === "February"){
                  return year;
                }else{
                  return "";
                }
              }
            }
          }],
        yAxes:[{
          ticks:{
            beginAtZero:true
          }
        }]
      }
    };

    return (
        <>
        <div>Bar Chart</div>
        <Bar
          datasetIdKey='id'
          data={data}
          options={options}
          height="100px"
          width="600px"
          />
        </>
    )
}

export default TaskProgress3;

Upvotes: 1

Views: 15041

Answers (2)

Andy
Andy

Reputation: 5414

You need to give each dataset a xAxisID in the dataset, so you can define the position of it and how it displays.

Here's an example

import React from 'react';
import {
  Chart as ChartJS,
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  Title,
  Tooltip,
  Legend,
} from 'chart.js';
import { Line } from 'react-chartjs-2';
import faker from 'faker';

ChartJS.register(
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  Title,
  Tooltip,
  Legend
);

export const options = {
  responsive: true,
  plugins: {
    legend: {
      position: 'top' as const,
    },
    title: {
      display: true,
      text: 'Chart.js Line Chart - Multiple X Axes',
    },
  },
  scales: {
    x1: {
      position: 'top',
      ticks: {
        callback: function(value, index, values) {
          return this.getLabelForValue(value).split(';')[1];
        }
      }
    },
    x2: {
      position: 'bottom',
      ticks: {
        callback: function(value, index, values) {
          return this.getLabelForValue(value).split(';')[0];
        }
      }
    }
  }
};

const labels = ["January;2015", "February;2015", "March;2015", "January;2016", "February;2016", "March;2016"];

export const data = {
  labels,
  datasets: [
    {
      label: 'Red Dataset',
      data: labels.map(() => faker.datatype.number({ min: -1000, max: 1000 })),
      borderColor: 'rgb(255, 99, 132)',
      backgroundColor: 'rgba(255, 99, 132, 0.5)',
      xAxisID: 'x1'
    },
    {
      label: 'Blue Dataset',
      data: labels.map(() => faker.datatype.number({ min: -1000, max: 1000 })),
      borderColor: 'rgb(53, 162, 235)',
      backgroundColor: 'rgba(53, 162, 235, 0.5)',
      xAxisID: 'x2'
    },
  ],
};

export function App() {
  return <Line options={options} data={data} />;
}

Upvotes: 1

LeeLenalee
LeeLenalee

Reputation: 31431

This is because you are using V2 syntax in V3, V3 has some major breaking changes. Please read the migration guide for all of them.

In v3 all scales are their own object where the object key is the scale ID

var options = {
  type: 'line',
  data: {
    labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
    datasets: [{
        label: '# of Votes',
        data: [12, 19, 3, 5, 2, 3],
        borderColor: 'orange'
      },
      {
        label: '# of Points',
        data: [7, 11, 5, 8, 3, 7],
        borderColor: 'pink'
      }
    ]
  },
  options: {
    scales: {
      x: {
        ticks: {
          callback: function(label) {
            return `\$${this.getLabelForValue(label)}`
          }
        }
      },
      secondXAxis: {
        axis: 'x',
        labels: ['V2', 'syntax', 'in', 'v3'],
        grid: {
          drawOnChartArea: false
        }
      }
    }
  }
}

var ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
  <canvas id="chartJSContainer" width="600" height="400"></canvas>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.6.0/chart.js"></script>
</body>

Upvotes: 3

Related Questions