1

I'm trying to render a LineChart using react-chartjs-2 and chartjs library in react-typescript.

Type Declaration File

export type LineChartOptions = _DeepPartialObject<
    CoreChartOptions<'line'> &
        ElementChartOptions<'line'> &
        PluginChartOptions<'line'> &
        DatasetChartOptions<'line'> &
        ScaleChartOptions<'line'> &
        LineControllerChartOptions
>;

export type LineChartData<T> = ChartData<'line', T>;

LineGraph.tsx

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

interface LineGraphProps {
    options: LineChartOptions;
    data: LineChartData<{ x: string; y: number }[]>;
}

function LineGraph(props: LineGraphProps) {
    return (
        <div className="graph-container-wrapper">
            <Line options={props.options} data={props.data} className="graph-container" />
        </div>
    );
}

export default LineGraph;

SolvedGraph.tsx

function SolvedGraph() {
    return <LineGraph options={options} data={data} />;
}

const options: LineChartOptions = {
  responsive: true,
  plugins: {
      title: {
          display: true,
          text: 'Puzzles solved in previous 15 days',
          color: '#efa238',
          font: {
              size: 16
          }
      },
      legend: {
          display: false
      }
  },
  scales: {
      x: {
          ticks: {
              color: '#efa238'
          },
          border: {
              color: '#efa238'
          },
          grid: {
              display: false
          },
          offset: true
      },
      y: {
          ticks: {
              callback: function (label: string | number, index: number, ticks: Tick[]) {
                  if (Math.floor(Number(label)) === label) {
                      return label;
                  }
              },
              color: '#efa238'
          },
          border: {
              color: '#efa238'
          },
          grid: {
              display: false
          },
          offset: true
      }
  }
};

const dt = [
  { x: '2023-07-25T00:00:00.000Z', y: 2 },
  { x: '2023-07-26T00:00:00.000Z', y: 3 },
  { x: '2023-07-27T00:00:00.000Z', y: 4 },
  { x: '2023-07-28T00:00:00.000Z', y: 0 },
  { x: '2023-07-29T00:00:00.000Z', y: 1 },
  { x: '2023-07-30T00:00:00.000Z', y: 5 },
  { x: '2023-07-31T00:00:00.000Z', y: 4 },
  { x: '2023-08-01T00:00:00.000Z', y: 2 },
  { x: '2023-08-02T00:00:00.000Z', y: 1 },
  { x: '2023-08-03T00:00:00.000Z', y: 3 },
  { x: '2023-08-04T00:00:00.000Z', y: 2 },
  { x: '2023-08-05T00:00:00.000Z', y: 0 },
  { x: '2023-08-06T00:00:00.000Z', y: 4 },
  { x: '2023-08-07T00:00:00.000Z', y: 1 },
  { x: '2023-08-08T00:00:00.000Z', y: 3 }
];

const data: LineChartData<{ x: string; y: number }[]> = {
  datasets: [
      {
          data: dt.map((d) => ({ x: moment(d.x).format('DD MMM'), y: d.y })),
          borderColor: '#9f5a30',
          backgroundColor: '#efa238',
          parsing: {
              xAxisKey: 'x',
              yAxisKey: 'y'
          }
      }
  ]
};

export default SolvedGraph;

When I run the server, it throws an error

Cannot read properties of undefined (reading 'labels')
TypeError: Cannot read properties of undefined (reading 'labels')
    at ChartComponent (http://localhost:3000/static/js/bundle.js:214268:20)
    at renderWithHooks (http://localhost:3000/static/js/bundle.js:126838:22)
    at updateForwardRef (http://localhost:3000/static/js/bundle.js:129409:24)

Also when I declare the options and data in LineGraph.tsx component instead of passing from parent component with the same type, it doesn't throw any error and work completely fine.

Fixed: Generally this error occurred when the empty dataset is passed into chart data. Mistakenly I was initializing the child component first which contains the chart initialization code and the parent component later resulting in empty dataset.

  • @kikon I've already formatted x using moment before passing into dataset, so that shouldn't be the problem. Earlier I've tried using type "time" and adapter but that resulted into parsing error. Data wasn't being able to parse correctly. – localhost_3000 Aug 11 '23 at 13:56
  • @kikon thanks for your input. I got the problem. Who would believe I was directly importing the child component before calling the parent component. Hence the dataset became empty and thrown error. – localhost_3000 Aug 12 '23 at 09:44

0 Answers0