0

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>
        )
    }
}
2
  • What does the console log says? Is the new data in the console? Commented Nov 7, 2019 at 16:27
  • Yes new data successfully within console. Commented Nov 7, 2019 at 16:29

1 Answer 1

1

getNewData is not bound to the class context, so the setState will fail. you can use an arrow function so it will inherit the enclosing one.

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]
                }))
            }
        });
    }
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.