diff --git a/Client/src/Components/Charts/CustomGauge/index.css b/Client/src/Components/Charts/CustomGauge/index.css new file mode 100644 index 000000000..e69de29bb diff --git a/Client/src/Components/Charts/CustomGauge/index.jsx b/Client/src/Components/Charts/CustomGauge/index.jsx new file mode 100644 index 000000000..d00ab7f5f --- /dev/null +++ b/Client/src/Components/Charts/CustomGauge/index.jsx @@ -0,0 +1,108 @@ +import { useTheme } from "@emotion/react"; +import { useEffect, useState } from "react"; +import { Box, Typography } from "@mui/material"; +import PropTypes from "prop-types"; +import "./index.css"; + +/** + * A Performant SVG based circular gauge + * + * @component + * @param {Object} props - Component properties + * @param {number} [props.progress=0] - Progress percentage (0-100) + * @param {number} [props.radius=60] - Radius of the gauge circle + * @param {string} [props.color="#000000"] - Color of the progress stroke + * @param {number} [props.strokeWidth=15] - Width of the gauge stroke + * + * @example + * + * + * @returns {React.ReactElement} Rendered CustomGauge component + */ +const CustomGauge = ({ + progress = 0, + radius = 60, + color = "#000000", + strokeWidth = 15, +}) => { + // Calculate the length of the stroke for the circle + const circumference = 2 * Math.PI * radius; + const totalSize = radius * 2 + strokeWidth * 2; // This is the total size of the SVG, needed for the viewBox + const strokeLength = (progress / 100) * circumference; + const [offset, setOffset] = useState(circumference); + const theme = useTheme(); + + // Handle initial animation + useEffect(() => { + setOffset(circumference); + const timer = setTimeout(() => { + setOffset(circumference - strokeLength); + }, 100); + + return () => clearTimeout(timer); + }, [progress, circumference, strokeLength]); + + return ( + + + + + + + + {`${progress}%`} + + + ); +}; + +export default CustomGauge; + +CustomGauge.propTypes = { + progress: PropTypes.number, + radius: PropTypes.number, + color: PropTypes.string, + strokeWidth: PropTypes.number, +};