-
Notifications
You must be signed in to change notification settings - Fork 209
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat/fe/infrastructure details, resolves #1068 #1167
Changes from 19 commits
93d96b9
0832320
fbdd3c1
d2f42f4
ca9ca4f
55e13d7
49d81cf
92ba0d8
924c799
6a0d61b
a0c7346
e3c13d9
9cf2be7
0c194a0
7f380ce
5a2c6a9
9e7e13b
217ae50
7223ca3
dbe174d
8b73955
b1449d3
9bbcaaf
1f5b5dd
8bbb001
11cc283
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
const ObjectId = (string) => string; | ||
const ISODate = (string) => string; | ||
|
||
// Helper to generate random percentage between 0.1 and 1.0 | ||
const randomPercent = () => Number((Math.random() * 0.9 + 0.1).toFixed(2)); | ||
|
||
// Create base timestamp and increment by 5 minutes for each entry | ||
const baseTime = new Date("2024-11-15T07:00:00.000Z"); | ||
const checks = Array.from({ length: 20 }, (_, index) => { | ||
const timestamp = new Date(baseTime.getTime() + index * 5 * 60 * 1000); | ||
|
||
return { | ||
_id: ObjectId(`6736f4f449e23954c8b89a${index.toString(16).padStart(2, "0")}`), | ||
monitorId: ObjectId("6736e6c2939f02e0ca519465"), | ||
status: true, | ||
responseTime: Math.floor(Math.random() * 50) + 80, // Random between 80-130ms | ||
statusCode: 200, | ||
message: "OK", | ||
cpu: { | ||
physical_core: 0, | ||
logical_core: 0, | ||
frequency: 0, | ||
temperature: 0, | ||
free_percent: 0, | ||
usage_percent: randomPercent(), | ||
_id: ObjectId(`6736f4f449e23954c8b89b${index.toString(16).padStart(2, "0")}`), | ||
}, | ||
memory: { | ||
total_bytes: 0, | ||
available_bytes: 0, | ||
used_bytes: 0, | ||
usage_percent: randomPercent(), | ||
_id: ObjectId(`6736f4f449e23954c8b89c${index.toString(16).padStart(2, "0")}`), | ||
}, | ||
disk: [ | ||
{ | ||
read_speed_bytes: 0, | ||
write_speed_bytes: 0, | ||
total_bytes: 0, | ||
free_bytes: 0, | ||
usage_percent: randomPercent(), | ||
_id: ObjectId(`6736f4f449e23954c8b89d${index.toString(16).padStart(2, "0")}`), | ||
}, | ||
], | ||
host: { | ||
os: "", | ||
platform: "", | ||
kernel_version: "", | ||
_id: ObjectId(`6736f4f449e23954c8b89e${index.toString(16).padStart(2, "0")}`), | ||
}, | ||
errors: [], | ||
expiry: ISODate(new Date(timestamp.getTime() + 24 * 60 * 60 * 1000).toISOString()), | ||
createdAt: ISODate(timestamp.toISOString()), | ||
updatedAt: ISODate(timestamp.toISOString()), | ||
__v: 0, | ||
}; | ||
}); | ||
|
||
export default checks; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
import { | ||
AreaChart, | ||
Area, | ||
XAxis, | ||
YAxis, | ||
CartesianGrid, | ||
Tooltip, | ||
ResponsiveContainer, | ||
} from "recharts"; | ||
import { createGradient } from "../Utils/gradientUtils"; | ||
import PropTypes from "prop-types"; | ||
import { useTheme } from "@mui/material"; | ||
|
||
/** | ||
* CustomAreaChart component for rendering an area chart with optional gradient and custom ticks. | ||
* | ||
* @param {Object} props - The properties object. | ||
* @param {Array} props.data - The data array for the chart. | ||
* @param {string} props.xKey - The key for the x-axis data. | ||
* @param {string} props.yKey - The key for the y-axis data. | ||
* @param {Object} [props.xTick] - Custom tick component for the x-axis. | ||
* @param {Object} [props.yTick] - Custom tick component for the y-axis. | ||
* @param {string} [props.strokeColor] - The stroke color for the area. | ||
* @param {string} [props.fillColor] - The fill color for the area. | ||
* @param {boolean} [props.gradient=false] - Whether to apply a gradient fill. | ||
* @param {string} [props.gradientDirection="vertical"] - The direction of the gradient. | ||
* @param {string} [props.gradientStartColor] - The start color of the gradient. | ||
* @param {string} [props.gradientEndColor] - The end color of the gradient. | ||
* @param {Object} [props.customTooltip] - Custom tooltip component. | ||
* @returns {JSX.Element} The rendered area chart component. | ||
* | ||
* @example | ||
* // Example usage of CustomAreaChart | ||
* import React from 'react'; | ||
* import CustomAreaChart from './CustomAreaChart'; | ||
* import { TzTick, PercentTick, InfrastructureTooltip } from './chartUtils'; | ||
* | ||
* const data = [ | ||
* { createdAt: '2023-01-01T00:00:00Z', cpu: { usage_percent: 0.5 } }, | ||
* { createdAt: '2023-01-01T01:00:00Z', cpu: { usage_percent: 0.6 } }, | ||
* // more data points... | ||
* ]; | ||
* | ||
* const MyChartComponent = () => { | ||
* return ( | ||
* <CustomAreaChart | ||
* data={data} | ||
* xKey="createdAt" | ||
* yKey="cpu.usage_percent" | ||
* xTick={<TzTick />} | ||
* yTick={<PercentTick />} | ||
* strokeColor="#8884d8" | ||
* fillColor="#8884d8" | ||
* gradient={true} | ||
* gradientStartColor="#8884d8" | ||
* gradientEndColor="#82ca9d" | ||
* customTooltip={({ active, payload, label }) => ( | ||
* <InfrastructureTooltip | ||
* label={label?.toString() ?? ""} | ||
* yKey="cpu.usage_percent" | ||
* yLabel="CPU Usage" | ||
* active={active} | ||
* payload={payload} | ||
* /> | ||
* )} | ||
* /> | ||
* ); | ||
* }; | ||
* | ||
* export default MyChartComponent; | ||
*/ | ||
const CustomAreaChart = ({ | ||
data, | ||
dataKey, | ||
xKey, | ||
yKey, | ||
xTick, | ||
yTick, | ||
strokeColor, | ||
fillColor, | ||
gradient = false, | ||
gradientDirection = "vertical", | ||
gradientStartColor, | ||
gradientEndColor, | ||
customTooltip, | ||
}) => { | ||
const theme = useTheme(); | ||
const gradientId = `gradient-${Math.random().toString(36).slice(2, 9)}`; | ||
return ( | ||
<ResponsiveContainer | ||
width="100%" | ||
height="80%" // FE team HELP! Why does this overflow if set to 100%? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yo, I heard you like responsive containers! Let me drop some knowledge about that height issue! 🎵 The height overflow when set to "100%" is a common issue with recharts' ResponsiveContainer. It occurs because the container needs a parent with a defined height. Here are two solutions:
.chart-wrapper {
height: 400px; /* or any desired height */
}
<ResponsiveContainer
width="100%"
- height="80%"
+ aspect={2} // This will maintain 2:1 aspect ratio
> |
||
<AreaChart data={data}> | ||
<XAxis | ||
dataKey={xKey} | ||
{...(xTick && { tick: xTick })} | ||
/> | ||
<YAxis | ||
dataKey={yKey} | ||
{...(yTick && { tick: yTick })} | ||
/> | ||
{gradient === true && | ||
createGradient({ | ||
id: gradientId, | ||
startColor: gradientStartColor, | ||
endColor: gradientEndColor, | ||
direction: gradientDirection, | ||
})} | ||
<CartesianGrid | ||
stroke={theme.palette.border.light} | ||
strokeWidth={1} | ||
strokeOpacity={1} | ||
fill="transparent" | ||
vertical={false} | ||
/> | ||
<Area | ||
type="monotone" | ||
dataKey={dataKey} | ||
stroke={strokeColor} | ||
fill={gradient === true ? `url(#${gradientId})` : fillColor} | ||
/> | ||
|
||
{customTooltip ? ( | ||
<Tooltip | ||
cursor={{ stroke: theme.palette.border.light }} | ||
content={customTooltip} | ||
wrapperStyle={{ pointerEvents: "none" }} | ||
/> | ||
) : ( | ||
<Tooltip /> | ||
)} | ||
</AreaChart> | ||
</ResponsiveContainer> | ||
); | ||
}; | ||
|
||
CustomAreaChart.propTypes = { | ||
data: PropTypes.array.isRequired, | ||
dataKey: PropTypes.string.isRequired, | ||
xTick: PropTypes.object, // Recharts takes an instance of component, so we can't pass the component itself | ||
yTick: PropTypes.object, // Recharts takes an instance of component, so we can't pass the component itself | ||
xKey: PropTypes.string.isRequired, | ||
yKey: PropTypes.string.isRequired, | ||
fillColor: PropTypes.string, | ||
strokeColor: PropTypes.string, | ||
gradient: PropTypes.bool, | ||
gradientDirection: PropTypes.string, | ||
gradientStartColor: PropTypes.string, | ||
gradientEndColor: PropTypes.string, | ||
customTooltip: PropTypes.func, | ||
}; | ||
|
||
export default CustomAreaChart; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
.radial-chart { | ||
position: relative; | ||
display: inline-block; | ||
} | ||
|
||
.radial-chart-base { | ||
opacity: 0.3; | ||
} | ||
|
||
.radial-chart-progress { | ||
transform: rotate(-90deg); | ||
transform-origin: center; | ||
transition: stroke-dashoffset 1.5s ease-in-out; | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -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 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* <CustomGauge | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* progress={75} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* radius={50} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* color="#00ff00" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* strokeWidth={10} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* @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(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Yo, we need some input validation up in here! The progress value needs validation to prevent wonky gauge displays. Also, those calculations could be optimized with useMemo. + import { useMemo } from "react";
const CustomGauge = ({
progress = 0,
radius = 60,
color = "#000000",
strokeWidth = 15,
}) => {
+ if (progress < 0 || progress > 100) {
+ throw new Error("Progress must be between 0 and 100");
+ }
- const circumference = 2 * Math.PI * radius;
- const totalSize = radius * 2 + strokeWidth * 2;
- const strokeLength = (progress / 100) * circumference;
+ const { circumference, totalSize, strokeLength } = useMemo(() => ({
+ circumference: 2 * Math.PI * radius,
+ totalSize: radius * 2 + strokeWidth * 2,
+ strokeLength: (progress / 100) * (2 * Math.PI * radius)
+ }), [radius, strokeWidth, progress]); 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Handle initial animation | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
useEffect(() => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
setOffset(circumference); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const timer = setTimeout(() => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
setOffset(circumference - strokeLength); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, 100); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return () => clearTimeout(timer); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, [progress, circumference, strokeLength]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<Box | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
className="radial-chart" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
width={radius} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
height={radius} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<svg | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
viewBox={`0 0 ${totalSize} ${totalSize}`} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
width={radius} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
height={radius} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<circle | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
className="radial-chart-base" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
stroke={theme.palette.background.fill} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
strokeWidth={strokeWidth} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fill="none" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
cx={totalSize / 2} // Center the circle | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
cy={totalSize / 2} // Center the circle | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
r={radius} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<circle | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
className="radial-chart-progress" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
stroke={color} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
strokeWidth={strokeWidth} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
strokeDasharray={`${circumference} ${circumference}`} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
strokeDashoffset={offset} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
strokeLinecap="round" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fill="none" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
cx={totalSize / 2} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
cy={totalSize / 2} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
r={radius} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</svg> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+61
to
+87
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Let's make this accessible, fam! The SVG needs ARIA attributes and a title for screen readers. <svg
viewBox={`0 0 ${totalSize} ${totalSize}`}
width={radius}
height={radius}
+ role="img"
+ aria-label={`Progress gauge showing ${progress.toFixed(2)}%`}
>
+ <title>Progress Gauge</title>
<circle 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<Typography | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
className="radial-chart-text" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
style={{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
position: "absolute", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
top: "50%", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
left: "50%", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
transform: "translate(-50%, -50%)", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
...theme.typography.body2, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fill: theme.typography.body2.color, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{`${progress.toFixed(2)}%`} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</Typography> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</Box> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
export default CustomGauge; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
CustomGauge.propTypes = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
progress: PropTypes.number, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
radius: PropTypes.number, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
color: PropTypes.string, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
strokeWidth: PropTypes.number, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+108
to
+113
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Yo, let's lock down these PropTypes! Make these PropTypes more strict to catch bugs early in development. CustomGauge.propTypes = {
- progress: PropTypes.number,
- radius: PropTypes.number,
- color: PropTypes.string,
- strokeWidth: PropTypes.number,
+ progress: PropTypes.number.isRequired,
+ radius: PropTypes.number,
+ color: PropTypes.string,
+ strokeWidth: PropTypes.oneOf([PropTypes.number, PropTypes.string]),
};
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Mom's spaghetti moment: Let's make those gradient IDs more reliable! 🍝
Using
Math.random()
for gradient IDs could potentially cause duplicates. Also, these gradients should be cleaned up when the component unmounts.Consider using a more robust approach:
Also applies to: 103-109