Merge branch 'develop' into 1067-fe-hardware-monitoring-create-hardware-monitor
This commit is contained in:
commit
b35fe8d616
4 files changed
+161
-12
No files matched your search
Generated
+12
-12
@@ -1725,9 +1725,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@remix-run/router": {
|
||||
"version": "1.20.0",
|
||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.20.0.tgz",
|
||||
"integrity": "sha512-mUnk8rPJBI9loFDZ+YzPGdeniYK+FTmRD1TMCz7ev2SNIozyKKpnGgsxO34u6Z4z/t0ITuu7voi/AshfsGsgFg==",
|
||||
"version": "1.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.21.0.tgz",
|
||||
"integrity": "sha512-xfSkCAchbdG5PnbrKqFWwia4Bi61nH+wm8wLEqfHDyp7Y3dZzgqS2itV8i4gAq9pC2HsTpwyBC6Ds8VHZ96JlA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
@@ -5442,12 +5442,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-router": {
|
||||
"version": "6.27.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.27.0.tgz",
|
||||
"integrity": "sha512-YA+HGZXz4jaAkVoYBE98VQl+nVzI+cVI2Oj/06F5ZM+0u3TgedN9Y9kmMRo2mnkSK2nCpNQn0DVob4HCsY/WLw==",
|
||||
"version": "6.28.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.28.0.tgz",
|
||||
"integrity": "sha512-HrYdIFqdrnhDw0PqG/AKjAqEqM7AvxCz0DQ4h2W8k6nqmc5uRBYDag0SBxx9iYz5G8gnuNVLzUe13wl9eAsXXg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@remix-run/router": "1.20.0"
|
||||
"@remix-run/router": "1.21.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
@@ -5457,13 +5457,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-router-dom": {
|
||||
"version": "6.27.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.27.0.tgz",
|
||||
"integrity": "sha512-+bvtFWMC0DgAFrfKXKG9Fc+BcXWRUO1aJIihbB79xaeq0v5UzfvnM5houGUm1Y461WVRcgAQ+Clh5rdb1eCx4g==",
|
||||
"version": "6.28.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.28.0.tgz",
|
||||
"integrity": "sha512-kQ7Unsl5YdyOltsPGl31zOjLrDv+m2VcIEcIHqYYD3Lp0UppLjrzcfJqDJwXxFw3TH/yvapbnUvPlAj7Kx5nbg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@remix-run/router": "1.20.0",
|
||||
"react-router": "6.27.0"
|
||||
"@remix-run/router": "1.21.0",
|
||||
"react-router": "6.28.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
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 DATA = [{ value: MAXIMUM_VALUE }];
|
||||
const PROGRESS_THRESHOLD = 50;
|
||||
const DEFAULT_CONTAINER_HEIGHT = 160;
|
||||
const TEXT_POSITIONS = {
|
||||
value: { x: "50%", y: "45%" },
|
||||
label: { x: "50%", y: "55%" },
|
||||
};
|
||||
const COMMON_RADIAL_BAR_PROPS = {
|
||||
minAngle: 15,
|
||||
clockWise: true,
|
||||
dataKey: "value",
|
||||
cornerRadius: 0,
|
||||
};
|
||||
|
||||
const RADIAL_BAR_CHART_PROPS = {
|
||||
cx: "50%",
|
||||
cy: "50%",
|
||||
innerRadius: "45%",
|
||||
outerRadius: "100%",
|
||||
startAngle: 90,
|
||||
endAngle: -270,
|
||||
};
|
||||
|
||||
const RADIAL_BAR_OVERLAY_PROPS = {
|
||||
transform: "rotate(180deg)",
|
||||
position: "absolute",
|
||||
top: "0",
|
||||
left: "0",
|
||||
};
|
||||
|
||||
const COMMON_HEADER_PROPS = {
|
||||
textAnchor: "middle",
|
||||
dominantBaseline: "middle",
|
||||
};
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @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
|
||||
*
|
||||
* @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' }}
|
||||
* />
|
||||
*/
|
||||
const Gauge = ({
|
||||
progressValue,
|
||||
displayText,
|
||||
containerHeight,
|
||||
gaugeHeader,
|
||||
gaugeSubheader,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
const myProgressValue = Math.max(MINIMUM_VALUE, Math.min(progressValue, MAXIMUM_VALUE));
|
||||
|
||||
return (
|
||||
<ResponsiveContainer height={containerHeight ?? DEFAULT_CONTAINER_HEIGHT}>
|
||||
<RadialBarChart
|
||||
{...RADIAL_BAR_CHART_PROPS}
|
||||
data={DATA}
|
||||
>
|
||||
<RadialBar
|
||||
{...COMMON_RADIAL_BAR_PROPS}
|
||||
fill={
|
||||
progressValue > PROGRESS_THRESHOLD
|
||||
? theme.palette.primary.main
|
||||
: theme.palette.percentage.uptimePoor
|
||||
}
|
||||
background={{ fill: theme.palette.background.fill }}
|
||||
data={[{ value: myProgressValue }]}
|
||||
/>
|
||||
<RadialBar
|
||||
{...COMMON_RADIAL_BAR_PROPS}
|
||||
data={DATA}
|
||||
style={RADIAL_BAR_OVERLAY_PROPS}
|
||||
/>
|
||||
<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 default Gauge;
|
||||
@@ -29,6 +29,18 @@ const darkTheme = createTheme({
|
||||
body1: { fontSize: 13, color: text.tertiary, fontWeight: 400 },
|
||||
body2: { fontSize: 12, color: text.tertiary, fontWeight: 400 },
|
||||
},
|
||||
chart: {
|
||||
header: {
|
||||
fontWeight: 400,
|
||||
fill: text.tertiary,
|
||||
fontSize: 11,
|
||||
},
|
||||
subheader: {
|
||||
fontWeight: 400,
|
||||
fill: text.tertiary,
|
||||
fontSize: 9,
|
||||
},
|
||||
},
|
||||
palette: {
|
||||
mode: "dark",
|
||||
primary: { main: "#1570ef" },
|
||||
|
||||
@@ -12,6 +12,7 @@ const background = {
|
||||
fill: "#F4F4F4",
|
||||
accent: "#f9fafb",
|
||||
};
|
||||
|
||||
const border = { light: "#eaecf0", dark: "#d0d5dd" };
|
||||
|
||||
const fontFamilyDefault =
|
||||
@@ -28,6 +29,18 @@ const lightTheme = createTheme({
|
||||
body1: { fontSize: 13, color: text.tertiary, fontWeight: 400 },
|
||||
body2: { fontSize: 12, color: text.tertiary, fontWeight: 400 },
|
||||
},
|
||||
chart: {
|
||||
header: {
|
||||
fontWeight: 400,
|
||||
fill: text.tertiary,
|
||||
fontSize: 11,
|
||||
},
|
||||
subheader: {
|
||||
fontWeight: 400,
|
||||
fill: text.tertiary,
|
||||
fontSize: 9,
|
||||
},
|
||||
},
|
||||
palette: {
|
||||
primary: { main: "#1570EF" },
|
||||
secondary: { main: "#F4F4F4", dark: "#e3e3e3", contrastText: "#475467" },
|
||||
|
||||
Reference in new issue
Block a user