Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .claude/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"version": "0.0.1",
"configurations": [
{
"name": "next-dev",
"runtimeExecutable": "npm",
"runtimeArgs": ["run", "dev"],
"port": 3000
}
]
}
24 changes: 24 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
version: 2
updates:
# ワークフローはコミットハッシュで固定しているため、更新は Dependabot に任せる
# (ハッシュと隣のバージョンコメントの両方が書き換えられる)。
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
commit-message:
prefix: ci

- package-ecosystem: npm
directory: /
schedule:
interval: weekly
open-pull-requests-limit: 5
# minor / patch はまとめて 1 つの PR にし、major だけ個別に上げる。
groups:
npm-minor-and-patch:
patterns:
- '*'
update-types:
- minor
- patch
62 changes: 62 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: Deploy to GitHub Pages

on:
push:
branches: [master]
pull_request:
branches: [master]
workflow_dispatch:

# GitHub Pages へのデプロイに必要な権限。
permissions:
contents: read
pages: write
id-token: write

# 進行中のデプロイはキャンセルせず、後続を 1 つだけ待たせる。
concurrency:
group: pages
cancel-in-progress: false

jobs:
build:
runs-on: ubuntu-latest
steps:
# サプライチェーン対策として、各アクションはタグではなくコミットハッシュで固定する
# (更新は Dependabot がコメントのバージョンごと書き換える)。
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 22
cache: npm

- run: npm ci

- run: npm run lint

- run: npm run typecheck

- name: Build static site
# プロジェクトページは https://<user>.github.io/<repo>/ に配信されるため basePath を渡す。
env:
NEXT_PUBLIC_BASE_PATH: /${{ github.event.repository.name }}
run: npm run build

- name: Upload artifact
if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request'
uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
with:
path: ./out

deploy:
needs: build
if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request'
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
node_modules/
.next/
out/
next-env.d.ts
*.tsbuildinfo

.DS_Store
.env*.local

.ipynb_checkpoints/
__pycache__/
67 changes: 43 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,41 +1,60 @@
I am considering implementing a web version.

# AtCoder Rating Graph
Compare AtCoder rating graph with others.

複数ユーザーの AtCoder レーティング推移を、AtCoder の色帯(灰・茶・緑…)を背景に重ねて比較できる Web アプリです。

**https://hiramekun.github.io/AtCoderRatingGraph/**

![image](https://user-images.githubusercontent.com/20180425/79305365-3d2ffe00-7f2e-11ea-8626-90e717293688.png)

## 機能

- AtCoder ID を複数入力して「比較する」を押すと、各ユーザーのレーティング推移を 1 つのグラフに重ねて表示
- 開始日・終了日、または「全期間 / 直近1年 / 直近3年 / 直近5年」で表示期間を絞り込み
- 存在しない ID など、取得に失敗したユーザーはエラーとして表示し、他のユーザーのグラフはそのまま描画

## Installation
If you want to execute this repository, I strongrly recommend you to fork this repository at first.
Python >= 3.6 is required.
## 技術構成

```
After you fork this repository.
$ git clone https://github.com/`your user name`/AtCoderRatingGraph.git
```
- TypeScript / React 19 / Next.js 16 (App Router, `output: 'export'` による静的書き出し)
- グラフ描画: [Recharts](https://recharts.org/)。レート帯の背景色・目盛り・罫線は AtCoder 公式のレーティンググラフに合わせ、
折れ線とマーカーだけをユーザーごとに色分けしています。
- データ取得: AtCoder の `/users/<user>/history/json`。atcoder.jp は CORS ヘッダを返さずブラウザから直接取得できないため、
[AtCoder Problems](https://kenkoooo.com/atcoder/) が公開しているプロキシ (`https://kenkoooo.com/atcoder/proxy/...`) を経由しています。
- サーバー処理は無く、すべてブラウザ上で完結する静的サイトです。

Or you can simply clone this repository, too.
## 開発

```
$ git clone https://github.com/hiramekun/AtCoderRatingGraph.git
Node.js 20 以上が必要です。

```bash
npm ci
npm run dev
```

Then install requirements.
http://localhost:3000 で確認できます。その他のコマンド:

```
$ cd AtCoderRatingGraph
$ pip install -r requirements.txt
```bash
npm run lint
npm run typecheck
npm run build
```

## Usage
`npm run build` は `out/` に静的ファイルを書き出します。GitHub Pages と同じパス構成で確認したい場合は
`NEXT_PUBLIC_BASE_PATH=/AtCoderRatingGraph npm run build` としてください。

```
$ jupyter notebook
or
$ jupyter lab
## デプロイ

`master` へ push されると [GitHub Actions](.github/workflows/deploy.yml) がビルドして GitHub Pages へ自動デプロイします。
Pull Request では lint / typecheck / build のみ実行し、デプロイは行いません。

初回のみ、リポジトリの **Settings → Pages → Build and deployment → Source** を **GitHub Actions** に設定する必要があります。

## Jupyter Notebook 版(旧実装)

移行前の実装として `compare_rating.ipynb` を残しています。Python 3.6 以上で以下を実行してください。

```bash
pip install -r requirements.txt
jupyter lab
```

Change each name in `users` as you want.
Then run all cells.
`users` のリストを書き換えて全セルを実行するとグラフが表示されます。
10 changes: 10 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import coreWebVitals from 'eslint-config-next/core-web-vitals';
import typescript from 'eslint-config-next/typescript';

const config = [
{ ignores: ['.next/**', 'out/**', 'node_modules/**', 'next-env.d.ts'] },
...coreWebVitals,
...typescript,
];

export default config;
14 changes: 14 additions & 0 deletions next.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type { NextConfig } from 'next';

// GitHub Pages (project pages) は https://<user>.github.io/<repo>/ に配信されるため、
// CI ではリポジトリ名を basePath として渡す。ローカル開発時は空文字。
const basePath = process.env.NEXT_PUBLIC_BASE_PATH ?? '';

const nextConfig: NextConfig = {
output: 'export',
basePath,
images: { unoptimized: true },
trailingSlash: true,
};

export default nextConfig;
Loading