File size: 2,036 Bytes
22aa376 c798beb 22aa376 eda28cd 22aa376 eda28cd 22aa376 eda28cd 22aa376 eda28cd 22aa376 c798beb 22aa376 eda28cd c798beb 22aa376 eda28cd |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
import {
ModelData,
ProviderInfo,
CalendarData,
Activity,
} from "../types/heatmap";
export const generateCalendarData = (
modelData: ModelData[],
providers: ProviderInfo[]
): CalendarData => {
const data: Record<string, Activity[]> = Object.fromEntries(
providers.map((provider) => [provider.authors[0], []]),
);
const today = new Date();
const startDate = new Date(today);
startDate.setMonth(today.getMonth() - 11);
startDate.setDate(1);
// create a map to store counts for each provider and date
const countMap: Record<string, Record<string, number>> = {};
modelData.forEach((item) => {
const dateString = item.createdAt.split("T")[0];
providers.forEach(({ authors }) => {
if (authors.some((author) => item.id.startsWith(author))) {
countMap[authors[0]] = countMap[authors[0]] || {};
countMap[authors[0]][dateString] =
(countMap[authors[0]][dateString] || 0) + 1;
}
});
});
// fill in with 0s for days with no activity
for (let d = new Date(startDate); d <= today; d.setDate(d.getDate() + 1)) {
const dateString = d.toISOString().split("T")[0];
providers.forEach(({ authors }) => {
const count = countMap[authors[0]]?.[dateString] || 0;
data[authors[0]].push({ date: dateString, count, level: 0 });
});
}
// calculate average counts for each provider
const avgCounts = Object.fromEntries(
Object.entries(data).map(([provider, days]) => [
provider,
days.reduce((sum, day) => sum + day.count, 0) / days.length || 0,
]),
);
// assign levels based on count relative to average
Object.entries(data).forEach(([provider, days]) => {
const avgCount = avgCounts[provider];
days.forEach((day) => {
day.level =
day.count === 0
? 0
: day.count <= avgCount * 0.5
? 1
: day.count <= avgCount
? 2
: day.count <= avgCount * 1.5
? 3
: 4;
});
});
return data;
}; |