Files
Checkmate/Client/src/Components/Charts/MonitorDetailsAreaChart/index.jsx
T

169 lines
4.5 KiB
React

import PropTypes from "prop-types";
import {
AreaChart,
Area,
XAxis,
Tooltip,
CartesianGrid,
ResponsiveContainer,
} from "recharts";
import { Box, Stack, Typography } from "@mui/material";
import { useTheme } from "@emotion/react";
import { useMemo } from "react";
import "./index.css";
import { useSelector } from "react-redux";
import { formatDateWithTz } from "../../../Utils/timeUtils";
const CustomToolTip = ({ active, payload, label }) => {
const uiTimezone = useSelector((state) => state.ui.timezone);
const theme = useTheme();
if (active && payload && payload.length) {
return (
<Box
className="area-tooltip"
sx={{
backgroundColor: theme.palette.background.main,
border: 1,
borderColor: theme.palette.border.dark,
borderRadius: theme.shape.borderRadius,
py: theme.spacing(2),
px: theme.spacing(4),
}}
>
<Typography
sx={{
color: theme.palette.text.tertiary,
fontSize: 12,
fontWeight: 500,
}}
>
{formatDateWithTz(label, "ddd, MMMM D, YYYY, h:mm A", uiTimezone)}
</Typography>
<Box mt={theme.spacing(1)}>
<Box
display="inline-block"
width={theme.spacing(4)}
height={theme.spacing(4)}
backgroundColor={theme.palette.primary.main}
sx={{ borderRadius: "50%" }}
/>
<Stack
display="inline-flex"
direction="row"
justifyContent="space-between"
ml={theme.spacing(3)}
sx={{
"& span": {
color: theme.palette.text.tertiary,
fontSize: 11,
fontWeight: 500,
},
}}
>
<Typography component="span" sx={{ opacity: 0.8 }}>
Response Time
</Typography>{" "}
<Typography component="span">
{payload[0].payload.originalResponseTime}
<Typography component="span" sx={{ opacity: 0.8 }}>
{" "}
ms
</Typography>
</Typography>
</Stack>
</Box>
{/* Display original value */}
</Box>
);
}
return null;
};
const MonitorDetailsAreaChart = ({ checks }) => {
const uiTimezone = useSelector((state) => state.ui.timezone);
const formatDate = (timestamp) => {
return formatDateWithTz(timestamp, "HH:mm:ss", uiTimezone);
};
const memoizedChecks = useMemo(() => checks, [checks[0]]);
const theme = useTheme();
return (
<ResponsiveContainer width="100%" minWidth={25} height={220}>
<AreaChart
width="100%"
height="100%"
data={memoizedChecks}
margin={{
top: 10,
right: 0,
left: 0,
bottom: 0,
}}
>
<CartesianGrid
stroke={theme.palette.border.light}
strokeWidth={1}
strokeOpacity={1}
fill="transparent"
vertical={false}
/>
<defs>
<linearGradient id="colorUv" x1="0" y1="0" x2="0" y2="1">
<stop
offset="0%"
stopColor={theme.palette.primary.main}
stopOpacity={0.8}
/>
<stop
offset="100%"
stopColor={theme.palette.primary.light}
stopOpacity={0}
/>
</linearGradient>
</defs>
<XAxis
stroke={theme.palette.border.dark}
dataKey="createdAt"
tickFormatter={formatDate}
tick={{ fontSize: "13px" }}
tickLine={false}
height={18}
/>
<Tooltip
cursor={{ stroke: theme.palette.border.light }}
content={<CustomToolTip />}
/>
<Area
type="monotone"
dataKey="responseTime"
stroke={theme.palette.primary.main}
fill="url(#colorUv)"
strokeWidth={1.5}
activeDot={{ stroke: theme.palette.background.main, r: 5 }}
/>
</AreaChart>
</ResponsiveContainer>
);
};
MonitorDetailsAreaChart.propTypes = {
checks: PropTypes.array,
};
CustomToolTip.propTypes = {
active: PropTypes.bool,
payload: PropTypes.arrayOf(
PropTypes.shape({
payload: PropTypes.shape({
originalResponseTime: PropTypes.number.isRequired,
}).isRequired,
})
),
label: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
};
export default MonitorDetailsAreaChart;