Chart.js update() method only works once in the end instead of updating every iteration

…衆ロ難τιáo~ 提交于 2021-01-29 06:07:34

问题


function insertSort(inputArray = myChart.data.datasets[0].data) {
    let inputArrayLength = inputArray.length;
    let outerIndex = 1;
    let innerIndex = 0;
    while(outerIndex<inputArrayLength) {
        innerIndex = outerIndex - 1;
        temp = outerIndex;
        while(innerIndex>=0){
            if (inputArray[temp]<inputArray[innerIndex]){
                inputArray[innerIndex] = [inputArray[temp], inputArray[temp] = inputArray[innerIndex]][0];
                temp = innerIndex;
                innerIndex--;
            } else {
                innerIndex--;
            }
        }
        sleep(1000);
        console.log('Intermediate result is: ', inputArray);
        myChart.data.datasets[0].data = inputArray;
        myChart.update();
        outerIndex++;
    }
    console.log('Final result is: ', inputArray);
    return true;
}
function sleep(milliseconds) {
  console.log('going in sleep');
  const date = Date.now();
  let currentDate = null;
  do {
    currentDate = Date.now();
  } while (currentDate - date < milliseconds);
  console.log('out of sleep');
}
let ctx = document.getElementById('myChart').getContext('2d');
let randomArray = Array.from({length: 10}, () => Math.floor(Math.random() * 10+1));
let myChart = new Chart(ctx, {
    type: 'bar',
    data: {
        labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange', 'Blue', 'Blue', 'Blue', 'Blue'],
        datasets: [{
            label: '# of Votes',
            data: randomArray,
            backgroundColor: [
                'rgba(255, 99, 132, 0.2)',
                'rgba(54, 162, 235, 0.2)',
                'rgba(255, 206, 86, 0.2)',
                'rgba(75, 192, 192, 0.2)',
                'rgba(153, 102, 255, 0.2)',
                'rgba(54, 162, 235, 0.2)',
                'rgba(54, 162, 235, 0.2)',
                'rgba(54, 162, 235, 0.2)',
                'rgba(54, 162, 235, 0.2)',
                'rgba(54, 162, 235, 0.2)'
            ],
            borderWidth: 1
        }]
    },
    options: {
        scales: {
            yAxes: [{
                ticks: {
                    beginAtZero: true
                }
            }]
        }
    }
});
<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

    <title>Hello, world!</title>
  </head>
  <body>
    <h1>Hello, world!</h1>
    <button type="button" onclick="insertSort()">StartSorting</button>
    <canvas id="myChart" width="400" height="400">
    </canvas>
    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.js"></script>
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
  </body>
</html>

I have built a simple insertion sort algorithm in JavaScript, which sorts an array of ten random integers from the smallest to the largest.

  • The result is visualised by using Chart.js library, ten bars of different heights are sorted and updated from the shortest to the tallest.

What I want to achieve now is: visualise each step of this sorting process. I introduced a sleep() function which basically delays the code execution and right after this sleep() function, I call myChart.update() to update the bars. But the result is not what I expected, it turned out that all bars were only updated once by the end of this code execution instead of being updated whenever a sorting step is completed.

Can anyone help? My code can be executed by C&P as a HTML file and run it in Chrome browser. Click startSorting button to have it sorted, and some simple debugging messages are available in the developer console.


回答1:


Your code blocks the UI, hence the console log messages and the updated chart can only be shown once its execution has completed (see https://stackoverflow.com/a/32316972/2358409).

Instead of using your own sleep function, you better use setTimeout in order to schedule individual work portions. Below runnable code illustrates how this could work while the function insertSort was simplified and no longer does what it originally did.

function insertSort(inputArray = myChart.data.datasets[0].data) {
    let inputArrayLength = inputArray.length;
    let outerIndex = 1;
    while(outerIndex<inputArrayLength) {
        setTimeout(() => {           
           myChart.data.datasets[0].data = Array.from({length: 10}, () => Math.floor(Math.random() * 10+1));
           console.log('Intermediate result is: ', myChart.data.datasets[0].data.join(', '));
           myChart.update();
        }, 1000 * outerIndex);
        outerIndex++;
    }
    console.log('Final result is: ', inputArray.join(', '));
    return true;
}

let ctx = document.getElementById('myChart').getContext('2d');
let randomArray = Array.from({length: 10}, () => Math.floor(Math.random() * 10+1));
let myChart = new Chart(ctx, {
    type: 'bar',
    data: {
        labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange', 'Blue', 'Blue', 'Blue', 'Blue'],
        datasets: [{
            label: '# of Votes',
            data: randomArray,
            backgroundColor: [
                'rgba(255, 99, 132, 0.2)',
                'rgba(54, 162, 235, 0.2)',
                'rgba(255, 206, 86, 0.2)',
                'rgba(75, 192, 192, 0.2)',
                'rgba(153, 102, 255, 0.2)',
                'rgba(54, 162, 235, 0.2)',
                'rgba(54, 162, 235, 0.2)',
                'rgba(54, 162, 235, 0.2)',
                'rgba(54, 162, 235, 0.2)',
                'rgba(54, 162, 235, 0.2)'
            ],
            borderWidth: 1
        }]
    },
    options: {
        scales: {
            yAxes: [{
                ticks: {
                    beginAtZero: true
                }
            }]
        }
    }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.js"></script>
<button type="button" onclick="insertSort()">StartSorting</button>
<canvas id="myChart" height="100">


来源:https://stackoverflow.com/questions/60374063/chart-js-update-method-only-works-once-in-the-end-instead-of-updating-every-it

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!