1

I currently have a dynamic graph that updates with the redux state in my react application, but after updating React to 18.0 I have run into a issue with react-chartjs-2 that is telling me I need to destroy the canvas before rendering a new chart.

I found some sources on other posts and blogs but they were all aimed at class components for the graph, and I am using a functional component. Is the only solution to this problem to render it as a class component or can it be rendered with a functional component?

Here is my component:

import { Typography } from "@mui/material";
import { Line } from "react-chartjs-2";
import { useSelector } from "react-redux";
import { selectSensorGraph } from "../../redux/slices/robotSlice";

const data = [
  50, 65, 85, 65, 45, 25, 0, -15, -25, -10, 35, 65, 85, 65, 45, 25, 0, -15, -5,
  -10,
];
const borderColours = data.map((value) =>
  value < 0.1 ? "rgb(0, 157, 255)" : "rgb(255, 0, 0)"
);

function SensorGraph() {
  const graph_data = useSelector(selectSensorGraph);

  try {
    var label_list = [];
    var data_list = [];
    graph_data["data"].forEach((row) => {
      var date = new Date(row["Timestamp"] * 1000);
      var hours = date.getHours();
      var minutes = (date.getMinutes() < 10 ? "0" : "") + date.getMinutes();
      label_list.push(`${hours}:${minutes}`);
      data_list.push(row[graph_data["sensor"]]["value"]);
    });
  } catch (err) {
    console.log(`Error: ${err}`);
  }

  const graphHeader = () => {
    if (graph_data["sensor"].includes("Speed")) {
      return "Speed in RPM";
    } else if (graph_data["sensor"].includes("Temp")) {
      return "Temperature in °C";
    } else if (graph_data["sensor"].includes("Torque")) {
      return "Torque in N*m";
    }
  };

  const chartData = {
    labels: label_list,
    datasets: [
      {
        label: graphHeader(),
        data: data_list,
        borderWidth: 5,
        // borderColor: borderColours,
        fill: {
          target: "origin",
          above: "rgb(255, 0, 0, 0.5)",
          below: "rgb(0, 157, 255, 0.5)",
        },
        pointBorderWidth: 2,
        pointBackgroundColor: borderColours,
      },
    ],
  };

  const options = {
    scales: {
      yAxes: [
        {
          ticks: {
            beginAtZero: true,
            max: 100,
            min: -100,
          },
        },
      ],
    },
    animation: {
      duration: 0,
    },
  };

  return (
    <>
      {data_list.length >= 1 ? (
        <Line data={chartData} options={options} />
      ) : (
        <Typography>No sensor data</Typography>
      )}
    </>
  );
}

export default SensorGraph;
Blademaster680
  • 202
  • 2
  • 8

0 Answers0