Added null entries

This commit is contained in:
Daniel Cojocea
2024-09-10 17:43:43 -04:00
parent 34f0a1e067
commit db3c7e6b52
2 changed files with 132 additions and 17 deletions

View File

@@ -8,42 +8,144 @@ import {
} from "recharts";
import { useTheme } from "@emotion/react";
import { useMemo } from "react";
import { Box, Stack, Typography } from "@mui/material";
import { formatDate } from "../../../../Utils/timeUtils";
const config = {
accessibility: {
id: "accessibility",
text: "accessibility",
color: "primary",
},
bestPractices: {
id: "bestPractices",
text: "best practices",
color: "warning",
},
performance: {
id: "performance",
text: "performance",
color: "success",
},
seo: {
id: "seo",
text: "SEO",
color: "unresolved",
},
};
const PagespeedDetailsAreaChart = ({ data }) => {
const formatDate = (timestamp) => {
const date = new Date(timestamp);
return date.toLocaleTimeString("en-US", {
hour: "numeric",
minute: "2-digit",
hour12: true,
const CustomToolTip = ({ active, payload, label }) => {
const theme = useTheme();
if (active && payload && payload.length) {
return (
<Box
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,
}}
>
{formatDate(new Date(label))}
</Typography>
{Object.keys(config).map((key) => {
const { color } = config[key];
const dotColor = theme.palette[color].main;
return (
<Stack
key={`${key}-tooltip`}
direction="row"
alignItems="center"
gap={theme.spacing(3)}
mt={theme.spacing(1)}
sx={{
"& span": {
color: theme.palette.text.tertiary,
fontSize: 11,
fontWeight: 500,
},
}}
>
<Box
width={theme.spacing(4)}
height={theme.spacing(4)}
backgroundColor={dotColor}
sx={{ borderRadius: "50%" }}
/>
<Typography
component="span"
textTransform="capitalize"
sx={{ opacity: 0.8 }}
>
{config[key].text}
</Typography>{" "}
<Typography component="span">
{payload[0].payload[key]}
</Typography>
</Stack>
);
})}
</Box>
);
}
return null;
};
const processDataWithGaps = (data, interval) => {
if (data.length === 0) return [];
let formattedData = [];
let last = new Date(data[0].createdAt).getTime();
// Helper function to add a null entry
const addNullEntry = (timestamp) => {
formattedData.push({
accessibility: "N/A",
bestPractices: "N/A",
performance: "N/A",
seo: "N/A",
createdAt: timestamp,
});
};
const memoizedData = useMemo(() => data, [data[0]]);
data.forEach((entry) => {
const current = new Date(entry.createdAt).getTime();
if (current - last > interval * 2) {
// Insert null entries for each interval
let temp = last + interval;
while (temp < current) {
addNullEntry(new Date(temp).toISOString());
temp += interval;
}
}
formattedData.push(entry);
last = current;
});
return formattedData;
};
const PagespeedDetailsAreaChart = ({ data, interval }) => {
const theme = useTheme();
const memoizedData = useMemo(
() => processDataWithGaps(data, interval),
[data]
);
return (
<ResponsiveContainer width="100%" minWidth={25} height={220}>
<ResponsiveContainer width="100%" minWidth={25} height={215}>
<AreaChart
width="100%"
height="100%"
@@ -60,17 +162,28 @@ const PagespeedDetailsAreaChart = ({ data }) => {
<XAxis
stroke={theme.palette.border.dark}
dataKey="createdAt"
tickFormatter={formatDate}
tickFormatter={(timestamp) =>
formatDate(new Date(timestamp), {
year: undefined,
month: undefined,
day: undefined,
})
}
tick={{
fontSize: 12,
fontSize: 11,
fontWeight: 100,
opacity: 0.8,
stroke: theme.palette.text.tertiary,
}}
tickLine={false}
minTickGap={20}
height={18}
interval="preserveEnd"
/>
<Tooltip
cursor={{ stroke: theme.palette.border.light }}
content={<CustomToolTip />}
/>
<Tooltip />
<defs>
{Object.values(config).map(({ id, color }) => {
const startColor = theme.palette[color].main;
@@ -87,17 +200,18 @@ const PagespeedDetailsAreaChart = ({ data }) => {
{Object.keys(config).map((key) => {
const { color } = config[key];
const strokeColor = theme.palette[color].main;
const activeDotColor = theme.palette[color].bg;
const bgColor = theme.palette.background.main;
return (
<Area
connectNulls
key={key}
dataKey={key}
stackId={1}
stroke={strokeColor}
strokeWidth={1.5}
fill={`url(#${config[key].id})`}
activeDot={{ stroke: activeDotColor, r: 5 }}
activeDot={{ stroke: bgColor, fill: strokeColor, r: 4.5 }}
/>
);
})}

View File

@@ -265,8 +265,6 @@ const PageSpeedDetails = () => {
let loading = Object.keys(monitor).length === 0;
const data = monitor?.checks ? [...monitor.checks].reverse() : [];
console.log(data);
const splitDuration = (duration) => {
const { time, format } = formatDurationSplit(duration);
return (
@@ -415,7 +413,10 @@ const PageSpeedDetails = () => {
</IconBox>
<Typography component="h2">Score history</Typography>
</Stack>
<PagespeedDetailsAreaChart data={data} />
<PagespeedDetailsAreaChart
data={data}
interval={monitor?.interval}
/>
</ChartBox>
<ChartBox flex={1}>
<Stack direction="row" alignItems="center" gap={theme.spacing(6)}>