MCPcopy
hub / github.com/npmx-dev/npmx.dev / buildYearlyEvolution

Function buildYearlyEvolution

app/utils/chart-data-buckets.ts:106–140  ·  view source on GitHub ↗
(
  daily: DailyRawPoint[],
  rangeStartIso?: string,
  rangeEndIso?: string,
)

Source from the content-addressed store, hash-verified

104}
105
106export function buildYearlyEvolution(
107 daily: DailyRawPoint[],
108 rangeStartIso?: string,
109 rangeEndIso?: string,
110): YearlyDataPoint[] {
111 const sorted = sortedDaily(daily)
112 const byYear = new Map<string, number>()
113 for (const item of sorted) {
114 const y = item.day.slice(0, 4)
115 byYear.set(y, (byYear.get(y) ?? 0) + item.value)
116 }
117
118 const entries = Array.from(byYear.entries()).sort(([a], [b]) => a.localeCompare(b))
119
120 return entries.map(([year, value], i) => {
121 const total = daysInYear(Number(year))
122 const yearStart = parseIsoDate(`${year}-01-01`)
123 const isFirst = i === 0
124 const isLast = i === entries.length - 1
125
126 const startOffset =
127 isFirst && rangeStartIso
128 ? Math.floor((parseIsoDate(rangeStartIso).getTime() - yearStart.getTime()) / DAY_MS)
129 : 0
130 const endOffset =
131 isLast && rangeEndIso
132 ? Math.floor((parseIsoDate(rangeEndIso).getTime() - yearStart.getTime()) / DAY_MS) + 1
133 : total
134 const actualDays = endOffset - startOffset
135
136 if (actualDays < total) value = fillPartialBucket(value, actualDays, total)
137
138 return { year, value, timestamp: yearStart.getTime() }
139 })
140}

Calls 6

daysInYearFunction · 0.90
parseIsoDateFunction · 0.90
sortedDailyFunction · 0.85
fillPartialBucketFunction · 0.85
setMethod · 0.65
getMethod · 0.65

Tested by

no test coverage detected