Updating Dom on array element swaps for sorting visualiser Vue.JS

209 views Asked by At

Vue noob here who will be most grateful for any advice.

I am trying to build a basic sorting algorithm visualiser that will display an array of integers as a bar chart and my goal is to have the program step through the comparison steps by changing the colors of the two values being compared before swapping them so there will be a slight delay to the user to make them easier to understand.

The issue I am currently having is that I cannot get the DOM to update on the array change. I know that Vue has some limitations when it comes to watching for arrays changes when set by index so I have been using the splice mutation which I understand should resolve it however my screen doesn't get updated until the entire array is sorted.

I have tried utilising setTimeout function to add in a delay incase it was just happening too quickly for me to see but that doesn't appear to resolve anything.

I tried this.$forceUpdate() that I have seen on some other posts but was unsuccessful with that option also. Another post recommended modifying the div to be displayed an hidden so I tried seeing if adding a 'v-if' and then changing the value to false and then back to true to hack it to update but no luck either.

Any help would be amazing. Here is a sample of the code I wrote.

bubbleSort(){

    var is_sorted = false;
    var counter = 0;

    while(!is_sorted){

        is_sorted = true;

        for( let i = 0; i < (this.num_list.length - 1 - counter); i++){
            this.show = false;
            this.index_compare_val_1 = this.num_list[i];
            this.index_compare_val_2 = this.num_list[i +1];
           
            // check if values need to be swapped
            if(this.num_list[i] > this.num_list[i + 1]){
               this.swapNumbersInArray(i, i+1)
               is_sorted = false;
            }
            //this.show = true
            setTimeout(this.show = true, 50)
        }
        counter =+ 1   
    }
   },
   swapNumbersInArray(index_1, index_2){
    var a = this.num_list[index_2] 
    this.num_list.splice(index_2, 1, this.num_list[index_1] );
    this.num_list.splice(index_1, 1, a );

    this.temp_list = this.num_list
    this.num_list = this.temp_list


   },
1

There are 1 answers

0
Steve On

Solved this issue by switching approach by utilising a sleep promise that has a setTimeout and making the sorting algorithm function asynchronous.

It now steps through the animations of the algorithm at a speed that properly visualises the sorting process.

Code Below:

async bubbleSort(){
            console.log("Running Bubble Sort")
            var is_sorted = false;
            var counter = 0;
            while(!is_sorted){
                is_sorted = true;
                for( let i = 0; i < (this.num_list.length - 1 - counter); i++){
                    // set compared values for coloring
                    this.compare_val_1 = this.num_list[i];
                    this.compare_val_2 = this.num_list[i +1];     
                    // check if values need to be swapped
                    if(this.num_list[i] > this.num_list[i + 1]){
                        this.swapNumbersInArray(i, i+1)
                        await this.sleep(5) // short delay so user can see the animation
                        is_sorted = false;
                    }
            }
            counter =+ 1  
            }
        this.sorted = true; // changes color to finalColor
        },



   sleep(ms){
            return new Promise((resolve) => {
            setTimeout(resolve, ms);
            });
        },