Skip to content

Commit 008364e

Browse files
authored
Merge pull request #1316 from harukaeru/tee_in_those_days_chart
add: Add TEE In Those Days Chart to UserPage.
2 parents 3789897 + d386937 commit 008364e

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

atcoder-problems-frontend/src/pages/UserPage/ProgressChartBlock/index.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import { useLocalStorage } from "../../../utils/LocalStorage";
2727
import {
2828
countUniqueAcByDate,
2929
countTeeByDate,
30+
countTeeMovingAverage,
3031
} from "../../../utils/StreakCounter";
3132
import Submission from "../../../interfaces/Submission";
3233
import { ProblemId } from "../../../interfaces/Status";
@@ -146,6 +147,8 @@ export const ProgressChartBlock: React.FC<Props> = (props) => {
146147
return list;
147148
}, [] as { dateSecond: number; count: number }[]);
148149

150+
const teeMovingAverage = countTeeMovingAverage(dailyTeeCount);
151+
149152
const dateColorCountMap = Array.from(submissionsByProblem.values())
150153
.map((submissionsOfProblem) => {
151154
const accepted = submissionsOfProblem
@@ -277,6 +280,11 @@ export const ProgressChartBlock: React.FC<Props> = (props) => {
277280
</Row>
278281
<TeeChart climbingData={teeClimbing} />
279282

283+
<Row className="my-2 border-bottom">
284+
<h1>TEE Moving Average (30 days)</h1>
285+
</Row>
286+
<TeeChart climbingData={teeMovingAverage} />
287+
280288
<Row className="my-2 border-bottom">
281289
<h1>Heatmap</h1>
282290
</Row>

atcoder-problems-frontend/src/utils/StreakCounter.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,49 @@ export const countTeeByDate = (
111111
.map(([dateLabel, count]) => ({ dateLabel, count }))
112112
.sort((a, b) => a.dateLabel.localeCompare(b.dateLabel));
113113
};
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

Comments
 (0)