Визуализация алгоритмов сортировки

Я пытаюсь визуализировать алгоритмы сортировки, используя d3.js, но я немного застрял. Когда я пытаюсь перерисовать графики, включив в них цикл сортировки. график показывает только окончательное значение. То же самое произошло после использования функции setInterval. Я включил сценарий без всех функций таймера ниже (не включал функцию settime)

var arr = new Array(10, 34, 66, 3, 56, 45, 67, 43, 45, 7);
var wi = 500;
var he = 500;
var temp = 0;

//Scaling
var canvas = d3.select("body")
  .append("svg")
  .attr("width", wi)
  .attr("height", he);

for (l = 9; l > 0; l--) {

    for( p=0;p<l; p++){
                      if(arr[p]>arr[p+1]){
                          swap(p,arr);
                       
                                 
                         }
                      
                  }
  updatevisualization(arr);
}

function swap(n, arr) {
  temp = arr[n];
  arr[n] = arr[n + 1];
  arr[n + 1] = temp;
}

//visualizaiton
function updatevisualization(xx) {
  var bars = canvas.selectAll("rect")
    .data(xx)
    .enter()
    .append("rect")
    .attr("height", function(d) {
      return (5 * d);
    })
    .attr("width", 10)
    .attr("x", function(d, i) {
      return i * 20;
    });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>

3 ответа

Решение

var arr = new Array(10, 34, 66, 3, 56, 45, 67, 43, 45, 7);
var wi = 500;
var he = 500;
var temp = 0;

//Scaling
var canvas = d3.select("body")
  .append("svg")
  .attr("width", wi)
  .attr("height", he);
updatevisualization(arr);

setTimeout(function(){
  var nAr = arr.sort(function(a,b){return a>b;});//Sorting numbers in ascending order
  canvas.html('');//removing old bars('rect's)
  update(nAr);//Creating bar('rect')s with new sorted array.
}, 1000);


/*
for (l = 9; l > 0; l--) {

      var myVar = setTimeout(function(){  for( p=0;p<l; p++){
                      if(arr[p]>arr[p+1]){
                          swap(p,arr);
                       
                                 
                         }
                      
                  }}, 1000);
  updatevisualization(arr);
}
*/


function swap(n, arr) {
  temp = arr[n];
  arr[n] = arr[n + 1];
  arr[n + 1] = temp;
}

//visualizaiton
function updatevisualization(xx) {
  var bars = canvas.selectAll("rect")
    .data(xx)
    .enter()
    .append("rect")
    .attr("height", function(d) {
      return (5 * d);
    })
    .attr("width", 10)
    .attr("x", function(d, i) {
      return i * 20;
    });
}

function update(numbers) {
canvas.selectAll('bar').data(arr).exit().remove();
  var selection = canvas
    .selectAll("bar").data(numbers);

  selection.enter()
    .append("rect")
    .attr("height", function(d) {
      return (5 * d);
    })
    .attr("width", 10)
    .attr("x", function(d, i) {
      return i * 20;
    });
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>

Я только что добавил небольшой код для сортировки массива и повторного создания элементов. Попробуйте соблюдать код.

На самом деле это то, что я искал. Из вышеперечисленного Aswers я смог собрать вещи вместе;):D

<!Doctype <!DOCTYPE html>
<html>

<head>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>

  <title>Visualizer App Beta!!</title>
</head>


<body>

  <script>
    var arr = new Array(10, 34, 66, 3, 56, 45, 67, 43, 45, 7);
    var wi = 500;
    var he = 500;
    var temp = 0;
     // var pos=0;
     // draww(arr);
     //    var x= d3.scale.linear().domain([3-67]).range([3-he]);
    var canvas = d3.select("body")
      .append("svg")
      .attr("width", wi)
      .attr("height", he);


    var l = 9; //Scaling


    var startChunk = function(l) {
      //updatevisualization(arr);
      canvas.html('');
      update(arr);
      if (l == 0) return;
      for (p = 0; p < l; p++) {
        if (arr[p] > arr[p + 1]) {
          swap(p, arr);
        }
      }
      setTimeout(function() {
        startChunk(l - 1);
      }, 1000);
    };

     // Schedule the first chunk
    startChunk(9);





    function swap(n, arr) {

      temp = arr[n];
      arr[n] = arr[n + 1];
      arr[n + 1] = temp;


    }


   
     //visualizaiton

    function update(numbers) {
      canvas.selectAll('bar').data(arr).exit().remove();
      var selection = canvas
        .selectAll("bar").data(numbers);

      selection.enter()
        .append("rect")
        .attr("height", function(d) {
          return (5 * d);
        })
        .attr("width", 10)
        .attr("x", function(d, i) {
          return i * 20;
        });
    };
  </script>

</body>

</html>

В вашем коде вы выполняете функцию setTimeout и процедуру updateVisualization несколько раз за один проход, что воспринимается как мгновенная операция, поскольку она в основном выполняется за секунду, фактически меньше миллисекунды.

Когда вся область выполнения алгоритма сортировки завершается, и JS запускает следующие циклы цикла событий. По сути, теперь он просто спит и ждет внешних событий и событий таймера.

В конце концов, примерно через 1000 мс JS начинает планировать все шаги алгоритма сортировки, как вы запросили с помощью функции setTimeout. Экран никогда не обновляется, потому что весь код обновления экрана уже завершен в первом цикле событий вместе с алгоритмом сортировки.

Чтобы получать обновления по расписанию, вы можете разделить цикл на части работы, запланированные отдельно:

Вот что должна делать часть работы: Обновление экрана; Если требуется следующий шаг, выполните этот шаг и запланируйте следующий фрагмент;

Первый блок запускается вручную, он не запланирован предыдущим фрагментом.

var startChunk = function(l) {
  updatevisualization(arr);
  if (l == 0) return;
  for (p = 0; p < l; p++) {
    if (arr[p] > arr[p + 1]) {
      swap(p, arr);
    }
  }
  setTimeout(function() {
    startChunk(l - 1);
  }, 1000);
};

// Schedule the first chunk
startChunk(9);

Как примечание стороны, вы должны использовать что-то вроде console.log("What's on at " + new Date()); отлаживать асинхронный код и знать, что происходит и когда.

Другие вопросы по тегам