import React, { useState, useEffect } from "react";
import { makeStyles } from "@material-ui/styles";
// This function from @material-ui/styles help create css
const userStyle = makeStyles({
container: {
display: "flex",
justifyContent: "center",
alignItems: "flex-end",
height: "100%",
border: "2px solid lightgray"
},
bar: {
margin: "1px"
}
});
// Initializes a random array based on props given (min, max, amt)
const initArray = (min, max, amount) => {
let arr = [];
for (let i = 0; i < amount; i++)
arr.push(Math.floor(Math.random() * max) + min);
return arr;
};
// Main sorting array. Change this for different algorithms.
const BubbleSort = props => {
// Make our styles first with useStyles()
const classes = userStyle();
// useState is used to create "state" variables in function components which have no state.
// It works like this:
// const [var, targetMethod] = useState(arg from targetMethod);
// Object.assign(target, source) (makes an empty array from initArray return val)
const [masterArr] = useState(Object.assign([], initArray(1, 100, 50)));
// "array" var will hold the sorted array
const [array, setArray] = useState([]);
// Finds max val in array for scaling bars
const [maxVal, setMaxVal] = useState(0);
// sortingIndex is used when drawing the bars.
const [sortingIndex, setSortingIndex] = useState(0);
// Use useEffect() in place of componentDidMount() and
// componentDidUpdate() to handle "side effects".
// Side effects are modifications to the DOM that you want to
// do after updating the DOM (render) without having to re-render
useEffect(() => {
// "..." means unpack the variable into an array
setMaxVal(Math.max(...masterArr));
// Call function which sets array "state" variable
setArray(masterArr);
// Create a copy of masterArray for modifying
let masterCopy = Object.assign([], masterArr);
Sort(masterCopy);
}, []);
// Bubblesort algorithm
const Sort = arr => {
for (let i = 0; i < arr.length - 1; i++) {
for (let j = 0; j < arr.length - (i - 1); j++) {
setTimeout(() => {
// Swap if necessary
if (arr[j] > arr[j + 1]) {
let tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
// Set array to most recent sort
setArray(Object.assign([], arr));
// Update sorting index
setSortingIndex(j);
}
}, 10);
}
}
};
return (
// JSX tag for doing array mapping and conditional styling
<>
<div className={classes.container}>
{/* Maps each element of array with a value and index*/}
{array.map((value, index) => (
// Each bar is just a colored div
<div
className={classes.bar}
style={{
background: sortingIndex === (index - 1) ? "red" : "green",
width: `${100 / array.length}%`,
// Scale height based on maxVal in array
height: `${(value * 100) / maxVal}%`
}}
/>
))}
</div>
</>
);
};
export default BubbleSort;