Skip to content

Commit 2be8f15

Browse files
authored
Add files via upload
1 parent 657532f commit 2be8f15

File tree

1 file changed

+239
-0
lines changed

1 file changed

+239
-0
lines changed

script.js

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
let array = [1]
2+
let arrayLength = 25
3+
let modes = {initial: 1, sorting: 2, done: 3}
4+
let algorithms = {
5+
quickSort: {key: 2, name: "Quick Sort", description: `The time complexity of Quick Sort is O(n^2) in worst case and O(n*Log n) in average and best cases. The in-place version of quicksort has a space complexity of O(log n), even in the worst case. This unstable partition requires O(1) space. <br> <a href="https://youtu.be/Hoixgm4-P4M" target="_blank">Learn more...</a>`},
6+
bubbleSort: {key: 3, name: "Bubble Sort", description: `The time complexity of Bubble Sort is O(n^2) in worst and average cases and O(n) in best case. It has the space complexity of O(1). <br> <a href="https://youtu.be/xli_FI7CuzA" target="_blank">Learn more...</a>`},
7+
selectionSort: {key: 4, name: "Selection Sort", description: `The time complexity of Selection Sort is O(n^2) in worst and average cases and O(n^2) in best case. It has the space complexity of O(1). <br> <a href="https://youtu.be/g-PGLbMth_g" target="_blank">Learn more...</a>`},
8+
insertionSort: {key: 5, name: "Insertion Sort", description: `The time complexity of Insertion Sort is O(n^2) in all the 3 cases (worst, average and best). It has the space complexity of O(1). <br> <a href="https://youtu.be/JU767SDMDvA" target="_blank">Learn more...</a>`},
9+
}
10+
let indicatorPanelContent = {
11+
quickSort: `<div class="node node-sorted node-example ml-3" id="sorted_node_example"></div><div class="text-light ml-2">Sorted</div>
12+
<div class="ml-3 text-light">|</div>
13+
<div class="node node-unsorted node-example ml-3" id="unsorted_node_example"></div><div class="text-light ml-2">Unsorted</div>
14+
<div class="ml-3 text-light">|</div>
15+
<div class="node node-pivot ml-3" id="pivot_node_example"></div><div class="text-light ml-2">Pivot</div>
16+
<div class="ml-3 text-light">|</div>`,
17+
bubbleSort: `<div class="node node-sorted node-example ml-3" id="sorted_node_example"></div><div class="text-light ml-2">Sorted</div>
18+
<div class="ml-3 text-light">|</div>
19+
<div class="node node-unsorted node-example ml-3" id="unsorted_node_example"></div><div class="text-light ml-2">Unsorted</div>
20+
<div class="ml-3 text-light">|</div>`,
21+
selectionSort: `<div class="node node-position ml-3" id="position_node_example"></div><div class="text-light ml-2">Position</div>
22+
<div class="ml-3 text-light">|</div>
23+
<div class="node node-minimum ml-3" id="minimum_node_example"></div><div class="text-light ml-2">Minimum</div>
24+
<div class="ml-3 text-light">|</div>`,
25+
insertionSort: `<div class="node node-position ml-3" id="position_node_example"></div><div class="text-light ml-2">Position</div>
26+
<div class="ml-3 text-light">|</div>
27+
<div class="node node-scanner ml-3" id="scanner_node_example"></div><div class="text-light ml-2">Scanner</div>
28+
<div class="ml-3 text-light">|</div>`,
29+
}
30+
let mode = modes.initial
31+
let algorithm = algorithms.quickSort // Updated to quickSort
32+
33+
const SEARCH_TIME = 20000
34+
const RUNNING_SORTING_MESSAGE = "Sorting is ongoing"
35+
36+
document.addEventListener('DOMContentLoaded', () => {
37+
array = generateArray(arrayLength)
38+
showAlgorithmList()
39+
updateVisualizerButton()
40+
updateIndicatorPanel()
41+
updateAlgorithmInfo()
42+
plotGraph()
43+
handleUserEvent()
44+
})
45+
46+
function handleUserEvent () {
47+
algorithmInputHandler()
48+
visualizerButtonHandler()
49+
resetButtonHandler()
50+
algorithmInfoHandler()
51+
customInputHandler()
52+
}
53+
54+
function showAlgorithmList() {
55+
let algorithmList = document.querySelector('#algorithm_list')
56+
Object.keys(algorithms).map(index => {
57+
algorithmList.insertAdjacentHTML('beforeend', `<a class="dropdown-item cursor-pointer" id="algorithm_${algorithms[index].key}">${algorithms[index].name}</a>`)
58+
})
59+
}
60+
function algorithmInputHandler() {
61+
let quickSortAlgorithm = document.querySelector('#algorithm_list').querySelector(`#algorithm_${algorithms.quickSort.key}`)
62+
quickSortAlgorithm.addEventListener('click', () => {
63+
if (mode === modes.initial || mode === modes.done) {
64+
algorithm = algorithms.quickSort
65+
updateVisualizerButton()
66+
updateIndicatorPanel()
67+
updateAlgorithmInfo()
68+
}
69+
})
70+
let bubbleSortAlgorithm = document.querySelector('#algorithm_list').querySelector(`#algorithm_${algorithms.bubbleSort.key}`)
71+
bubbleSortAlgorithm.addEventListener('click', () => {
72+
if (mode === modes.initial || mode === modes.done) {
73+
algorithm = algorithms.bubbleSort
74+
updateVisualizerButton()
75+
updateIndicatorPanel()
76+
updateAlgorithmInfo()
77+
}
78+
})
79+
let selectionSortAlgorithm = document.querySelector('#algorithm_list').querySelector(`#algorithm_${algorithms.selectionSort.key}`)
80+
selectionSortAlgorithm.addEventListener('click', () => {
81+
if (mode === modes.initial || mode === modes.done) {
82+
algorithm = algorithms.selectionSort
83+
updateVisualizerButton()
84+
updateIndicatorPanel()
85+
updateAlgorithmInfo()
86+
}
87+
})
88+
let insertionSortAlgorithm = document.querySelector('#algorithm_list').querySelector(`#algorithm_${algorithms.insertionSort.key}`)
89+
insertionSortAlgorithm.addEventListener('click', () => {
90+
if (mode === modes.initial || mode === modes.done) {
91+
algorithm = algorithms.insertionSort
92+
updateVisualizerButton()
93+
updateIndicatorPanel()
94+
updateAlgorithmInfo()
95+
}
96+
})
97+
}
98+
99+
function visualizerButtonHandler() {
100+
let visualizerButton = document.querySelector('#start_btn')
101+
let statusMessage = document.querySelector('#status_message')
102+
visualizerButton.addEventListener('click', async event => {
103+
if (mode === modes.initial || mode === modes.done) {
104+
mode = modes.sorting
105+
statusMessage.innerHTML = ''
106+
statusMessage.insertAdjacentHTML('beforeend', `Sorting <i class="fas fa-spinner"></i>`)
107+
let animation = []
108+
let movesCount = 0
109+
if (algorithm.key === algorithms.quickSort.key) {
110+
quickSort.sort([...array], animation)
111+
await barVisualizer.quickSort(animation)
112+
movesCount = animation.filter(set => !set.sorted).length
113+
} else if (algorithm.key === algorithms.bubbleSort.key) {
114+
bubbleSort.sort([...array], animation)
115+
await barVisualizer.bubbleSort(animation)
116+
movesCount = animation.filter(set => !set.sorted).length
117+
} else if (algorithm.key === algorithms.selectionSort.key) {
118+
selectionSort.sort([...array], animation)
119+
await barVisualizer.selectionSort(animation)
120+
movesCount = animation.filter(set => !set.sorted).length
121+
} else if (algorithm.key === algorithms.insertionSort.key) {
122+
insertionSort.sort([...array], animation)
123+
await barVisualizer.insertionSort(animation)
124+
movesCount = animation.filter(set => !set.sorted).length
125+
}
126+
statusMessage.innerHTML = `Sorting Completed | Total Moves: ${movesCount}`
127+
mode = modes.done
128+
}
129+
})
130+
}
131+
132+
function resetButtonHandler () {
133+
let graphBody = document.querySelector('#graph_body')
134+
let resetButton = document.querySelector('#reset_btn')
135+
resetButton.addEventListener('click', async event => {
136+
if (mode===modes.initial||mode===modes.done){
137+
let statusMessage = document.querySelector('#status_message')
138+
statusMessage.innerHTML = ''
139+
array = generateArray(arrayLength)
140+
graphBody.innerHTML = ''
141+
plotGraph()
142+
mode = modes.initial
143+
}
144+
})
145+
}
146+
147+
function customInputHandler() {
148+
let customInputButton = document.querySelector('#custom_input_btn')
149+
customInputButton.addEventListener('click', event => {
150+
if (mode===modes.initial||mode===modes.done){
151+
let customInput = document.querySelector('#custom_input')
152+
customInput.style.display = "flex"
153+
}
154+
else alert(RUNNING_SORTING_MESSAGE)
155+
})
156+
let customInputCancelButton = document.querySelector('#custom_input_cancel_btn')
157+
customInputCancelButton.addEventListener('click', event => {
158+
let customInput = document.querySelector('#custom_input')
159+
customInput.style.display = "none"
160+
})
161+
let customInputSubmitButton = document.querySelector('#custom_input_submit_btn')
162+
customInputSubmitButton.addEventListener('click', event => {
163+
let customInputField = document.querySelector('#custom_input_field')
164+
let input = customInputField.value
165+
input = input.split(',').map(value => {
166+
let number = Number(value)
167+
if (number<5) number = 5
168+
if (number>500) number =500
169+
return number
170+
})
171+
if (input.includes(NaN)) alert('Invalid Input')
172+
else {
173+
array = input
174+
arrayLength = array.length
175+
plotGraph()
176+
customInputCancelButton.click()
177+
}
178+
})
179+
}
180+
181+
function algorithmInfoHandler() {
182+
let algorithmInfoButton = document.querySelector('#graph_header').querySelector('.algorithm-info-btn')
183+
algorithmInfoButton.addEventListener('click', event => {
184+
let algorithmInfo = document.querySelector('#algorithm_info')
185+
algorithmInfo.style.display = "flex"
186+
})
187+
let algorithmInfoCancelButton = document.querySelector('#algorithm_info_cancel_btn')
188+
algorithmInfoCancelButton.addEventListener('click', event => {
189+
let algorithmInfo = document.querySelector('#algorithm_info')
190+
algorithmInfo.style.display = "none"
191+
})
192+
}
193+
194+
function updateVisualizerButton() {
195+
let visualizerButton = document.querySelector('#start_btn')
196+
visualizerButton.innerHTML = `Start ${algorithm.name}`
197+
let algorithmMessage = document.querySelector('#algorithm_message')
198+
algorithmMessage.innerHTML = `${algorithm.name} Algorithm`
199+
let statusMessage = document.querySelector('#status_message')
200+
statusMessage.innerHTML = ``
201+
}
202+
203+
function updateIndicatorPanel() {
204+
let indicatorPanel = document.querySelector('#indicator_panel')
205+
indicatorPanel.innerHTML = ''
206+
let key = 'merge'
207+
Object.keys(algorithms).map(index => {
208+
if (algorithms[index] === algorithm) key = index
209+
})
210+
indicatorPanel.insertAdjacentHTML('beforeend', indicatorPanelContent[key])
211+
}
212+
213+
function updateAlgorithmInfo() {
214+
let algorithmInfoHeader = document.querySelector('#algorithm_info_header')
215+
let algorithmInfoBody = document.querySelector('#algorithm_info_body')
216+
algorithmInfoHeader.innerHTML = algorithm.name+" Algorithm"
217+
algorithmInfoBody.innerHTML = algorithm.description
218+
}
219+
220+
function plotGraph(unsortedNodes=[]) {
221+
let graphBody = document.querySelector('#graph_body')
222+
let nodeWidth = Math.floor(graphBody.offsetWidth/array.length*0.6)
223+
let barChart = graphBody.querySelector('#bar_chart')
224+
if (!barChart) graphBody.insertAdjacentHTML('beforeend', `<div class="bar-chart row m-0" id="bar_chart"></div>`)
225+
barChart = graphBody.querySelector('#bar_chart')
226+
barChart.innerHTML = ''
227+
array.map( (number, index) => {
228+
barChart.insertAdjacentHTML('beforeend', `<div class="node text-white text-center" id="node_${index}">${number}</div>`)
229+
let node = barChart.querySelector(`#node_${index}`)
230+
node.style.height = number+"px"
231+
node.style.width = nodeWidth+"px"
232+
node.style.fontSize = (nodeWidth/3)+"px"
233+
234+
let indices = unsortedNodes.filter(indices => indices.index===index)
235+
if (unsortedNodes.length && indices.length) {
236+
node.classList.add(indices[0].className)
237+
}
238+
})
239+
}

0 commit comments

Comments
 (0)