feat: final touches on Gauge Component

This commit is contained in:
Caio Cabral
2024-11-17 15:56:42 -05:00
parent 66cd813695
commit c542e537ab
3 changed files with 33 additions and 93 deletions

View File

@@ -1,34 +1,38 @@
import { RadialBarChart, RadialBar, ResponsiveContainer, Text, Legend } from "recharts";
import { RadialBarChart, RadialBar, ResponsiveContainer } from "recharts";
import PropTypes from "prop-types";
import { useTheme } from "@emotion/react";
const MINIMUM_VALUE = 0;
const MAXIMUM_VALUE = 100;
const CHART_MAXIMUM_DATA = {
value: MAXIMUM_VALUE,
fill: "transparent",
};
const PROGRESS_THRESHOLD = 50;
const DEFAULT_WIDTH = 60;
// const DEFAULT_CONTAINER_HEIGHT = 160;
// const TEXT_POSITIONS = {
// value: { x: "50%", y: "45%" },
// label: { x: "50%", y: "55%" },
// };
const RADIUS = "90%";
const RADIUS_SIZE = "90%";
const START_ANGLE = 90;
const CHART_RANGE = 360;
const RADIAL_BAR_CHART_PROPS = {
innerRadius: RADIUS,
outerRadius: RADIUS,
innerRadius: RADIUS_SIZE,
outerRadius: RADIUS_SIZE,
barSize: 6,
startAngle: START_ANGLE,
endAngle: START_ANGLE - CHART_RANGE,
margin: { top: 0, right: 0, bottom: 0, left: 0 },
};
const COMMON_RADIAL_BAR_PROPS = {
const RADIAL_BAR_PROPS = {
dataKey: "value",
cornerRadius: 8,
};
Gauge.propTypes = {
progressValue: PropTypes.number.isRequired,
width: PropTypes.number,
};
/**
* A circular gauge component that displays a progress value and text.
* The gauge fills based on the progress value and changes color at a 50% threshold.
@@ -36,61 +40,42 @@ const COMMON_RADIAL_BAR_PROPS = {
* @component
* @param {Object} props - Component props
* @param {number} props.progressValue - The value to display in the gauge (0-100)
* @param {string} props.displayText - The text to display below the progress value
* @param {number} [props.containerHeight=160] - Height of the gauge container in pixels
* @param {Object} [props.gaugeHeader] - Custom styles to apply to the progress value text
* @param {Object} [props.gaugeSubheader] - Custom styles to apply to the display text
*
* @param {number} props.width - Width of the gauge container in pixels
* @returns {JSX.Element} A circular gauge chart with progress value and text
*
* @example
* <Gauge
* progressValue={75}
* displayText="Completion"
* containerHeight={200}
* gaugeHeader={{ fontSize: '24px' }}
* gaugeSubheader={{ fill: 'gray' }}
* width={200}
* />
*/
const Gauge = ({
progressValue,
containerWidth,
// displayText,
// containerHeight,
// gaugeHeader,
// gaugeSubheader,
}) => {
function Gauge({ progressValue, width = DEFAULT_WIDTH }) {
const theme = useTheme();
const myProgressValue = Math.max(MINIMUM_VALUE, Math.min(progressValue, MAXIMUM_VALUE));
const chartColor =
progressValue > PROGRESS_THRESHOLD
? theme.palette.primary.main
: theme.palette.percentage.uptimePoor;
const chartData = [
{
value: MAXIMUM_VALUE,
fill: "transparent",
},
CHART_MAXIMUM_DATA,
{
value: myProgressValue,
fill:
progressValue > PROGRESS_THRESHOLD
? theme.palette.primary.main
: theme.palette.percentage.uptimePoor,
fill: chartColor,
},
];
const width = containerWidth ?? DEFAULT_WIDTH;
return (
<ResponsiveContainer
aspect={1}
width={width}
/* height={containerHeight ?? DEFAULT_CONTAINER_HEIGHT}
width={containerWidth} */
>
<RadialBarChart
{...RADIAL_BAR_CHART_PROPS}
data={chartData /* [{ ...DATA, fill: "#666666" }, { value: myProgressValue }] */}
data={chartData}
>
<RadialBar
{...COMMON_RADIAL_BAR_PROPS}
{...RADIAL_BAR_PROPS}
fill={
progressValue > PROGRESS_THRESHOLD
? theme.palette.primary.main
@@ -99,7 +84,6 @@ const Gauge = ({
background={{ fill: theme.palette.background.fill }}
label={{
position: "center",
fill: "#000000",
content: () => (
<text
x="50%"
@@ -107,47 +91,18 @@ const Gauge = ({
textAnchor="middle"
dominantBaseline="middle"
style={{
fontSize: "12px",
fill: "#000000",
...theme.typography.body1,
fill: theme.typography.body1.color,
}}
>{`${myProgressValue}%`}</text>
>
{`${myProgressValue}%`}
</text>
),
}}
/* data={[{ value: myProgressValue }]} */
/>
{/* <RadialBar
{...COMMON_RADIAL_BAR_PROPS}
data={DATA}
style={RADIAL_BAR_OVERLAY_PROPS}
/> */}
{/* TODO what is the text tag? */}
{/* <text
{...TEXT_POSITIONS.value}
role="text"
aria-label={`${myProgressValue}%`}
style={{ ...COMMON_HEADER_PROPS, ...theme.chart.header, ...gaugeHeader }}
>
{`${myProgressValue}%`}
</text>
<text
{...TEXT_POSITIONS.label}
role="text"
aria-label={`${displayText}`}
style={{ ...COMMON_HEADER_PROPS, ...theme.chart.subheader, ...gaugeSubheader }}
>
{`${displayText}`}
</text> */}
</RadialBarChart>
</ResponsiveContainer>
);
};
}
Gauge.propTypes = {
progressValue: PropTypes.number.isRequired,
displayText: PropTypes.string.isRequired,
containerHeight: PropTypes.number,
gaugeHeader: PropTypes.object,
gaugeSubheader: PropTypes.object,
};
export { Gauge };

View File

@@ -179,9 +179,6 @@ function Infrastructure() {
<Gauge
progressValue={row.cpu}
containerWidth={60}
/* displayText={row.cpu}
containerHeight={100}
containerWidth={100} */
/>
</TableCell>
<TableCell>

View File

@@ -32,19 +32,7 @@ const baseTheme = (palette) => ({
fontWeight: 400,
},
},
/* TODO take chart from here, it should live inside of the gauge, and get info from the theme */
chart: {
header: {
fontWeight: 400,
fill: palette.text.tertiary,
fontSize: typographyLevels.m,
},
subheader: {
fontWeight: 400,
fill: palette.text.tertiary,
fontSize: typographyLevels.xs,
},
},
spacing: 2,
/* TODO All these should live inside of a component*/
components: {