using System.Text.Json; using HotMap.Utils; namespace HotMap.Services; public record HeatMapItem(DateOnly Time, int Contributions); public record HeatMapGroupByWeek(DateOnly Monday, List Items); public class HeatMapService(ILogger logger) { private List? _cachedResult; public List GetItemsByWeek() { _cachedResult ??= CalculateByWeekItems(); return _cachedResult; } private record HeatMapItemInner(long Timestamp, int Contributions) { public DateTimeOffset Time => DateTimeOffset.FromUnixTimeSeconds(Timestamp); } private List CalculateByWeekItems() { List? items = JsonSerializer.Deserialize>(Data, s_jsonSerializerOptions); if (items is null or { Count: 0 }) { throw new InvalidOperationException("Failed to get heap map items."); } // The contribution is not grouped by day, so group them. IEnumerable groupedItems = items .Select(i => (DateOnly.FromDateTime(i.Time.DateTime), i.Contributions)) .GroupBy(pair => pair.Item1) .Select(group => new HeatMapItem(group.Key, group.Select(pair => pair.Contributions).Sum())); List result = new(52); // Consider the input data is in order. // Start should be one year ago. HeatMapGroupByWeek group = new(DateOnly.FromDateTime(DateTime.Now).AddDays(-365 - 7).GetMonday(), []); logger.LogInformation("Create new item group by week {}.", group.Monday); foreach ((DateOnly date, int contributions) in groupedItems) { DateOnly mondayOfItem = date.GetMonday(); logger.LogInformation("Current date of item: {}, monday is {}", date, mondayOfItem); // If current item is in the same week of last item. if (mondayOfItem == group.Monday) { // Fill the spacing of empty days with 0 contribution. FillSpacing(group, date); group.Items.Add(new HeatMapItem(date, contributions)); continue; } // Current time is in the next (or much more) week of last item. // Fill the spacing, including the last week inner spacing and outer spacing. while (group.Monday < mondayOfItem) { FillSpacing(group, date); result.Add(group); group = new HeatMapGroupByWeek(group.Monday.AddDays(7), []); logger.LogInformation("Create new item group by week {}.", group.Monday); } // Now, the inner spacing of one week. FillSpacing(group, date); group.Items.Add(new HeatMapItem(date, contributions)); } // Not fill the last item and add directly. result.Add(group); return result; } private static void FillSpacing(HeatMapGroupByWeek groupByWeek, in DateOnly date) { if (groupByWeek.Monday == date) { return; } if (groupByWeek.Items.Count == 0) { groupByWeek.Items.Add(new HeatMapItem(groupByWeek.Monday, 0)); } DateOnly lastDate = groupByWeek.Items.Last().Time; // The day in one week is 7, so th count of items of one week should not bigger than 7. while (groupByWeek.Items.Count < 7 && lastDate < date.AddDays(-1)) { lastDate = lastDate.AddDays(1); groupByWeek.Items.Add(new HeatMapItem(lastDate, 0)); } } private static readonly JsonSerializerOptions s_jsonSerializerOptions = new() { PropertyNameCaseInsensitive = true }; private const string Data = """ [ { "timestamp": 1735529400, "contributions": 1 }, { "timestamp": 1735623900, "contributions": 1 }, { "timestamp": 1735717500, "contributions": 1 }, { "timestamp": 1735803000, "contributions": 1 }, { "timestamp": 1735827300, "contributions": 1 }, { "timestamp": 1735889400, "contributions": 1 }, { "timestamp": 1735976700, "contributions": 1 }, { "timestamp": 1736063100, "contributions": 1 }, { "timestamp": 1736135100, "contributions": 1 }, { "timestamp": 1736222400, "contributions": 1 }, { "timestamp": 1736316000, "contributions": 1 }, { "timestamp": 1736402400, "contributions": 1 }, { "timestamp": 1736492400, "contributions": 1 }, { "timestamp": 1736572500, "contributions": 1 }, { "timestamp": 1736658900, "contributions": 1 }, { "timestamp": 1736775900, "contributions": 1 }, { "timestamp": 1736830800, "contributions": 1 }, { "timestamp": 1736918100, "contributions": 1 }, { "timestamp": 1737018900, "contributions": 1 }, { "timestamp": 1737019800, "contributions": 2 }, { "timestamp": 1737036900, "contributions": 1 }, { "timestamp": 1737081900, "contributions": 1 }, { "timestamp": 1737186300, "contributions": 1 }, { "timestamp": 1737261000, "contributions": 1 }, { "timestamp": 1737342900, "contributions": 1 }, { "timestamp": 1737430200, "contributions": 1 }, { "timestamp": 1737516600, "contributions": 1 }, { "timestamp": 1737602100, "contributions": 1 }, { "timestamp": 1737696600, "contributions": 1 }, { "timestamp": 1737707400, "contributions": 1 }, { "timestamp": 1737708300, "contributions": 7 }, { "timestamp": 1737783900, "contributions": 1 }, { "timestamp": 1737786600, "contributions": 1 }, { "timestamp": 1737861300, "contributions": 1 }, { "timestamp": 1737947700, "contributions": 1 }, { "timestamp": 1737948600, "contributions": 1 }, { "timestamp": 1738035900, "contributions": 1 }, { "timestamp": 1738161900, "contributions": 2 }, { "timestamp": 1738219500, "contributions": 1 }, { "timestamp": 1738296000, "contributions": 1 }, { "timestamp": 1738380600, "contributions": 1 }, { "timestamp": 1738485000, "contributions": 1 }, { "timestamp": 1738552500, "contributions": 1 }, { "timestamp": 1738639800, "contributions": 1 }, { "timestamp": 1738725300, "contributions": 1 }, { "timestamp": 1738836900, "contributions": 1 }, { "timestamp": 1738899000, "contributions": 1 }, { "timestamp": 1738919700, "contributions": 1 }, { "timestamp": 1739160000, "contributions": 1 }, { "timestamp": 1739283300, "contributions": 1 }, { "timestamp": 1739333700, "contributions": 1 }, { "timestamp": 1739420100, "contributions": 1 }, { "timestamp": 1739523600, "contributions": 1 }, { "timestamp": 1739599200, "contributions": 1 }, { "timestamp": 1739678400, "contributions": 1 }, { "timestamp": 1739868300, "contributions": 1 }, { "timestamp": 1739943900, "contributions": 1 }, { "timestamp": 1739954700, "contributions": 1 }, { "timestamp": 1740021300, "contributions": 1 }, { "timestamp": 1740123000, "contributions": 1 }, { "timestamp": 1740195000, "contributions": 1 }, { "timestamp": 1740296700, "contributions": 1 }, { "timestamp": 1740367800, "contributions": 1 }, { "timestamp": 1740466800, "contributions": 1 }, { "timestamp": 1740540600, "contributions": 1 }, { "timestamp": 1740629700, "contributions": 1 }, { "timestamp": 1740636900, "contributions": 1 }, { "timestamp": 1740661200, "contributions": 1 }, { "timestamp": 1740662100, "contributions": 5 }, { "timestamp": 1740663900, "contributions": 1 }, { "timestamp": 1740714300, "contributions": 1 }, { "timestamp": 1740734100, "contributions": 1 }, { "timestamp": 1740735900, "contributions": 1 }, { "timestamp": 1740738600, "contributions": 1 }, { "timestamp": 1740741300, "contributions": 1 }, { "timestamp": 1740744000, "contributions": 2 }, { "timestamp": 1740799800, "contributions": 1 }, { "timestamp": 1740886200, "contributions": 1 }, { "timestamp": 1740981600, "contributions": 1 }, { "timestamp": 1741059900, "contributions": 1 }, { "timestamp": 1741077000, "contributions": 1 }, { "timestamp": 1741092300, "contributions": 1 }, { "timestamp": 1741093200, "contributions": 1 }, { "timestamp": 1741146300, "contributions": 1 }, { "timestamp": 1741155300, "contributions": 1 }, { "timestamp": 1741233600, "contributions": 1 }, { "timestamp": 1741320900, "contributions": 1 }, { "timestamp": 1741337100, "contributions": 1 }, { "timestamp": 1741349700, "contributions": 2 }, { "timestamp": 1741365000, "contributions": 1 }, { "timestamp": 1741413600, "contributions": 1 }, { "timestamp": 1741425300, "contributions": 2 }, { "timestamp": 1741442400, "contributions": 1 }, { "timestamp": 1741494600, "contributions": 1 }, { "timestamp": 1741580100, "contributions": 1 }, { "timestamp": 1741669200, "contributions": 1 }, { "timestamp": 1741758300, "contributions": 1 }, { "timestamp": 1741845600, "contributions": 1 }, { "timestamp": 1741881600, "contributions": 1 }, { "timestamp": 1741882500, "contributions": 3 }, { "timestamp": 1741883400, "contributions": 1 }, { "timestamp": 1741922100, "contributions": 1 }, { "timestamp": 1742013000, "contributions": 1 }, { "timestamp": 1742108400, "contributions": 1 }, { "timestamp": 1742184000, "contributions": 1 }, { "timestamp": 1742275800, "contributions": 1 }, { "timestamp": 1742358600, "contributions": 1 }, { "timestamp": 1742388300, "contributions": 1 }, { "timestamp": 1742392800, "contributions": 1 }, { "timestamp": 1742445000, "contributions": 1 }, { "timestamp": 1742457600, "contributions": 1 }, { "timestamp": 1742466600, "contributions": 1 }, { "timestamp": 1742469300, "contributions": 1 }, { "timestamp": 1742470200, "contributions": 1 }, { "timestamp": 1742474700, "contributions": 1 }, { "timestamp": 1742478300, "contributions": 1 }, { "timestamp": 1742481000, "contributions": 1 }, { "timestamp": 1742536800, "contributions": 1 }, { "timestamp": 1742544000, "contributions": 1 }, { "timestamp": 1742625000, "contributions": 1 }, { "timestamp": 1742635800, "contributions": 1 }, { "timestamp": 1742709600, "contributions": 1 }, { "timestamp": 1742792400, "contributions": 1 }, { "timestamp": 1742796000, "contributions": 1 }, { "timestamp": 1742826600, "contributions": 2 }, { "timestamp": 1742830200, "contributions": 1 }, { "timestamp": 1742832000, "contributions": 1 }, { "timestamp": 1742882400, "contributions": 1 }, { "timestamp": 1742885100, "contributions": 1 }, { "timestamp": 1742886000, "contributions": 3 }, { "timestamp": 1742886900, "contributions": 1 }, { "timestamp": 1742962500, "contributions": 1 }, { "timestamp": 1743056100, "contributions": 1 }, { "timestamp": 1743094800, "contributions": 1 }, { "timestamp": 1743135300, "contributions": 1 }, { "timestamp": 1743139800, "contributions": 1 }, { "timestamp": 1743227100, "contributions": 1 }, { "timestamp": 1743315300, "contributions": 1 }, { "timestamp": 1743390000, "contributions": 1 }, { "timestamp": 1743486300, "contributions": 1 }, { "timestamp": 1743581700, "contributions": 1 }, { "timestamp": 1743606900, "contributions": 1 }, { "timestamp": 1743660900, "contributions": 1 }, { "timestamp": 1743750000, "contributions": 1 }, { "timestamp": 1743836400, "contributions": 1 }, { "timestamp": 1743920100, "contributions": 1 }, { "timestamp": 1743997500, "contributions": 1 }, { "timestamp": 1744093800, "contributions": 1 }, { "timestamp": 1744268400, "contributions": 1 }, { "timestamp": 1744351200, "contributions": 1 }, { "timestamp": 1744443900, "contributions": 1 }, { "timestamp": 1744470000, "contributions": 1 }, { "timestamp": 1744524000, "contributions": 1 }, { "timestamp": 1744525800, "contributions": 1 }, { "timestamp": 1744601400, "contributions": 2 }, { "timestamp": 1744607700, "contributions": 1 }, { "timestamp": 1744638300, "contributions": 5 }, { "timestamp": 1744695000, "contributions": 1 }, { "timestamp": 1744773300, "contributions": 1 }, { "timestamp": 1744794000, "contributions": 1 }, { "timestamp": 1744872300, "contributions": 1 }, { "timestamp": 1744957800, "contributions": 1 }, { "timestamp": 1744959600, "contributions": 1 }, { "timestamp": 1745044200, "contributions": 1 }, { "timestamp": 1745046900, "contributions": 1 }, { "timestamp": 1745131500, "contributions": 1 }, { "timestamp": 1745214300, "contributions": 1 }, { "timestamp": 1745388000, "contributions": 1 }, { "timestamp": 1745474400, "contributions": 2 }, { "timestamp": 1745477100, "contributions": 1 }, { "timestamp": 1745487000, "contributions": 1 }, { "timestamp": 1745560800, "contributions": 2 }, { "timestamp": 1745584200, "contributions": 1 }, { "timestamp": 1745651700, "contributions": 1 }, { "timestamp": 1745724600, "contributions": 1 }, { "timestamp": 1745899200, "contributions": 1 }, { "timestamp": 1745903700, "contributions": 4 }, { "timestamp": 1745904600, "contributions": 2 }, { "timestamp": 1746083700, "contributions": 1 }, { "timestamp": 1746170100, "contributions": 1 }, { "timestamp": 1746252000, "contributions": 1 }, { "timestamp": 1746341100, "contributions": 1 }, { "timestamp": 1746446400, "contributions": 1 }, { "timestamp": 1746508500, "contributions": 1 }, { "timestamp": 1746590400, "contributions": 1 }, { "timestamp": 1746591300, "contributions": 1 }, { "timestamp": 1746675900, "contributions": 1 }, { "timestamp": 1746776700, "contributions": 1 }, { "timestamp": 1746810900, "contributions": 1 }, { "timestamp": 1746859500, "contributions": 1 }, { "timestamp": 1746949500, "contributions": 1 }, { "timestamp": 1747023300, "contributions": 1 }, { "timestamp": 1747123200, "contributions": 1 }, { "timestamp": 1747203300, "contributions": 1 }, { "timestamp": 1747290600, "contributions": 1 }, { "timestamp": 1747379700, "contributions": 1 }, { "timestamp": 1747461600, "contributions": 1 }, { "timestamp": 1747548000, "contributions": 1 }, { "timestamp": 1747620900, "contributions": 1 }, { "timestamp": 1747659600, "contributions": 3 }, { "timestamp": 1747660500, "contributions": 1 }, { "timestamp": 1747662300, "contributions": 2 }, { "timestamp": 1747663200, "contributions": 3 }, { "timestamp": 1747725300, "contributions": 1 }, { "timestamp": 1747796400, "contributions": 1 }, { "timestamp": 1747971900, "contributions": 1 }, { "timestamp": 1747973700, "contributions": 1 }, { "timestamp": 1748079000, "contributions": 1 }, { "timestamp": 1748163600, "contributions": 1 }, { "timestamp": 1748242800, "contributions": 1 }, { "timestamp": 1748323800, "contributions": 1 }, { "timestamp": 1748326500, "contributions": 2 }, { "timestamp": 1748412900, "contributions": 1 }, { "timestamp": 1748498400, "contributions": 1 }, { "timestamp": 1748504700, "contributions": 3 }, { "timestamp": 1748594700, "contributions": 1 }, { "timestamp": 1748762100, "contributions": 1 }, { "timestamp": 1748852100, "contributions": 1 }, { "timestamp": 1748855700, "contributions": 1 }, { "timestamp": 1748934900, "contributions": 1 }, { "timestamp": 1748937600, "contributions": 1 }, { "timestamp": 1749001500, "contributions": 1 }, { "timestamp": 1749114900, "contributions": 1 }, { "timestamp": 1749138300, "contributions": 1 }, { "timestamp": 1749142800, "contributions": 2 }, { "timestamp": 1749198600, "contributions": 1 }, { "timestamp": 1749279600, "contributions": 1 }, { "timestamp": 1749303900, "contributions": 1 }, { "timestamp": 1749367800, "contributions": 1 }, { "timestamp": 1749370500, "contributions": 1 }, { "timestamp": 1749443400, "contributions": 1 }, { "timestamp": 1749525300, "contributions": 1 }, { "timestamp": 1749737700, "contributions": 3 }, { "timestamp": 1749804300, "contributions": 1 }, { "timestamp": 1749901500, "contributions": 1 }, { "timestamp": 1749994200, "contributions": 1 }, { "timestamp": 1750003200, "contributions": 2 }, { "timestamp": 1750005900, "contributions": 2 }, { "timestamp": 1750055400, "contributions": 1 }, { "timestamp": 1750134600, "contributions": 1 }, { "timestamp": 1750226400, "contributions": 1 }, { "timestamp": 1750319100, "contributions": 1 }, { "timestamp": 1751040900, "contributions": 1 }, { "timestamp": 1751094900, "contributions": 2 }, { "timestamp": 1751103000, "contributions": 1 }, { "timestamp": 1751105700, "contributions": 7 }, { "timestamp": 1751462100, "contributions": 1 }, { "timestamp": 1753277400, "contributions": 1 }, { "timestamp": 1756614600, "contributions": 2 }, { "timestamp": 1756619100, "contributions": 5 }, { "timestamp": 1756818000, "contributions": 1 }, { "timestamp": 1760679900, "contributions": 3 }, { "timestamp": 1760704200, "contributions": 1 }, { "timestamp": 1760706000, "contributions": 1 }, { "timestamp": 1760706900, "contributions": 1 }, { "timestamp": 1760708700, "contributions": 1 }, { "timestamp": 1760775300, "contributions": 1 }, { "timestamp": 1760776200, "contributions": 1 }, { "timestamp": 1760778000, "contributions": 1 }, { "timestamp": 1760779800, "contributions": 1 }, { "timestamp": 1760782500, "contributions": 1 }, { "timestamp": 1760784300, "contributions": 1 }, { "timestamp": 1760862600, "contributions": 1 }, { "timestamp": 1760886000, "contributions": 1 }, { "timestamp": 1761126300, "contributions": 3 }, { "timestamp": 1761134400, "contributions": 3 }, { "timestamp": 1761137100, "contributions": 1 }, { "timestamp": 1761139800, "contributions": 1 }, { "timestamp": 1761747300, "contributions": 1 }, { "timestamp": 1761813900, "contributions": 2 }, { "timestamp": 1762354800, "contributions": 1 }, { "timestamp": 1762401600, "contributions": 1 }, { "timestamp": 1762416900, "contributions": 1 }, { "timestamp": 1762439400, "contributions": 1 }, { "timestamp": 1762441200, "contributions": 5 }, { "timestamp": 1762488000, "contributions": 2 }, { "timestamp": 1762509600, "contributions": 3 }, { "timestamp": 1762674300, "contributions": 4 }, { "timestamp": 1762764300, "contributions": 2 }, { "timestamp": 1763200800, "contributions": 2 }, { "timestamp": 1763201700, "contributions": 4 }, { "timestamp": 1763447400, "contributions": 1 }, { "timestamp": 1763564400, "contributions": 2 }, { "timestamp": 1763565300, "contributions": 1 }, { "timestamp": 1763627400, "contributions": 2 }, { "timestamp": 1763817300, "contributions": 2 }, { "timestamp": 1763818200, "contributions": 4 }, { "timestamp": 1764169200, "contributions": 1 }, { "timestamp": 1764170100, "contributions": 4 }, { "timestamp": 1764231300, "contributions": 2 }, { "timestamp": 1764257400, "contributions": 1 }, { "timestamp": 1764303300, "contributions": 1 }, { "timestamp": 1764306900, "contributions": 1 }, { "timestamp": 1764661500, "contributions": 1 }, { "timestamp": 1764662400, "contributions": 5 }, { "timestamp": 1764831600, "contributions": 8 }, { "timestamp": 1764836100, "contributions": 1 }, { "timestamp": 1764863100, "contributions": 1 }, { "timestamp": 1764908100, "contributions": 1 }, { "timestamp": 1764916200, "contributions": 1 }, { "timestamp": 1764938700, "contributions": 1 }, { "timestamp": 1765174500, "contributions": 1 }, { "timestamp": 1765184400, "contributions": 1 }, { "timestamp": 1765207800, "contributions": 3 }, { "timestamp": 1765208700, "contributions": 2 }, { "timestamp": 1765270800, "contributions": 4 }, { "timestamp": 1765271700, "contributions": 3 }, { "timestamp": 1765295100, "contributions": 1 }, { "timestamp": 1765370700, "contributions": 7 }, { "timestamp": 1765379700, "contributions": 8 }, { "timestamp": 1765426500, "contributions": 2 }, { "timestamp": 1765440900, "contributions": 1 }, { "timestamp": 1765444500, "contributions": 4 }, { "timestamp": 1765457100, "contributions": 8 }, { "timestamp": 1765640700, "contributions": 2 }, { "timestamp": 1765702800, "contributions": 1 }, { "timestamp": 1765703700, "contributions": 4 }, { "timestamp": 1765801800, "contributions": 6 }, { "timestamp": 1765877400, "contributions": 2 }, { "timestamp": 1765897200, "contributions": 2 }, { "timestamp": 1765898100, "contributions": 1 }, { "timestamp": 1765947600, "contributions": 3 }, { "timestamp": 1765983600, "contributions": 2 }, { "timestamp": 1765986300, "contributions": 3 }, { "timestamp": 1766031300, "contributions": 1 }, { "timestamp": 1766043000, "contributions": 4 }, { "timestamp": 1766043900, "contributions": 1 }, { "timestamp": 1766044800, "contributions": 1 }, { "timestamp": 1766045700, "contributions": 1 }, { "timestamp": 1766046600, "contributions": 5 }, { "timestamp": 1766241000, "contributions": 1 }, { "timestamp": 1766567700, "contributions": 1 }, { "timestamp": 1766652300, "contributions": 1 }, { "timestamp": 1767262500, "contributions": 3 }, { "timestamp": 1767359700, "contributions": 1 }, { "timestamp": 1767424500, "contributions": 5 }, { "timestamp": 1767426300, "contributions": 1 }, { "timestamp": 1767454200, "contributions": 3 }, { "timestamp": 1767456900, "contributions": 1 }, { "timestamp": 1767459600, "contributions": 3 }, { "timestamp": 1767518100, "contributions": 1 }, { "timestamp": 1767519900, "contributions": 1 }, { "timestamp": 1767627000, "contributions": 5 } ] """; }