From 7700f927a40fb06975c6018f07b39c65b7d31638 Mon Sep 17 00:00:00 2001
From: bkrmadtya <karki.bikram007@gmail.com>
Date: Sat, 30 Jan 2021 23:42:00 +0200
Subject: [PATCH 1/4] wip: minimizing the steps to make it more simpler and
 cleaner

---
 package.json                      |  4 ++-
 src/App.tsx                       | 58 ++++++++++++++++++++++++++-----
 src/algorithms/BubbleSort.ts      | 22 +++++++++---
 src/algorithms/MergeSort.ts       | 38 +++++++++++++++-----
 src/app.scss                      | 32 ++++++++++++++---
 src/components/Bar.tsx            | 18 ++++++++--
 src/hooks/useSort.tsx             | 13 ++++---
 src/utils/BarColors.ts            |  9 ++---
 src/utils/enum.ts                 |  3 +-
 src/utils/randomArrayGenerator.ts |  4 +--
 yarn.lock                         | 17 +++++++--
 11 files changed, 177 insertions(+), 41 deletions(-)

diff --git a/package.json b/package.json
index 5bc2f68..8aab947 100644
--- a/package.json
+++ b/package.json
@@ -23,8 +23,10 @@
 		]
 	},
 	"dependencies": {
+		"d3-ease": "^2.0.0",
 		"react": "^17.0.1",
-		"react-dom": "^17.0.1"
+		"react-dom": "^17.0.1",
+		"react-spring": "^8.0.27"
 	},
 	"devDependencies": {
 		"@babel/core": "^7.12.10",
diff --git a/src/App.tsx b/src/App.tsx
index f078ba3..c4d6212 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -11,27 +11,69 @@ import BarComponent from 'src/components/Bar'
 // utils
 import BubbleSort from 'src/algorithms/BubbleSort'
 import MergeSort from 'src/algorithms/MergeSort'
+import { animated, useTransition } from 'react-spring'
 
 const App: React.FC = () => {
 	const { state, sort, reset, cancel, previousStep, nextStep } = useSort(
+		// BubbleSort
 		MergeSort
 	)
 
+	let height = 0
+	const transitions = useTransition(
+		state.steps[state.currentStep].map(data => ({
+			...data,
+			x: (height += 5)
+		})),
+		d => `${d.value}`,
+		{
+			from: { opacity: 1 },
+			leave: { height: 0, opacity: 1 },
+			enter: ({ x, value }) => ({ x, value, opacity: 1 }),
+			update: ({ x, value }) => ({ x, value, opacity: 1 }),
+			config: { duration: 100 }
+		}
+	)
+
 	return (
 		<div className='app'>
 			<h1>Sorting algorithms visualizer</h1>
 
-			<div className='bar__container'>
+			<div className='content'>
+				<div className='content__barContainer'>
+					{transitions.map(({ item, props: { x, ...rest }, key }, index) => (
+						<animated.div
+							key={key}
+							className='card'
+							style={{
+								zIndex: state.steps[0].length - index,
+								transform: x.interpolate(x => `translate3d(${x}px,0,0)`),
+								...rest
+							}}
+						>
+							<BarComponent
+								key={item.value}
+								value={item.value}
+								status={item.status}
+							/>
+						</animated.div>
+					))}
+				</div>
+
+				{/* <div className='bar__container'>
 				{state.steps[state.currentStep].map(a => (
 					<BarComponent key={a.value} value={a.value} status={a.status} />
-				))}
-			</div>
+					))}
+				</div> */}
 
-			<button onClick={sort}>Sort</button>
-			<button onClick={cancel}>Cancel</button>
-			<button onClick={reset}>Reset</button>
-			<button onClick={previousStep}>Previous Step</button>
-			<button onClick={nextStep}>Next Step</button>
+				<div className='content__controls'>
+					<button onClick={sort}>Sort</button>
+					<button onClick={cancel}>Cancel</button>
+					<button onClick={reset}>Reset</button>
+					<button onClick={previousStep}>Previous Step</button>
+					<button onClick={nextStep}>Next Step</button>
+				</div>
+			</div>
 		</div>
 	)
 }
diff --git a/src/algorithms/BubbleSort.ts b/src/algorithms/BubbleSort.ts
index e88391f..864cc5c 100644
--- a/src/algorithms/BubbleSort.ts
+++ b/src/algorithms/BubbleSort.ts
@@ -4,7 +4,7 @@ import changeStatusOfElement from 'src/utils/changeStatusOfElement'
 import swapElements from 'src/utils/swapElements'
 import { BarStatus } from 'src/utils/enum'
 
-const { ACTIVE, SORTED, UNSORTED } = BarStatus
+const { ACTIVE, SORTED, UNSORTED, GREATER, LESSER } = BarStatus
 
 export default class BubbleSort implements IAlgorithm {
 	private steps: Bar[][] = []
@@ -22,17 +22,29 @@ export default class BubbleSort implements IAlgorithm {
 				const second = result[j]
 
 				changeStatusOfElement(this.steps, first, ACTIVE)
-				changeStatusOfElement(this.steps, second, ACTIVE)
+				// changeStatusOfElement(this.steps, second, ACTIVE)
 
 				if (first.value > second.value) {
+					// this.steps.push([...result])
+					// changeStatusOfElement(this.steps, first, LESSER)
+					// changeStatusOfElement(this.steps, second, LESSER)
+
 					swapElements(result, first, second)
+					this.steps.push([...result])
+					// changeStatusOfElement(this.steps, first, LESSER)
+					// changeStatusOfElement(this.steps, second, LESSER)
 				} else {
+					changeStatusOfElement(this.steps, first, UNSORTED)
 					first = result[j]
 				}
 
-				this.steps.push([...result])
-				changeStatusOfElement(this.steps, first, UNSORTED)
-				changeStatusOfElement(this.steps, second, UNSORTED)
+				// this.steps.push([...result])
+				// changeStatusOfElement(this.steps, result[j - 1], GREATER)
+				// changeStatusOfElement(this.steps, result[j], GREATER)
+
+				// this.steps.push([...result])
+				// changeStatusOfElement(this.steps, first, UNSORTED)
+				// changeStatusOfElement(this.steps, second, UNSORTED)
 			}
 
 			changeStatusOfElement(this.steps, first, SORTED)
diff --git a/src/algorithms/MergeSort.ts b/src/algorithms/MergeSort.ts
index 2c2f7c2..8f0ddcd 100644
--- a/src/algorithms/MergeSort.ts
+++ b/src/algorithms/MergeSort.ts
@@ -2,7 +2,7 @@ import Bar from 'src/utils/Bar'
 import changeStatusOfElement from 'src/utils/changeStatusOfElement'
 import { BarStatus } from 'src/utils/enum'
 import { IAlgorithm } from 'src/utils/interface'
-const { ACTIVE, UNSORTED, SORTED } = BarStatus
+const { ACTIVE, UNSORTED, SORTED, GREATER, LESSER, UNSWAPPED } = BarStatus
 
 export default class MergeSort implements IAlgorithm {
 	private steps: Bar[][] = []
@@ -37,38 +37,58 @@ export default class MergeSort implements IAlgorithm {
 		const leastIndex = this.getLeastIndex(this.steps, leftArr[0], rightArr[0])
 
 		while (leftArr.length && rightArr.length) {
-			const isLeftEleGreater = leftArr[0].value > rightArr[0].value
+			const isRightSmaller = leftArr[0].value > rightArr[0].value
 			const currentIndex = sortedArr.length
 
 			changeStatusOfElement(this.steps, leftArr[0], ACTIVE)
 			changeStatusOfElement(this.steps, rightArr[0], ACTIVE)
 
-			const lesserEle = isLeftEleGreater
+			const smallerEle = isRightSmaller
 				? this.removeFirstElementAndReturn(rightArr)
 				: this.removeFirstElementAndReturn(leftArr)
 
-			const greaterEle = isLeftEleGreater ? leftArr[0] : rightArr[0]
+			const greaterEle = isRightSmaller ? leftArr[0] : rightArr[0]
 
-			sortedArr.push(lesserEle)
+			this.steps.push([...this.steps[this.steps.length - 1]])
+			changeStatusOfElement(
+				this.steps,
+				smallerEle,
+				isRightSmaller ? LESSER : GREATER
+			)
+			changeStatusOfElement(
+				this.steps,
+				greaterEle,
+				isRightSmaller ? LESSER : GREATER
+			)
+
+			sortedArr.push(smallerEle)
 
 			// move lesser element to the least position
 			const modifiedStep = this.changeElementPosition(
 				this.steps,
-				lesserEle,
+				smallerEle,
 				leastIndex,
 				currentIndex
 			)
 
 			this.steps.push(modifiedStep)
 
+			this.steps.push(modifiedStep)
+
 			if (
 				leftArr.length + rightArr.length + sortedArr.length ===
 				this.steps[0].length
 			) {
-				changeStatusOfElement(this.steps, lesserEle, SORTED)
+				changeStatusOfElement(this.steps, smallerEle, SORTED)
 			} else {
-				changeStatusOfElement(this.steps, lesserEle, UNSORTED)
+				// incase right is smaller
 				changeStatusOfElement(this.steps, greaterEle, UNSORTED)
+				if (!isRightSmaller) {
+					changeStatusOfElement(this.steps, smallerEle, UNSORTED)
+				} else {
+					this.steps.push([...this.steps[this.steps.length - 1]])
+					changeStatusOfElement(this.steps, smallerEle, UNSORTED)
+				}
 			}
 		}
 
@@ -131,6 +151,8 @@ export default class MergeSort implements IAlgorithm {
 		currentIndex: number,
 		leastIndex: number
 	): Bar[] => {
+		console.log()
+		eleToMove.status = LESSER
 		const modifiedStep = [...steps[steps.length - 1]]
 		const indexOfLesserEle = modifiedStep.findIndex(
 			ele => ele.value === eleToMove.value
diff --git a/src/app.scss b/src/app.scss
index b799f07..3b2c348 100644
--- a/src/app.scss
+++ b/src/app.scss
@@ -1,6 +1,30 @@
-.bar__container {
+.content {
+	height: 100vh;
 	display: flex;
-	flex-direction: row;
-	justify-content: center;
-	align-items: flex-end;
+	flex-direction: column;
+	&__barContainer {
+		height: 500px;
+		// flex: 1;
+		display: flex;
+		flex-direction: row;
+		justify-content: center;
+		align-content: flex-end;
+	}
+
+	&__controls {
+		height: 200px;
+		flex: 1;
+	}
+}
+
+.card {
+	will-change: transform, height, opacity;
+	margin: 0;
+	padding: 0;
+}
+
+.bar {
+	// width: 5px;
+	/* border-radius: 5px; */
+	box-shadow: 0px 10px 25px -10px rgba(0, 0, 0, 0.2);
 }
diff --git a/src/components/Bar.tsx b/src/components/Bar.tsx
index 1d1042e..c89ee83 100644
--- a/src/components/Bar.tsx
+++ b/src/components/Bar.tsx
@@ -9,12 +9,26 @@ interface IProps {
 
 const Bar: React.FC<IProps> = ({ value, status }: IProps) => {
 	const barStyle = {
+		display: 'flex',
+		alignItems: 'flex-end',
+		justifyContent: 'center',
 		height: value,
 		width: 5,
 		margin: 2.5,
-		backgroundColor: BarColors[status]
+		backgroundColor: BarColors[status],
+		// border: `1px solid ${BarColors[status]}`,
+		fontSize: 8,
+		color: 'white',
+		padding: 2
+		// backgroundImage:
+		// 	'linear-gradient(180deg, rgba(247,92,92,1) 0%, rgba(238,174,202,1) 36%, rgba(148,233,209,1) 100%)',
+		// backgroundClip: 'text'
 	}
-	return <div style={barStyle}></div>
+	return (
+		<div className='bar' style={barStyle}>
+			{value}
+		</div>
+	)
 }
 
 export default Bar
diff --git a/src/hooks/useSort.tsx b/src/hooks/useSort.tsx
index 9225f20..c72d7dc 100644
--- a/src/hooks/useSort.tsx
+++ b/src/hooks/useSort.tsx
@@ -3,13 +3,15 @@ import Bar from 'src/utils/Bar'
 import randomArrayGenerator from 'src/utils/randomArrayGenerator'
 import { ISortingAlgorithm, IState } from 'src/utils/interface'
 
-const initailArray = randomArrayGenerator(10)
+const arrSize = 10
+
+const initailArray = randomArrayGenerator(arrSize)
 
 const initialState: IState = {
 	steps: [[...initailArray]],
 	currentStep: 0,
 	timeouts: [],
-	delay: 50
+	delay: 200
 }
 
 const useSort = (
@@ -39,6 +41,7 @@ const useSort = (
 	}
 
 	const sort = (): void => {
+		console.log(state.steps)
 		let i = 0
 		const timeouts = []
 
@@ -69,13 +72,15 @@ const useSort = (
 
 	const reset = (): void => {
 		cancel()
-		const newArray = randomArrayGenerator(10)
+		const newArray = randomArrayGenerator(arrSize)
 		const newSteps = sortingAlgorithm.sort(newArray)
+
+		console.log('STEPS :: ', newSteps)
 		setState({
 			steps: [...newSteps],
 			currentStep: 0,
 			timeouts: [],
-			delay: 50
+			delay: 200
 		})
 	}
 
diff --git a/src/utils/BarColors.ts b/src/utils/BarColors.ts
index bf58011..9d446a7 100644
--- a/src/utils/BarColors.ts
+++ b/src/utils/BarColors.ts
@@ -3,10 +3,11 @@ import { BarStatus } from 'src/utils/enum'
 const BarColors = {
 	[BarStatus.ACTIVE]: 'orange',
 	[BarStatus.LESSER]: 'red',
-	[BarStatus.GREATER]: 'green',
-	[BarStatus.SORTED]: 'green',
-	[BarStatus.UNSORTED]: 'grey',
-	[BarStatus.PIVOT]: 'yellow'
+	[BarStatus.GREATER]: '#a4fba6',
+	[BarStatus.SORTED]: '	#0f9200',
+	[BarStatus.UNSORTED]: 'black',
+	[BarStatus.PIVOT]: 'yellow',
+	[BarStatus.UNSWAPPED]: '#ffc87c'
 }
 
 export default BarColors
diff --git a/src/utils/enum.ts b/src/utils/enum.ts
index ae74cab..2a25125 100644
--- a/src/utils/enum.ts
+++ b/src/utils/enum.ts
@@ -4,5 +4,6 @@ export enum BarStatus {
 	GREATER = 'GREATER',
 	SORTED = 'SORTED',
 	UNSORTED = 'UNSORTED',
-	PIVOT = 'PIVOT'
+	PIVOT = 'PIVOT',
+	UNSWAPPED = 'UNSWAPPED'
 }
diff --git a/src/utils/randomArrayGenerator.ts b/src/utils/randomArrayGenerator.ts
index 0f4bffa..90bd98d 100644
--- a/src/utils/randomArrayGenerator.ts
+++ b/src/utils/randomArrayGenerator.ts
@@ -5,14 +5,14 @@ const generateRandomSetOfNumbers = (sizeOfArray: number): Set<number> => {
 	const set = new Set<number>()
 
 	while (set.size < sizeOfArray) {
-		const randomNumber = Math.floor(Math.random() * (sizeOfArray * 5)) + 10
+		const randomNumber = Math.floor(Math.random() * (sizeOfArray * 20)) + 10
 		set.add(randomNumber)
 	}
 
 	return set
 }
 
-const randomArrayGenerator = (sizeOfArray: number): Array<Bar> => {
+const randomArrayGenerator = (sizeOfArray?: number | 15): Array<Bar> => {
 	const randomArray = Array.from(generateRandomSetOfNumbers(sizeOfArray))
 	return randomArray.map(height => new Bar(height, BarStatus.UNSORTED))
 }
diff --git a/yarn.lock b/yarn.lock
index 8f8523a..5940695 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -859,7 +859,7 @@
     "@babel/helper-validator-option" "^7.12.1"
     "@babel/plugin-transform-typescript" "^7.12.1"
 
-"@babel/runtime@^7.12.5", "@babel/runtime@^7.8.4":
+"@babel/runtime@^7.12.5", "@babel/runtime@^7.3.1", "@babel/runtime@^7.8.4":
   version "7.12.5"
   resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e"
   integrity sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==
@@ -2433,6 +2433,11 @@ currently-unhandled@^0.4.1:
   dependencies:
     array-find-index "^1.0.1"
 
+d3-ease@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-2.0.0.tgz#fd1762bfca00dae4bacea504b1d628ff290ac563"
+  integrity sha512-68/n9JWarxXkOWMshcT5IcjbB+agblQUaIsbnXmrzejn2O82n3p2A9R2zEB9HIEFWKFwPAEDDN8gR0VdSAyyAQ==
+
 dashdash@^1.12.0:
   version "1.14.1"
   resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
@@ -5426,7 +5431,7 @@ progress@^2.0.0:
   resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
   integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
 
-prop-types@^15.7.2:
+prop-types@^15.5.8, prop-types@^15.7.2:
   version "15.7.2"
   resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
   integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
@@ -5527,6 +5532,14 @@ react-is@^16.8.1:
   resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
   integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
 
+react-spring@^8.0.27:
+  version "8.0.27"
+  resolved "https://registry.yarnpkg.com/react-spring/-/react-spring-8.0.27.tgz#97d4dee677f41e0b2adcb696f3839680a3aa356a"
+  integrity sha512-nDpWBe3ZVezukNRandTeLSPcwwTMjNVu1IDq9qA/AMiUqHuRN4BeSWvKr3eIxxg1vtiYiOLy4FqdfCP5IoP77g==
+  dependencies:
+    "@babel/runtime" "^7.3.1"
+    prop-types "^15.5.8"
+
 react@^17.0.1:
   version "17.0.1"
   resolved "https://registry.yarnpkg.com/react/-/react-17.0.1.tgz#6e0600416bd57574e3f86d92edba3d9008726127"

From 2747259e564bf03b9736a2b4c46799ba35ab39eb Mon Sep 17 00:00:00 2001
From: bkrmadtya <karki.bikram007@gmail.com>
Date: Sun, 31 Jan 2021 00:09:16 +0200
Subject: [PATCH 2/4] fix: removed optional flag from the parameter of the
 randomArrayGenerator function

---
 src/utils/randomArrayGenerator.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/utils/randomArrayGenerator.ts b/src/utils/randomArrayGenerator.ts
index 90bd98d..641a26a 100644
--- a/src/utils/randomArrayGenerator.ts
+++ b/src/utils/randomArrayGenerator.ts
@@ -12,7 +12,7 @@ const generateRandomSetOfNumbers = (sizeOfArray: number): Set<number> => {
 	return set
 }
 
-const randomArrayGenerator = (sizeOfArray?: number | 15): Array<Bar> => {
+const randomArrayGenerator = (sizeOfArray: number): Array<Bar> => {
 	const randomArray = Array.from(generateRandomSetOfNumbers(sizeOfArray))
 	return randomArray.map(height => new Bar(height, BarStatus.UNSORTED))
 }

From ee0703e4da721b51c6bae625398746f243404b7f Mon Sep 17 00:00:00 2001
From: bkrmadtya <karki.bikram007@gmail.com>
Date: Sun, 31 Jan 2021 00:09:29 +0200
Subject: [PATCH 3/4] feat: commented extra step

---
 src/algorithms/MergeSort.ts | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/src/algorithms/MergeSort.ts b/src/algorithms/MergeSort.ts
index 8f0ddcd..e12a188 100644
--- a/src/algorithms/MergeSort.ts
+++ b/src/algorithms/MergeSort.ts
@@ -49,17 +49,17 @@ export default class MergeSort implements IAlgorithm {
 
 			const greaterEle = isRightSmaller ? leftArr[0] : rightArr[0]
 
-			this.steps.push([...this.steps[this.steps.length - 1]])
-			changeStatusOfElement(
-				this.steps,
-				smallerEle,
-				isRightSmaller ? LESSER : GREATER
-			)
-			changeStatusOfElement(
-				this.steps,
-				greaterEle,
-				isRightSmaller ? LESSER : GREATER
-			)
+			// this.steps.push([...this.steps[this.steps.length - 1]])
+			// changeStatusOfElement(
+			// 	this.steps,
+			// 	smallerEle,
+			// 	isRightSmaller ? LESSER : GREATER
+			// )
+			// changeStatusOfElement(
+			// 	this.steps,
+			// 	greaterEle,
+			// 	isRightSmaller ? LESSER : GREATER
+			// )
 
 			sortedArr.push(smallerEle)
 

From 4b209fe1b08493602d11d36b184d1904a1eb85c8 Mon Sep 17 00:00:00 2001
From: bkrmadtya <karki.bikram007@gmail.com>
Date: Sun, 31 Jan 2021 00:11:53 +0200
Subject: [PATCH 4/4] feat: changed style of the bar container to align items
 to flex end

---
 src/app.scss | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/app.scss b/src/app.scss
index 3b2c348..63c241a 100644
--- a/src/app.scss
+++ b/src/app.scss
@@ -8,7 +8,7 @@
 		display: flex;
 		flex-direction: row;
 		justify-content: center;
-		align-content: flex-end;
+		align-items: flex-end;
 	}
 
 	&__controls {
