React Chartjs-更新间隔图表

时间:2018-10-01 23:39:56

标签: reactjs chart.js settimeout

我正在尝试构建一个可视化显示不同排序算法的应用程序。我正在使用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>
        )
    }
}

Before

After

1 个答案:

答案 0 :(得分:0)

我对 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 并了解其工作原理。