我正在尝试构建一个可视化显示不同排序算法的应用程序。我正在使用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>
)
}
}
答案 0 :(得分:0)
我对 React 了解不多,但我知道 react-chartjs-2 是 Chart.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 并了解其工作原理。