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;