studiocms
Version:
Astro Native CMS for AstroDB. Built from the ground up by the Astro community.
50 lines (49 loc) • 1.74 kB
JavaScript
function processWebVitalsSummary(data) {
const grouped = data.reduce(
(acc, item) => {
if (!acc[item.name]) acc[item.name] = [];
acc[item.name].push(item);
return acc;
},
{}
);
const summary = {};
for (const [metricName, metrics] of Object.entries(grouped)) {
if (metrics.length < 4) continue;
metrics.sort((a, b) => a.rating.localeCompare(b.rating) || a.value - b.value);
const quartileSize = Math.ceil(metrics.length / 4);
for (let i = 0; i < metrics.length; i++) {
metrics[i].quartile = Math.floor(i / quartileSize) + 1;
}
for (let i = 0; i < metrics.length; i++) {
const nextItem = metrics[i + 1];
metrics[i].rating_end = !nextItem || nextItem.rating !== metrics[i].rating;
}
const sampleSize = metrics.length;
const histogram = {
good: 0,
"needs-improvement": 0,
poor: 0
};
for (let i = 0; i < metrics.length; i++) {
if (metrics[i].rating_end) {
const ratingCount = metrics.filter((m) => m.rating === metrics[i].rating).length;
histogram[metrics[i].rating] = ratingCount / sampleSize;
}
}
const p75Index = Math.floor(metrics.length * 0.75);
const p75Metric = metrics[p75Index] || null;
const percentiles = p75Metric ? { p75: { value: p75Metric.value, rating: p75Metric.rating } } : {};
const finalMetrics = metrics.filter(
// biome-ignore lint/style/noNonNullAssertion: This is a valid use case for non-null assertion
(metric) => metric.rating_end || metric.quartile * 25 === 75
);
if (finalMetrics.length > 0) {
summary[metricName] = { histogram, percentiles, sampleSize };
}
}
return summary;
}
export {
processWebVitalsSummary
};