From e17443b2c2c40b9337a9a34904a0c20afd9c023b Mon Sep 17 00:00:00 2001 From: AsianPotato <32502374+AsianPotato@users.noreply.github.com> Date: Thu, 28 Mar 2019 16:21:32 +0000 Subject: [PATCH 1/5] Add files via upload --- Algorithm-Visualiser.js | 433 +++++++++++++++++++++------------------- 1 file changed, 227 insertions(+), 206 deletions(-) diff --git a/Algorithm-Visualiser.js b/Algorithm-Visualiser.js index 67cb715..0087a8c 100644 --- a/Algorithm-Visualiser.js +++ b/Algorithm-Visualiser.js @@ -1,207 +1,228 @@ -class algorithmVisualiser{ - configVariables(){ // Bodge for ES6 not supporting Public Field Declarations - self.dataSet = { - data: [], - compIndicator: [], - compCount: 0, - swapIndicator: [], - swapCount: 0, - iterationCount: 0, - iteration: () => { self.dataSet.iterationCount++; self.dataSet.swapIndicator = []; self.dataSet.compIndicator = []; }, - swap: (x,y) => { - [ self.dataSet.data[x], self.dataSet.data[y] ] = [ self.dataSet.data[y], self.dataSet.data[x] ]; - self.dataSet.swapIndicator = [x, y]; - self.dataSet.swapCount++; - }, - lessthan: (x,y) => { self.dataSet.compIndicator = [x, y]; self.dataSet.compCount++; return self.dataSet.data[x] < self.dataSet.data[y]}, - greaterthan: (x,y) => { self.dataSet.compIndicator = [x, y]; self.dataSet.compCount++; return self.dataSet.data[x] > self.dataSet.data[y]}, - }; - self.options = { - size: 128, - delay: 16, - structure: "Random", - algorithm: "Bubble Sort", - gui: false, - fps: false, - lineColor: "#0000FF", - compColor: "#FF0000", - swapColor: "#00FF00", - lineWidth: 2.5, - fontSize: 15, - }; - } - constructor(canvas, opts = {}) { - self = this; - self.configVariables(); - self.configDynamicFunctions(); - self.options = {...self.options, ...opts}; // Apply construction options - self.ctx = canvas.getContext('2d'); - - if(self.options.gui){ - var gui = new dat.GUI(); - gui.add(self.options, 'algorithm', self.algorithms.map(x => x.name)).name("Algorithm"); - gui.add(self.options, 'structure', self.structures.map(x => x.name)).name("Structure").onFinishChange(self.reset); - gui.add(self.options, 'size', 64, 1024, 64).name("Size").onChange(self.reset); - gui.add(self.options, 'delay', 0, 64).name("Delay (ms)"); - gui.add(self, 'reset').name("Reset"); - gui.add(self, 'startStop').name("Start / Stop"); - - let advFolder = gui.addFolder("Advanced"); - advFolder.addColor(self.options, 'lineColor'); - advFolder.addColor(self.options, 'compColor'); - advFolder.addColor(self.options, 'swapColor'); - advFolder.add(self.options, 'lineWidth', 0, 15); - advFolder.add(self.options, 'fontSize', 0, 72); - - if(self.options.fps != false && self.options.gui){ - self.options.fps = new Stats(); - self.options.fps.domElement.height = '48px'; - [].forEach.call(self.options.fps.domElement.children, (child) => (child.style.display = '')); - - var perfFolder = gui.addFolder("Performance"); - var perfLi = document.createElement("li"); - self.options.fps.domElement.style.position = "static"; - perfLi.appendChild(self.options.fps.domElement); - perfLi.classList.add("gui-stats"); - perfFolder.__ul.appendChild(perfLi); - } - - } - - if(self.options.fps != false && !(self.options.gui)){ - self.options.fps = new Stats(); - self.options.fps.showPanel( 0 ); // 0: fps, 1: ms, 2: mb, 3+: custom - self.options.fps.domElement.style = "position:fixed;top:0;left:0;"; - document.body.appendChild( self.options.fps.domElement ); - } - - self.reset(); - self.draw(); - } - - startStop(){ - self.algorithms.find(x => x.name === self.options.algorithm).algorithm(); - } - - reset(){ - self.structures.find(x => x.name === self.options.structure).func(); - self.dataSet.iterationCount = 0; - self.dataSet.swapCount = 0; - self.dataSet.compCount = 0; - } - - draw(){ - if(self.options.fps != false){self.options.fps.begin();} - var ctx = self.ctx; - var width = ctx.canvas.width = ctx.canvas.clientWidth; - var height = ctx.canvas.height = ctx.canvas.clientHeight; - var scaleY = (height / Math.max(...self.dataSet.data)); - var lineWidth = self.options.lineWidth || (width/self.dataSet.data.length)+0.5; - - - for(let i=0;i self.draw() ); - //window.requestAnimationFrame( this.draw.bind(this) ); // Fix "this" binding - } - - async wait(time) { - return new Promise(function(resolve) { - setTimeout(resolve, time); - }); - } - - configDynamicFunctions(){ // Bodge for ES6 not supporting Public Field Declarations - self.structures = [ - {name:"Random", func: ()=>{ - self.dataSet.data = Array.from({length: self.options.size}, () => Math.floor(Math.random() * self.options.size)); - }}, - {name:"Random Unique", func: ()=>{ - self.dataSet.data = Array.from(new Array(self.options.size),(v,i)=>i); - for (let i = self.dataSet.data.length - 1; i > 0; i--) { - const j = Math.floor(Math.random() * (i + 1)); - [self.dataSet.data[i], self.dataSet.data[j]] = [self.dataSet.data[j], self.dataSet.data[i]]; - } - }}, - {name:"Reverse Order", func: ()=>{ - self.dataSet.data = Array.from(new Array(self.options.size),(v,i)=>self.options.size-i); - }}, - {name:"Nearly Sorted", func: ()=>{ - // TODO: Make Nearly Sorted Arr - }}, - {name:"Few Unique", func: ()=>{ - // TODO: Make Arr with a few unique values - }} - ] - - self.algorithms = [ - - {name:"Bubble Sort",algorithm: async ()=>{ - for (var i = ( self.dataSet.data.length - 1); i >= 0; i--){ - for (var j = ( self.dataSet.data.length - i); j > 0; j--){ - self.dataSet.iteration(); // Iterate counter etc... - if (self.dataSet.lessthan(j, j-1)){ - self.dataSet.swap(j, j-1); - } - await self.wait(self.options.delay); // Delay before next iteration - } - } - self.dataSet.swapIndicator = []; // Finished Empty active data - self.dataSet.swapIndicator =[]; // Finished Empty active data - }}, - - {name:"Quick Sort",algorithm: async ()=>{ - - }}, - - {name:"Selection Sort",algorithm: async ()=>{ - for(var i = 0; i < self.dataSet.data.length-1 ; i++) { - var minIdx = i ; - for(var j = i+1; j < self.dataSet.data.length ; j++ ) { - if(self.dataSet.lessthan(j, minIdx)) { //finds the minIdx element - minIdx = j ; - } - await self.wait(self.options.delay); // Delay before next iteration - } - self.dataSet.swap(minIdx, i); - } - }}, - - ]; - } -} - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/* End Class */ -///////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -var AV; - -window.onload = () => { - let AVCanvas = document.getElementById("algorithm-visualiser"); - AV = new algorithmVisualiser(AVCanvas, {gui: true, fps: true}); +lass algorithmVisualiser{ + configVariables(){ // Bodge for ES6 not supporting Public Field Declarations + self.dataSet = { + data: [], + compIndicator: [], + compCount: 0, + swapIndicator: [], + swapCount: 0, + iterationCount: 0, + iteration: () => { self.dataSet.iterationCount++; self.dataSet.swapIndicator = []; self.dataSet.compIndicator = []; }, + swap: (x,y) => { + [ self.dataSet.data[x], self.dataSet.data[y] ] = [ self.dataSet.data[y], self.dataSet.data[x] ]; + self.dataSet.swapIndicator = [x, y]; + self.dataSet.swapCount++; + }, + lessthan: (x,y) => { self.dataSet.compIndicator = [x, y]; self.dataSet.compCount++; return self.dataSet.data[x] < self.dataSet.data[y]}, + greaterthan: (x,y) => { self.dataSet.compIndicator = [x, y]; self.dataSet.compCount++; return self.dataSet.data[x] > self.dataSet.data[y]}, + }; + self.options = { + size: 128, + delay: 16, + structure: "Random", + algorithm: "Bubble Sort", + gui: false, + fps: false, + lineColor: "#0000FF", + compColor: "#FF0000", + swapColor: "#00FF00", + lineWidth: 2.5, + fontSize: 15, + }; + self.paused = true; + self.ran = false; + } + constructor(canvas, opts = {}) { + self = this; + self.configVariables(); + self.configDynamicFunctions(); + self.options = {...self.options, ...opts}; // Apply construction options + self.ctx = canvas.getContext('2d'); + + if(self.options.gui){ + var gui = new dat.GUI(); + gui.add(self.options, 'algorithm', self.algorithms.map(x => x.name)).name("Algorithm"); + gui.add(self.options, 'structure', self.structures.map(x => x.name)).name("Structure").onFinishChange(self.reset); + gui.add(self.options, 'size', 64, 1024, 64).name("Size").onChange(self.reset); + gui.add(self.options, 'delay', 0, 64).name("Delay (ms)"); + gui.add(self, 'reset').name("Reset"); + gui.add(self, 'startStop').name("Start / Stop"); + + let advFolder = gui.addFolder("Advanced"); + advFolder.addColor(self.options, 'lineColor'); + advFolder.addColor(self.options, 'compColor'); + advFolder.addColor(self.options, 'swapColor'); + advFolder.add(self.options, 'lineWidth', 0, 15); + advFolder.add(self.options, 'fontSize', 0, 72); + + if(self.options.fps != false && self.options.gui){ + self.options.fps = new Stats(); + self.options.fps.domElement.height = '48px'; + [].forEach.call(self.options.fps.domElement.children, (child) => (child.style.display = '')); + + var perfFolder = gui.addFolder("Performance"); + var perfLi = document.createElement("li"); + self.options.fps.domElement.style.position = "static"; + perfLi.appendChild(self.options.fps.domElement); + perfLi.classList.add("gui-stats"); + perfFolder.__ul.appendChild(perfLi); + } + + } + + if(self.options.fps != false && !(self.options.gui)){ + self.options.fps = new Stats(); + self.options.fps.showPanel( 0 ); // 0: fps, 1: ms, 2: mb, 3+: custom + self.options.fps.domElement.style = "position:fixed;top:0;left:0;"; + document.body.appendChild( self.options.fps.domElement ); + } + + self.reset(); + self.draw(); + } + + startStop(){ + if(self.paused) + { + self.paused = false; + if (!self.ran) + { + self.algorithms.find(x => x.name === self.options.algorithm).algorithm(); + self.ran = true; + } + } + else + self.paused = true; + } + + reset(){ + self.structures.find(x => x.name === self.options.structure).func(); + self.dataSet.iterationCount = 0; + self.dataSet.swapCount = 0; + self.dataSet.compCount = 0; + } + + draw(){ + if(self.options.fps != false){self.options.fps.begin();} + var ctx = self.ctx; + var width = ctx.canvas.width = ctx.canvas.clientWidth; + var height = ctx.canvas.height = ctx.canvas.clientHeight; + var scaleY = (height / Math.max(...self.dataSet.data)); + var lineWidth = self.options.lineWidth || (width/self.dataSet.data.length)+0.5; + + + + for(let i=0;i self.draw() ); + //window.requestAnimationFrame( this.draw.bind(this) ); // Fix "this" binding + } + + async wait(time) { + return new Promise(function(resolve) { + setTimeout(resolve, time); + }); + } + + configDynamicFunctions(){ // Bodge for ES6 not supporting Public Field Declarations + self.structures = [ + {name:"Random", func: ()=>{ + self.dataSet.data = Array.from({length: self.options.size}, () => Math.floor(Math.random() * self.options.size)); + }}, + {name:"Random Unique", func: ()=>{ + self.dataSet.data = Array.from(new Array(self.options.size),(v,i)=>i); + for (let i = self.dataSet.data.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [self.dataSet.data[i], self.dataSet.data[j]] = [self.dataSet.data[j], self.dataSet.data[i]]; + } + }}, + {name:"Reverse Order", func: ()=>{ + self.dataSet.data = Array.from(new Array(self.options.size),(v,i)=>self.options.size-i); + }}, + {name:"Nearly Sorted", func: ()=>{ + // TODO: Make Nearly Sorted Arr + }}, + {name:"Few Unique", func: ()=>{ + // TODO: Make Arr with a few unique values + }} + ] + + self.algorithms = [ + + {name:"Bubble Sort",algorithm: async ()=>{ + for (var i = ( self.dataSet.data.length - 1); i >= 0; i--){ + for (var j = ( self.dataSet.data.length - i); j > 0; j--){ + self.dataSet.iteration(); // Iterate counter etc... + if (self.dataSet.lessthan(j, j-1)){ + self.dataSet.swap(j, j-1); + } + while(self.paused) + { + await self.wait(50); + } + + await self.wait(self.options.delay); // Delay before next iteration + } + } + self.dataSet.swapIndicator = []; // Finished Empty active data + self.dataSet.swapIndicator =[]; // Finished Empty active data + }}, + + {name:"Quick Sort",algorithm: async ()=>{ + + }}, + + {name:"Selection Sort",algorithm: async ()=>{ + for(var i = 0; i < self.dataSet.data.length-1 ; i++) { + var minIdx = i ; + for(var j = i+1; j < self.dataSet.data.length ; j++ ) { + if(self.dataSet.lessthan(j, minIdx)) { //finds the minIdx element + minIdx = j ; + } + await self.wait(self.options.delay); // Delay before next iteration + } + self.dataSet.swap(minIdx, i); + } + }}, + + ]; + } +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* End Class */ +///////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +var AV; + +window.onload = () => { + let AVCanvas = document.getElementById("algorithm-visualiser"); + AV = new algorithmVisualiser(AVCanvas, {gui: true, fps: true}); }; \ No newline at end of file From 86213662a2f584723d5b05ef5c28c896dc3d6275 Mon Sep 17 00:00:00 2001 From: AsianPotato <32502374+AsianPotato@users.noreply.github.com> Date: Thu, 28 Mar 2019 16:26:48 +0000 Subject: [PATCH 2/5] Add files via upload From 4d55656ea476c5a566a74b0715e77424baf3076a Mon Sep 17 00:00:00 2001 From: AsianPotato <32502374+AsianPotato@users.noreply.github.com> Date: Thu, 28 Mar 2019 16:28:34 +0000 Subject: [PATCH 3/5] added pausing --- Algorithm-Visualiser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Algorithm-Visualiser.js b/Algorithm-Visualiser.js index 0087a8c..2c01fa8 100644 --- a/Algorithm-Visualiser.js +++ b/Algorithm-Visualiser.js @@ -1,4 +1,4 @@ -lass algorithmVisualiser{ +class algorithmVisualiser{ configVariables(){ // Bodge for ES6 not supporting Public Field Declarations self.dataSet = { data: [], From d6cc2c3c3602365d8c5d7f22838c43566fd01956 Mon Sep 17 00:00:00 2001 From: AsianPotato <32502374+AsianPotato@users.noreply.github.com> Date: Thu, 28 Mar 2019 16:38:28 +0000 Subject: [PATCH 4/5] fixed pausing --- Algorithm-Visualiser.js | 169 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 154 insertions(+), 15 deletions(-) diff --git a/Algorithm-Visualiser.js b/Algorithm-Visualiser.js index 2c01fa8..9ab23ef 100644 --- a/Algorithm-Visualiser.js +++ b/Algorithm-Visualiser.js @@ -12,9 +12,10 @@ class algorithmVisualiser{ [ self.dataSet.data[x], self.dataSet.data[y] ] = [ self.dataSet.data[y], self.dataSet.data[x] ]; self.dataSet.swapIndicator = [x, y]; self.dataSet.swapCount++; + self.audio.swap(); }, - lessthan: (x,y) => { self.dataSet.compIndicator = [x, y]; self.dataSet.compCount++; return self.dataSet.data[x] < self.dataSet.data[y]}, - greaterthan: (x,y) => { self.dataSet.compIndicator = [x, y]; self.dataSet.compCount++; return self.dataSet.data[x] > self.dataSet.data[y]}, + lessthan: (x,y) => { self.audio.comp(); self.dataSet.compIndicator = [x, y]; self.dataSet.compCount++; return self.dataSet.data[x] < self.dataSet.data[y]}, + greaterthan: (x,y) => { self.audio.comp(); self.dataSet.compIndicator = [x, y]; self.dataSet.compCount++; return self.dataSet.data[x] > self.dataSet.data[y]}, }; self.options = { size: 128, @@ -28,8 +29,19 @@ class algorithmVisualiser{ swapColor: "#00FF00", lineWidth: 2.5, fontSize: 15, + displayValues: false, }; - self.paused = true; + self.audio = { + enabled: true, + volume: 100, + //swapTone: "C4", + swapTone: 350, + compTone: 200, + synth: new Tone.Synth().toMaster(), + swap: () =>{self.audio.synth.triggerAttackRelease(self.audio.swapTone, '1n')}, + comp: () =>{self.audio.synth.triggerAttackRelease(self.audio.compTone, '1n')}, + }; + self.paused = true; self.ran = false; } constructor(canvas, opts = {}) { @@ -41,7 +53,7 @@ class algorithmVisualiser{ if(self.options.gui){ var gui = new dat.GUI(); - gui.add(self.options, 'algorithm', self.algorithms.map(x => x.name)).name("Algorithm"); + gui.add(self.options, 'algorithm', self.algorithms.map(x => x.name)).name("Algorithm").onFinishChange(self.reset); gui.add(self.options, 'structure', self.structures.map(x => x.name)).name("Structure").onFinishChange(self.reset); gui.add(self.options, 'size', 64, 1024, 64).name("Size").onChange(self.reset); gui.add(self.options, 'delay', 0, 64).name("Delay (ms)"); @@ -49,11 +61,17 @@ class algorithmVisualiser{ gui.add(self, 'startStop').name("Start / Stop"); let advFolder = gui.addFolder("Advanced"); + let audioFolder = advFolder.addFolder("Audio"); + audioFolder.add(self.audio, 'enabled').name("Enable"); + audioFolder.add(self.audio, 'volume').name("Volume").onChange(()=>{Tone.Master.volume = self.audio.volume}); + audioFolder.add(self.audio, 'swapTone', 20, 1024).name("Swap Tone"); + audioFolder.add(self.audio, 'compTone', 20, 1024).name("Comp Tone"); advFolder.addColor(self.options, 'lineColor'); advFolder.addColor(self.options, 'compColor'); advFolder.addColor(self.options, 'swapColor'); advFolder.add(self.options, 'lineWidth', 0, 15); advFolder.add(self.options, 'fontSize', 0, 72); + advFolder.add(self.options, 'displayValues'); if(self.options.fps != false && self.options.gui){ self.options.fps = new Stats(); @@ -98,6 +116,8 @@ class algorithmVisualiser{ reset(){ self.structures.find(x => x.name === self.options.structure).func(); self.dataSet.iterationCount = 0; + self.dataSet.swapIndicator = []; + self.dataSet.compIndicator = []; self.dataSet.swapCount = 0; self.dataSet.compCount = 0; } @@ -110,12 +130,14 @@ class algorithmVisualiser{ var scaleY = (height / Math.max(...self.dataSet.data)); var lineWidth = self.options.lineWidth || (width/self.dataSet.data.length)+0.5; - for(let i=0;i{ + var low = 0; + var high = self.dataSet.data.length - 1; + + // Create an auxiliary stack and push inital values + //int stack[high - low + 1]; + var stack = []; + var top = -1; + stack[++top] = low; + stack[++top] = high; + + // Keep popping from stack while is not empty + while (top >= 0) { + // Pop high and low + high = stack[top--]; + low = stack[top--]; + + // Inline Partion Calculation + var partitionIndex = (low - 1); + + for (var j = low; j <= high - 1; j++) { + if (self.dataSet.lessthan(j, high)) { // Should be <= + //if (self.dataSet.data[j] <= pivotValue) { + partitionIndex++; + self.dataSet.swap(partitionIndex, j); + await self.wait(self.options.delay); // Delay before next iteration + } + } + self.dataSet.swap(partitionIndex + 1, high); + await self.wait(self.options.delay); // Delay before next iteration + while(self.paused) + { + await self.wait(50); + } + partitionIndex++; + // End of Partition + // If there are elements on left side of pivot, + // then push left side to stack + if (partitionIndex - 1 > low) { + stack[++top] = low; + stack[++top] = partitionIndex - 1; + } + + // If there are elements on right side of pivot, + // then push right side to stack + if (partitionIndex + 1 < high) { + stack[++top] = partitionIndex + 1; + stack[++top] = high; + } + } }}, {name:"Selection Sort",algorithm: async ()=>{ @@ -207,11 +281,76 @@ class algorithmVisualiser{ minIdx = j ; } await self.wait(self.options.delay); // Delay before next iteration + while(self.paused) + { + await self.wait(50); + } } self.dataSet.swap(minIdx, i); } }}, + { + name: "Insertion Sort", algorithm: async () => { + for(let i = 1; i < self.dataSet.data.length; i++){ + let value = self.dataSet.data[i]; + let j = i - 1; + self.dataSet.compIndicator = [j, i]; self.dataSet.compCount++; + while(j >= 0 && self.dataSet.data[j] > value){ + self.dataSet.data[j + 1] = self.dataSet.data[j]; + self.dataSet.swapIndicator = [j, j+1]; self.dataSet.swapCount++; + j = j - 1; + await self.wait(self.options.delay); + while(self.paused) + { + await self.wait(50); + } + } + self.dataSet.data[j + 1] = value; + await self.wait(self.options.delay); + } + self.dataSet.swapIndicator = []; // Finished Empty active data + self.dataSet.compIndicator = []; // Finished Empty active data + } + }, + + { + name: "Shell Sort", algorithm: async () => { + // Define a gap distance. + let gap = Math.floor(self.dataSet.data.length / 2); + + // Until gap is bigger then zero do elements comparisons and swaps. + while (gap > 0) { + // Go and compare all distant element pairs. + for (let i = 0; i < (self.dataSet.data.length - gap); i += 1) { + let currentIndex = i; + let gapShiftedIndex = i + gap; + + while (currentIndex >= 0) { + self.dataSet.iteration(); // Iterate counter + // Compare and swap array elements if needed. + if (self.dataSet.lessthan(gapShiftedIndex, currentIndex)) { + self.dataSet.swap(currentIndex, gapShiftedIndex); + } + await self.wait(self.options.delay); self + gapShiftedIndex = currentIndex; + currentIndex -= gap; + while(self.paused) + { + await self.wait(50); + } + } + } + + // Shrink the gap. + gap = Math.floor(gap / 2); + } + + self.dataSet.swapIndicator = []; // Finished Empty active data + self.dataSet.compIndicator = []; // Finished Empty active data + } + }, + ]; } } From bb8d2e766551685cb7a3352afd79a2f69f3e3cc3 Mon Sep 17 00:00:00 2001 From: AsianPotato <32502374+AsianPotato@users.noreply.github.com> Date: Thu, 28 Mar 2019 16:44:20 +0000 Subject: [PATCH 5/5] cleaned up some pausing code --- Algorithm-Visualiser.js | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/Algorithm-Visualiser.js b/Algorithm-Visualiser.js index 9ab23ef..8489b21 100644 --- a/Algorithm-Visualiser.js +++ b/Algorithm-Visualiser.js @@ -210,9 +210,7 @@ class algorithmVisualiser{ self.dataSet.swap(j, j-1); } while(self.paused) - { await self.wait(50); - } await self.wait(self.options.delay); // Delay before next iteration } } @@ -251,9 +249,7 @@ class algorithmVisualiser{ self.dataSet.swap(partitionIndex + 1, high); await self.wait(self.options.delay); // Delay before next iteration while(self.paused) - { await self.wait(50); - } partitionIndex++; // End of Partition @@ -282,9 +278,7 @@ class algorithmVisualiser{ } await self.wait(self.options.delay); // Delay before next iteration while(self.paused) - { await self.wait(50); - } } self.dataSet.swap(minIdx, i); } @@ -302,9 +296,7 @@ class algorithmVisualiser{ j = j - 1; await self.wait(self.options.delay); while(self.paused) - { await self.wait(50); - } } self.dataSet.data[j + 1] = value; await self.wait(self.options.delay); @@ -336,9 +328,7 @@ class algorithmVisualiser{ gapShiftedIndex = currentIndex; currentIndex -= gap; while(self.paused) - { await self.wait(50); - } } }