javascriptjquerysortingvisualizer

How to create real-time changes in JavaScript


So I wrote a pretty basic code. I'm a real noob. Started JavaScript 3 days back. I want the sorting process to be visualized while the sorting is going on. But when the SORT button is clicked after a while the sorted array is show. But what I want is to show the changes happening to the array in real-time. Please help me out.

var array = [];
container_content= "";
for (var i=0; i < 50; i++) {
    array.push(Math.random() *500)
} 

container_content = "";

function myFunction(element) {
    container_content += '<div class="array-bar"></div>';
}
array.forEach(myFunction);
$(".container").html(container_content);

function another(element, index){
    element.style.height = array[index]
}
$( "div" ).each( function( index, element ){
    $( this ).css('height', array[index]);
});

$('button').click(function(){
    var i, j, temp;
    for(i = 0; i < array.length; i++)
    {
        for(j = 0; j < array.length-1; j++)
        {
            if( array[j] > array[j+1])
            {
                // swap the elements
                temp = array[j];
                array[j] = array[j+1];
                array[j+1] = temp;
            } 
        }
            $( "div" ).each( function( index, element ){
            $( this ).css('height', array[index]);
            });

    }

})

Solution

  • I took what you were trying to do and broke it down into 4 basic functions (1 main function and 3 helper functions).

    runSort is the main function that uses all the other helper functions to do everything.

    makeArrayAndUnsyncedBars generates your random array and basic divs that you'll use as green "bars", but it doesn't set the heights of these divs according to the values in the array.

    syncArrayToBars sets the heights of these "bar" divs according to the values in the array

    sortUntilNextSwap sorts the array until either a swap occurs or the sort completes. this function returns false if it made a swap (meaning that it's still working its way through the array) or true otherwise.

    var FRAMES_PER_SECOND = 50;
    
    var sortInterval = null;
    function runSort() {
      clearInterval(sortInterval);
    
      makeArrayAndUnsyncedBars(50);
      syncArrayToBars();
    
      sortInterval = setInterval(function() {
        var finishedSorting = sortUntilNextSwap();
        syncArrayToBars();
    
        if (finishedSorting) clearInterval(sortInterval);
      }, Math.round(1000 / FRAMES_PER_SECOND));
    }
    
    var array = [];
    function makeArrayAndUnsyncedBars(numberOfValues) {
      var htmlToAdd = "";
      array = [];
      for (var i = 0; i < numberOfValues; i++) {
        htmlToAdd += "<div class=\"bar\"></div>";
        array.push(rando(150));
      }
      $("#bars").html(htmlToAdd);
    }
    
    function syncArrayToBars() {
      for (var i = 0; i < array.length; i++) $(".bar").eq(i).css({
        height: array[i] + "px"
      });
    }
    
    var i, j, temp;
    function sortUntilNextSwap() {
      for (i = 0; i < array.length; i++) {
        for (j = 0; j < array.length - 1; j++) {
          if (array[j] > array[j + 1]) {
            // swap the elements
            temp = array[j];
            array[j] = array[j + 1];
            array[j + 1] = temp;
            return false;
          }
        }
      }
      return true;
    }
    .bar {
      width: 5px;
      background: #5aedab;
      border-radius: 3px;
      display: inline-block;
      margin: 0px 3px;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://randojs.com/1.0.0.js"></script>
    <div id="bars"></div>
    <button onclick="runSort();">Run sort</button>

    EDIT: I should mention that I used rando.js for the randomness out of habit, but it's not super necessary here given that you use Math.random() very little anyway. Take it out or leave it in according to your preference.