Skip to content

Commit 5c99f31

Browse files
authored
Merge pull request #1369 from yotsutose/PieChart-Only-Rated
Pie Chartsの表示をRatedとAllで切り替え可能にする
2 parents dd95540 + b49bac1 commit 5c99f31

File tree

3 files changed

+87
-21
lines changed

3 files changed

+87
-21
lines changed

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

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import React from "react";
2-
import { Row, Col } from "reactstrap";
1+
import React, { useState } from "react";
2+
import { Row, Col, Button, ButtonGroup } from "reactstrap";
33
import {
44
useContestToProblems,
55
useUserSubmission,
@@ -15,6 +15,7 @@ import {
1515
} from "../../../utils";
1616
import { SmallPieChart } from "../PieChartBlock/SmallPieChart";
1717
import {
18+
isRatedContest,
1819
classifyContest,
1920
ContestCategories,
2021
ContestCategory,
@@ -72,7 +73,8 @@ export const makeCategoryCounts = (
7273
contestsData: Contest[],
7374
contestToProblemsData: Map<string, Problem[]>,
7475
userSubmissionsData: Submission[],
75-
userId: string
76+
userId: string,
77+
onlyRated: boolean
7678
) => {
7779
const contestMap = new Map<string, Contest>(
7880
contestsData.map((contest) => [contest.id, contest])
@@ -118,8 +120,12 @@ export const makeCategoryCounts = (
118120
const category = classifyContest(statusByContest.contest);
119121
statusByContest.problemStatuses.forEach((problemStatus) => {
120122
const formerCount = counts.get(category);
123+
const isRated = isRatedContest(
124+
statusByContest.contest,
125+
contestToProblemsData.get(statusByContest.contest.id)?.length ?? 0
126+
);
121127
if (formerCount === undefined) return;
122-
128+
if (!isRated && onlyRated) return;
123129
statusCounter(formerCount, problemStatus.status);
124130
});
125131
return counts;
@@ -132,16 +138,23 @@ export const CategoryPieChart: React.FC<Props> = (props) => {
132138
const contestToProblems =
133139
useContestToProblems() ?? new Map<ContestId, Problem[]>();
134140
const userSubmissions = useUserSubmission(props.userId) ?? [];
141+
const [onlyRated, setOnlyRated] = useState(true);
135142

136143
const categoryCounts = makeCategoryCounts(
137144
contests,
138145
contestToProblems,
139146
userSubmissions,
140-
props.userId
147+
props.userId,
148+
onlyRated
141149
);
142150

143151
return (
144152
<div>
153+
<ButtonGroup className="mb-2">
154+
<Button onClick={(): void => setOnlyRated(!onlyRated)}>
155+
{onlyRated ? "Only Rated Contests" : "All Contests"}
156+
</Button>
157+
</ButtonGroup>
145158
<Row className="my-3">
146159
{ContestCategories.map((category) => {
147160
const count = categoryCounts.get(category);

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

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
import React from "react";
2-
import { Row, Col } from "reactstrap";
3-
import { useProblemModelMap, useUserSubmission } from "../../../api/APIClient";
1+
import React, { useState } from "react";
2+
import { Row, Col, Button, ButtonGroup } from "reactstrap";
3+
import {
4+
useProblemModelMap,
5+
useUserSubmission,
6+
useContestMap,
7+
} from "../../../api/APIClient";
48
import {
59
getRatingColor,
610
getRatingColorCode,
@@ -12,6 +16,7 @@ import {
1216
rejectedProblemIdsFromArray,
1317
solvedProblemIdsFromArray,
1418
} from "../UserUtils";
19+
import { isRatedContest } from "../../../utils/ContestClassifier";
1520

1621
interface Props {
1722
userId: string;
@@ -29,9 +34,15 @@ const getPieChartTitle = (ratingColor: RatingColor): string => {
2934
};
3035

3136
export const DifficultyPieChart: React.FC<Props> = (props) => {
32-
const submissions = useUserSubmission(props.userId) ?? [];
37+
const [onlyRated, setOnlyRated] = useState(true);
38+
const contestMap = useContestMap();
3339
const problemModels = useProblemModelMap();
3440
const colorCount = new Map<RatingColor, number>();
41+
const allSubmissions = useUserSubmission(props.userId) ?? [];
42+
const submissions = allSubmissions.filter(
43+
(submission) =>
44+
isRatedContest(contestMap.get(submission.contest_id), 2) || !onlyRated
45+
);
3546
Array.from(problemModels?.values() ?? []).forEach((model) => {
3647
if (model.difficulty !== undefined) {
3748
const color = getRatingColor(model.difficulty);
@@ -78,6 +89,11 @@ export const DifficultyPieChart: React.FC<Props> = (props) => {
7889

7990
return (
8091
<div>
92+
<ButtonGroup className="mb-2">
93+
<Button onClick={(): void => setOnlyRated(!onlyRated)}>
94+
{onlyRated ? "Only Rated Contests" : "All Contests"}
95+
</Button>
96+
</ButtonGroup>
8197
<Row className="my-3">
8298
{data
8399
.filter((e) => e.totalCount > 0)

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

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import { Col, Row } from "reactstrap";
2-
import React from "react";
1+
import { Col, Row, Button, ButtonGroup } from "reactstrap";
2+
import React, { useState } from "react";
33
import {
44
useContestToProblems,
55
useUserSubmission,
6+
useContestMap,
67
} from "../../../api/APIClient";
78
import Problem from "../../../interfaces/Problem";
89
import Submission from "../../../interfaces/Submission";
@@ -12,6 +13,7 @@ import {
1213
isAccepted,
1314
isValidResult,
1415
} from "../../../utils";
16+
import { isRatedContest } from "../../../utils/ContestClassifier";
1517
import { SmallPieChart } from "./SmallPieChart";
1618

1719
enum SubmissionStatus {
@@ -143,18 +145,26 @@ export const PieChartBlock = (props: Props) => {
143145
);
144146
const contestToProblems =
145147
useContestToProblems() ?? new Map<ContestId, Problem[]>();
148+
const [onlyRated, setOnlyRated] = useState(true);
149+
const contestMap = useContestMap();
146150

147151
const abcSolved = solvedCountForPieChart(
148-
Array.from(contestToProblems).filter(([contestId]) =>
149-
contestId.startsWith("abc")
150-
),
152+
Array.from(contestToProblems)
153+
.filter(([contestId]) => contestId.startsWith("abc"))
154+
.filter(
155+
([contestId]) =>
156+
isRatedContest(contestMap.get(contestId), 2) || !onlyRated
157+
),
151158
submissionsMap,
152159
props.userId
153160
);
154161
const arcSolved = solvedCountForPieChart(
155-
Array.from(contestToProblems).filter(([contestId]) =>
156-
contestId.startsWith("arc")
157-
),
162+
Array.from(contestToProblems)
163+
.filter(([contestId]) => contestId.startsWith("arc"))
164+
.filter(
165+
([contestId]) =>
166+
isRatedContest(contestMap.get(contestId), 2) || !onlyRated
167+
),
158168
submissionsMap,
159169
props.userId
160170
);
@@ -167,23 +177,50 @@ export const PieChartBlock = (props: Props) => {
167177
);
168178
return (
169179
<>
170-
<PieCharts problems={abcSolved} title="AtCoder Beginner Contest" />
171-
<PieCharts problems={arcSolved} title="AtCoder Regular Contest" />
172-
<PieCharts problems={agcSolved} title="AtCoder Grand Contest" />
180+
<PieCharts
181+
problems={abcSolved}
182+
title="AtCoder Beginner Contest"
183+
setOnlyRated={setOnlyRated}
184+
onlyRated={onlyRated}
185+
/>
186+
<PieCharts
187+
problems={arcSolved}
188+
title="AtCoder Regular Contest"
189+
setOnlyRated={setOnlyRated}
190+
onlyRated={onlyRated}
191+
/>
192+
<PieCharts
193+
problems={agcSolved}
194+
title="AtCoder Grand Contest"
195+
setOnlyRated={setOnlyRated}
196+
onlyRated={onlyRated}
197+
/>
173198
</>
174199
);
175200
};
176201

177202
interface PieChartsProps {
178203
problems: { total: number; solved: number; rejected: number }[];
179204
title: string;
205+
setOnlyRated: (onlyRated: boolean) => void;
206+
onlyRated: boolean;
180207
}
181208

182-
const PieCharts: React.FC<PieChartsProps> = ({ problems, title }) => (
209+
const PieCharts: React.FC<PieChartsProps> = ({
210+
problems,
211+
title,
212+
setOnlyRated,
213+
onlyRated,
214+
}) => (
183215
<div>
184216
<Row className="my-2 border-bottom">
185217
<h1>{title}</h1>
186218
</Row>
219+
<ButtonGroup className="mb-2">
220+
<Button onClick={(): void => setOnlyRated(!onlyRated)}>
221+
{onlyRated ? "Only Rated Contests" : "All Contests"}
222+
</Button>
223+
</ButtonGroup>
187224
<Row className="my-3">
188225
{problems.map(({ solved, rejected, total }, i) => {
189226
const key = i <= 6 ? "ABCDEFG".charAt(i) : "H/Ex";

0 commit comments

Comments
 (0)