React Chartjs - 间隔更新图表 [英] React Chartjs - Update Chart on interval

查看:26
本文介绍了React Chartjs - 间隔更新图表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试构建一个可以直观地显示不同排序算法的应用程序.我正在使用 react 和 react-chartjs-2.渲染和更新工作完美,我对数据进行洗牌没有问题,然后在算法运行完成后更新图表.

但是,我似乎无法在排序过程中更新它.每当发生交换时,我都会尝试更新状态.

import React, { Component } from 'react';从'react-chartjs-2'导入{栏};导出默认类 BarChart 扩展组件 {构造函数(道具){超级(道具);这个.state = {数据: {标签:this.createLabels(),数据集:[{标签:'冒泡排序',数据:this.createData(),背景颜色:this.createBg()}]}}}创建数据(){常量数据 = [];for (让 i = 0; i <10; i++) {数据[i] = Math.floor(Math.random() * 1000) + 1;}返回数据;}创建标签(){常量标签 = [];for (让 i = 0; i <10; i++) {标签[i] = `标签 ${i}`;}返回标签;}createBg() {常量颜色 = [];for (让 i = 0; i <10; i++) {//生成颜色const red = Math.floor(Math.random() * 255) + 1;常量绿色 = Math.floor(Math.random() * 255) + 1;const blue = Math.floor(Math.random() * 255) + 1;颜色[i] = `rgba(${red}, ${green}, ${blue}, 0.5)`;}返回颜色;}更新() {//创建数据集的副本const datasetsCopy = this.state.data.datasets.slice(0);const dataCopy = datasetsCopy[0].data.slice(0);//用随机值更新图表数据for (让 i = 0; i < dataCopy.length; i++) {dataCopy[i] = Math.floor(Math.random() * (100 - 10 + 1)) + 10;}//设置复制的更新数据集datasetsCopy[0].data = dataCopy;//更新图表的数据状态这个.setState({数据:Object.assign({},this.state.data,{数据集:数据集复制})});}组件DidMount() {设置超时(() => {this.bubbleSort();}, 1000);}组件WillUnmount() {clearInterval(this.timer)}气泡排序(){//创建数据集的副本const datasetsCopy = this.state.data.datasets.slice(0);const dataCopy = datasetsCopy[0].data.slice(0);//用随机值更新图表数据让 temp1 = 0;让 temp2 = 0;让计时器 = 100;for (让 i = 0; i < dataCopy.length - 1; i++) {for (让 j = 0; j < dataCopy.length - i - 1; j++) {if (dataCopy[j] > dataCopy[j + 1]) {计时器+= 100;this.timer = setTimeout(() =>{temp1 = 数据复制[j];temp2 = 数据复制[j + 1];//交换数据复制[j] = temp2;数据复制[j + 1] = temp1;//设置复制的更新数据集datasetsCopy[0].data = dataCopy;//更新图表的数据状态这个.setState({数据:Object.assign({},this.state.data,{数据集:数据集复制})});}, 定时器)}}}}使成为() {返回 (

<酒吧数据={this.state.data}宽度={100}高度={500}选项={{保持纵横比:假}}/></div>)}}

解决方案

我对 React 了解不多,但我知道 react-chartjs-2Chart.js 的包装器.直接使用 Chart.js 时,更新图表的首选方法是在图表数据或其选项发生更改后调用 chart.update().

因此,在您的代码中,每次您希望在其 canvas 上重新绘制图表时,您都可以这样做.

为此,您首先需要按照说明获取对 Chart.js 实例的引用 这里.

constructor() {...this.chartReference = React.createRef();...}组件DidMount() {this.chart = this.chartReference.current.chartInstance;...}使成为() {返回 (<酒吧ref={this.chartReference}.../>);}

然后您的 bubbleSort 方法可以拆分为以下单独的方法,它应该可以按预期工作.

bubbleSort() {让数据 = this.chart.data.datasets[0].data;让交换;让超时 = 0;做 {交换=假;for (让 i = 0; i < data.length; i++) {如果(数据[i] > 数据[i + 1]){让 tmp = 数据[i];数据[i] = 数据[i + 1];数据[i + 1] = tmp;超时 += 100;this.updateChartDelayed(data.slice(0), timeout);交换=真;}}} 而(交换);}updateChartDelayed(数据,超时){this.timer = setTimeout(() => {this.chart.data.datasets[0].data = 数据;this.chart.update();}, 暂停);}

请看一下这个 StackBlitz 看看它是如何工作的.

I am trying to build an application that visually displays different sorting algorithms. I am using react and react-chartjs-2. The render and update work perfectly and I have no problem shuffling the data, then update the chart AFTER the algorithm is done running.

However, I can't seem to update it during the sorting. I am trying to update state whenever a swap occurs.

import React, { Component } from 'react';
import { Bar } from 'react-chartjs-2';

export default class BarChart extends Component {
      constructor(props) {
        super(props);
        this.state = {
            data: {
                labels: this.createLabels(),
                datasets: [
                    {
                        label: 'Bubble Sort',
                        data: this.createData(),
                        backgroundColor: this.createBg()
                    }
                ]
            }
        }
    }

    createData() {
        const data = [];
        for (let i = 0; i < 10; i++) {
            data[i] = Math.floor(Math.random() * 1000) + 1;
        }

        return data;
    }

    createLabels() {
        const labels = [];
        for (let i = 0; i < 10; i++) {
            labels[i] = `Label ${i}`;
        }

        return labels;
    }

    createBg() {
        const colors = [];
        for (let i = 0; i < 10; i++) {
            // generate colors
            const red = Math.floor(Math.random() * 255) + 1;
            const green = Math.floor(Math.random() * 255) + 1;
            const blue = Math.floor(Math.random() * 255) + 1;
            colors[i] = `rgba(${red}, ${green}, ${blue}, 0.5)`;
        }

        return colors;
    }

    update() {
        // create copy of dataset
        const datasetsCopy = this.state.data.datasets.slice(0);
        const dataCopy = datasetsCopy[0].data.slice(0);

        // update chartdata with random values
        for (let i = 0; i < dataCopy.length; i++) {
            dataCopy[i] = Math.floor(Math.random() * (100 - 10 + 1)) + 10;
        }

        // set copied updated dataset
        datasetsCopy[0].data = dataCopy;

        // update data state of chart
        this.setState({
            data: Object.assign({}, this.state.data, {
                datasets: datasetsCopy
            })
        });
    }

    componentDidMount() {
        setTimeout(() => {
            this.bubbleSort();
        }, 1000);
    }

    componentWillUnmount() {
        clearInterval(this.timer)
    }

    bubbleSort() {

        // create copy of dataset
        const datasetsCopy = this.state.data.datasets.slice(0);
        const dataCopy = datasetsCopy[0].data.slice(0);

        // update chartdata with random values
        let temp1 = 0;
        let temp2 = 0;
        let timer = 100;
        for (let i = 0; i < dataCopy.length - 1; i++) {
            for (let j = 0; j < dataCopy.length - i - 1; j++) {
                if (dataCopy[j] > dataCopy[j + 1]) {
                    timer += 100;
                    this.timer = setTimeout(
                        () => {

                            temp1 = dataCopy[j];
                            temp2 = dataCopy[j + 1];

                            // swap
                            dataCopy[j] = temp2;
                            dataCopy[j + 1] = temp1;

                            // set copied updated dataset
                            datasetsCopy[0].data = dataCopy;

                            // update data state of chart
                            this.setState({
                                data: Object.assign({}, this.state.data, {
                                    datasets: datasetsCopy
                                })
                            });
                        }
                        , timer
                    )
                }
            }
        }
    }

    render() {

        return (
            <div>
                <Bar
                    data={this.state.data}
                    width={100}
                    height={500}
                    options={{
                        maintainAspectRatio: false
                    }}
                />
            </div>
        )
    }
}

解决方案

I don't know much about React but I know that react-chartjs-2 is a wrapper for Chart.js. When using Chart.js directly, the preferred method to update a chart is to invoke chart.update() once the chart data or its options have changed.

Therefore, in your code, your could do the same each time you want the chart be re-drawn on its canvas.

To do so, you first need to obtain a reference to the Chart.js instance as explained here.

constructor() {
  ... 
  this.chartReference = React.createRef(); 
  ...
}

componentDidMount() {
  this.chart = this.chartReference.current.chartInstance;
  ...
}

render() {
  return (
    <Bar
      ref={this.chartReference}
      ...
    />
  );
}

Your bubbleSort method could then be split into the following separate methods and it should work as expected.

bubbleSort() {
  let data = this.chart.data.datasets[0].data;
  let swapped;
  let timeout = 0;
  do {
    swapped = false;
    for (let i = 0; i < data.length; i++) {
      if (data[i] > data[i + 1]) {
        let tmp = data[i];
        data[i] = data[i + 1];
        data[i + 1] = tmp;
        timeout += 100;
        this.updateChartDelayed(data.slice(0), timeout);
        swapped = true;
      }
    }
  } while (swapped);
}

updateChartDelayed(data, timeout) {
  this.timer = setTimeout(() => {
    this.chart.data.datasets[0].data = data;
    this.chart.update();
  }, timeout);
}

Please take a look at this StackBlitz and see how it works.

这篇关于React Chartjs - 间隔更新图表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆