Визуализация алгоритмов сортировки
Я пытаюсь визуализировать алгоритмы сортировки, используя 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());
отлаживать асинхронный код и знать, что происходит и когда.