@@ -111,3 +111,49 @@ export const countTeeByDate = (
111
111
. map ( ( [ dateLabel , count ] ) => ( { dateLabel, count } ) )
112
112
. sort ( ( a , b ) => a . dateLabel . localeCompare ( b . dateLabel ) ) ;
113
113
} ;
114
+
115
+ export const countTeeMovingAverage = (
116
+ dailyTeeCount : {
117
+ dateLabel : string ;
118
+ count : number ;
119
+ } [ ]
120
+ ) => {
121
+ const DURATION = 30 ;
122
+ if ( ! Array . isArray ( dailyTeeCount ) || dailyTeeCount . length === 0 ) {
123
+ return [ ] ;
124
+ }
125
+
126
+ const minDateLabel = dailyTeeCount [ 0 ] . dateLabel ;
127
+ const maxDateLabel = dailyTeeCount [ dailyTeeCount . length - 1 ] . dateLabel ;
128
+ const dateDelta =
129
+ 1 +
130
+ ( new Date ( maxDateLabel ) . getTime ( ) - new Date ( minDateLabel ) . getTime ( ) ) /
131
+ 1000 /
132
+ 86400 ;
133
+
134
+ const differentiatedTees = Array . from ( Array ( dateDelta ) ) . map ( ( __ , i ) => {
135
+ const nextDate = new Date ( minDateLabel ) ;
136
+ nextDate . setDate ( nextDate . getDate ( ) + i ) ;
137
+ const nextDateLabel = nextDate . toISOString ( ) . substring ( 0 , 10 ) ;
138
+ const found = dailyTeeCount . find ( ( tee ) => tee . dateLabel === nextDateLabel ) ;
139
+ if ( found ) {
140
+ return found ;
141
+ } else {
142
+ return { dateLabel : nextDateLabel , count : 0 } ;
143
+ }
144
+ } ) ;
145
+
146
+ return differentiatedTees
147
+ . map ( ( { dateLabel } , i ) => {
148
+ const dateSecond = parseDateLabel ( dateLabel ) . unix ( ) ;
149
+ const begin = Math . max ( i - ( DURATION - 1 ) , 0 ) ;
150
+ const total = differentiatedTees
151
+ . slice ( begin , i + 1 )
152
+ . reduce ( ( tot , data ) => data . count + tot , 0 ) ;
153
+ if ( ! total ) {
154
+ return null ;
155
+ }
156
+ return { dateSecond, count : total / DURATION } ;
157
+ } )
158
+ . filter ( ( data ) : data is { dateSecond : number ; count : number } => ! ! data ) ;
159
+ } ;
0 commit comments