I'm building a dynamic chart using chart.js.
Within componentDidMount, I'm calling getNewData() every second with setInterval.
This updates the data within my dataset, for some reason the chart won't update / re-render when state is updated.
How can I get the chart to update it's points when new data is added?
Component code:
import React, {Component} from 'react';
import { Line } from 'react-chartjs-2';
import 'chartjs-plugin-lineheight-annotation';
import './styles.scss';
export default class SmallCard extends Component {
constructor(props) {
super(props);
this.state = {
data: {
labels: ["1", "2", "3", "4", "5"],
datasets: [
{
label: "Videos Made",
backgroundColor: "rgba(255, 0, 255, 0.75)",
data: [4, 5, 1, 10, 32, 2, 12]
},
{
label: "Subscriptions",
backgroundColor: "rgba(0, 255, 0, 0.75)",
data: [14, 15, 21, 0, 12, 24, 32]
}
]
}
}
}
componentDidMount() {
this.interval = setInterval(() => this.getNewData(), 1000);
}
componentWillUnmount() {
clearInterval(this.interval);
}
getNewData() {
const min = 1;
const max = 10;
const rand = min + Math.floor(Math.random() * (max - min));
this.setState({
data: {
datasets: this.state.data.datasets.map((item, index) => ({
...item,
data: [...this.state.data.datasets[index].data, rand]
}))
}
});
}
setGradientColour = (canvas, colour) => {
const ctx = canvas.getContext('2d');
//console.log("ctx", ctx)
const gradient = ctx.createLinearGradient(0, 0, 0, 400);
gradient.addColorStop(0, colour);
gradient.addColorStop(0.95, "rgba(133, 255, 144, 0.85");
return gradient;
}
getChartData = canvas => {
const { data } = this.state;
if(data.datasets) {
let colors = ["rgba(255, 0, 255, 0.75)", "rgba(0, 255, 0, 0.75)"];
data.datasets.forEach((set, i) => {
set.backgroundColor = this.setGradientColour(canvas, colors[i]);
set.borderColor = "white";
set.borderWidth = 2;
})
}
return data;
}
render() {
const data = this.state.data.datasets[1].data;
console.log("data", data)
return (
<div className="small-card-wrap">
<Line
options={{
responsive: true,
lineHeightAnnotation: {
always: false,
hover: true,
color: 'white',
noDash: true
}
}}
data={this.getChartData} />
</div>
)
}
}