【问题标题】:React Chartjs - Update Chart on intervalReact Chartjs - 间隔更新图表
【发布时间】:2018-10-01 23:39:56
【问题描述】:

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

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

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>
        )
    }
}

【问题讨论】:

    标签: reactjs chart.js settimeout


    【解决方案1】:

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

    因此,在您的代码中,每次您希望图表在其canvas 上重新绘制时,您都可以执行相同的操作。

    为此,您首先需要获取对 Chart.js 实例的引用,如 here 所述。

    constructor() {
      ... 
      this.chartReference = React.createRef(); 
      ...
    }
    
    componentDidMount() {
      this.chart = this.chartReference.current.chartInstance;
      ...
    }
    
    render() {
      return (
        <Bar
          ref={this.chartReference}
          ...
        />
      );
    }
    

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

    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);
    }
    

    请看看这个StackBlitz,看看它是如何工作的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-13
      • 1970-01-01
      • 2018-08-25
      • 1970-01-01
      • 1970-01-01
      • 2013-06-25
      • 1970-01-01
      • 2017-10-15
      相关资源
      最近更新 更多