NRIネットコム社員が様々な視点で、日々の気づきやナレッジを発信するメディアです

注目のタグ

    Angularで卓球分析アプリを作ろう その1

    本記事は  Webデザイン事業部ウィーク 2024  2日目の記事です。
    🌈  1日目  ▶▶ 本記事 ▶▶  3日目  💐

    はじめに

    こんにちは、フロントエンジニアの渡部です。
    今までの経験としてはAnguarを用いてWebアプリのフロント開発をしてることが多いです。

    今回は趣味で作ったWebアプリの紹介をAngular17に触れてみた感想とともにしていこうと思います。

    作った経緯

    趣味で卓球をしており、数値化した自身のデータを見られるツールあったらと常々思っていました。
    また、ここ数年最新のAngular事情を追えておらずキャッチアップしておきたいとも思っていました。

    なら折角だしこの2つを組み合わせて卓球分析Webアプリ作ってみることにしました。

    開発環境

    • Windows 11
    • Angular: v17.3.3
      今回の主役
      開発環境整えるタイミングでの最新版取得しています。
    • VS Code

    Angularの主なライブラリ

    • ngx-papaparse
      取り込んだcsvファイルを取り込むためのライブラリ
    • PrimeNG
      Angular向けUIコンポーネントを提供しているライブラリ
      無料かつ今まで使っていないUIコンポーネントということで選択しています。Angular Materialngx-bootstrpは使ったことがありました。

    アプリ開発

    1. csvファイルの準備
      下記添付ファイルのように1試合につき1ファイルのデータを準備 各項目の詳細は下記の通り

      • 試合日
        フォーマットはYYYYMMDD
      • 試合名
        フォーマットは自由、どの試合の何試合目かがわかるように
      • 相手用具情報
        ラケット(シェークorペンorハンドソウ)、ラバー(裏、表、粒、アンチ)
      • サービス・レシーブ情報
        ゲーム開始時、サービス開始ならS、レシーブ開始ならR
      • 点数取得タイミングと、ラリー数
        0-0の時に自分が点を取った得点は全体で1得点目なので自行の1番目に記載。1-0で相手が点を取った場合は全体で2得点目なので相手行の2番目に記載...のように取得した点数が全体で何番目のラリーかわかるように書いていく
        また、取った点数の場所にラリー数を記載する
      • ラリーの最後に自身が行ったプレーの略称
        フォアドライブならFtD、バックブロックならBtBのようにフォアorバック、回転方向、打法の順で記載
      • スコア
        5-3や12-10のようにハイフンでつなぎ、左が自身、右が相手の点数になるように記載
    2. webページ表示時に1で準備したcsvファイルを処理し、アプリにデータを持たせる
      各ページ表示用データはここで持たせたデータを使いまわす。 表示するデータは次の画面構成にて説明

    画面構成

    1. ダッシュボード画面

      • 取り込んだ試合全体概況
        • 総試合数とその勝敗
        • 勝率
        • 取得/喪失ゲーム数
        • 取得/喪失ゲーム数
      • ゲーム毎の勝敗比率
      • 勝ちゲーム、負けゲーム毎の点差
        2点差、3点差、4点差、5点差以上での分類
      • ラリー詳細
        • 試合毎のサービスエース数
        • レシーブエース数
        • 得点毎のラリー数
        • サービス開始
        • レシーブ開始毎の得点率
      • 取り込み済み試合リスト
    2. 個別結果画面

      • 表示ゲーム切り替えタブ
      • ゲーム毎の得失点
        • サービス時獲得/喪失ポイント
        • レシーブ時獲得/喪失ポイント
      • ポイント獲得推移グラフ
        • 自身のポイント獲得推移グラフ
        • 相手のポイント獲得推移グラフ
      • ダッシュボードへ戻るボタン

    作ってみた所感

    1. standAloneコンポーネントによって意識する場所減って楽になった
      開発始める際にmoduleファイルがなかったりComponentデコレータでimportsを設定する必要があるという違いがありました。
      開発中画面のimportsに必要なコンポーネントを書かないといけなく、いままではapp-routing.module.tsapp.module.tsの別ファイルに記述増やしてからまた開発中の画面に戻ってきて...のように別ファイルに移動して記述増やしてというくだりをやっていたのですが、開発中画面だけで完結するようになったので煩わしさが少し解消されました
      今回は個人での画面開発でしたが、複数人でそれぞれの画面を開発する際は共通ファイルを操作する機会が減るので開発しやすくなったのかなと思います。

    2. 組み込み制御フロー記述で表示制御が書きやすくなった
      Angular16まではAngularのテンプレートを使用したifforswitchといった制御は

        <div *ngFor="let item of itemList;">
            {{item}}
        </div>
      

        <div *ngIf="checkFlg;else falseBlock">
            {{trueValue}}
        </div>
        <ng-template #falseBlock>
            {{falseValue}}  
        </ng-template>
      

      のように記述する必要がありました。
      *ngForについてはletで呼び出した変数を使いまわすで理解しやすいところあったのですが、*ngIfについては、elseの向き先で<ng-template><ng-container>のどっち使うのか悩むこと多くよく調べ直していました。

      Angular17では

        @for (item of itemList; track item) {
            <div>{{item}}</div>
        }
      

        @if (checkFlg) {
            <div>{{trueValue}}</div>
        } @else {
            <div>{{falseValue}}</div>
        }
      

      のように記述することができるようになっています。
      @ifの場合でtypeScriptのif文と似たような記述ができるようになり、書きやすくなりました。
      @forでは@for (item of itemList) {のようにtrack itemの記述忘れによるエラーを開発中何度か発生させてしまいました。記述方法の違いについては、慣れの問題かと思いますが、気を付けるポイントかと思います。

    3. csvファイルへのデータを埋めることに時間がかかる
      試合動画をもとにデータ作成をしているのですが、1プレーごとにラリーの数を数え、自身の最後のプレーを確認するとなると1試合あたり1時間前後かかってしまいます。今後もデータ作成をしていきたいので、単純化する方法を検討する必要がありそうです。

    今後の展望

    今回卓球分析アプリを作ってみましたが、まだまだ改善する余地はあるので今気づいている改善点を記しておきます。
    改善でき次第、続編を書きたいと思いますし、アプリの公開が出来たらと考えています。

    • デザインの修正
      PrimeNGの初期設定を流用することとなってしまったので使用する色の統一感やレスポンシブ対応など手を加えていきたいです。

    • データベースとの連携
      現在の作りだと試合データを生成するたびにcsvファイルが増えること、機能追加等により既存データへの項目増減が発生する可能性があることが今後の懸念としてあるので、csvファイルでの開発を続けていくより、データベースを使っての開発に切り替えたいです。

    • 機能拡充
      個別試合の検索機能やラリー数やプレー種別ごとの得点失点の割合など細かなデータの表示ができるようにしたいです。

    用語説明

    記事中の用語(主に卓球用語)について補足説明

    • Angular
      Webアプリケーション向けフレームワークの一つ。Googleによって開発されている。
    • ゲーム
      11点先取(10-10となった場合は2点差着くまで)で獲得となる試合中の単位。おおよその試合は5ゲームマッチで行われるため先に3ゲーム獲得した選手の勝ちとなる。3ゲームマッチなら2ゲーム先取、7ゲームマッチなら4ゲーム先取。
    • ドライブ
      前進回転をボールに加える打法。
    • バック
      主に体の正面からラケットを持たない側(右持ちなら左側)での打法。基本的にはラケットの面はフォアとは反対側を使って打つ。
    • フォア
      主にラケットを持った側(右持ちなら右側)での打法。スイングしやすいので威力出しやすい。 *ブロック
      相手の強打を返球する打法。スイングは大きくとらずラケットの面を合わせることで返球する守備的技術。
    • ラケット
      手のひらで握る木の板のこと。握手するように握るシェークハンド、ペンのように握るペンホルダー、ピストルのように握るハンドソウなどがある。
    • ラバー
      木の板に貼るボールとの接地面を担うゴム製のシート。表面が平面となっいる裏ソフトラバー、表面が凸凹している表ソフトラバー・粒高ラバー、表面は平だが摩擦力を落としているアンチラバーに大別される。
    執筆者:渡部
    フロントエンドエンジニア
    持ってる資格:基本情報、webデザイン技能検定2級、Python3エンジニア認定基礎試験、運転免許(普通自動車第一種、小型限定普通二輪)、司書、学芸員