はじめに
よろしくお願いします!初投稿です!
みなさんは「PowerBI」をご存じでしょうか。
私は、IT系の仕事をしていますが、お客さんが「PowerBI」を導入するとのことで、
とはいえ、私自身あまり知らないなと思って、勉強してみました。
「PowerBI」は、簡単に言うと、データをきれいに見せるためのツールですが、
勉強している中で、サンプルのデータをいじっても楽しくないので、
私の趣味のDanceDanceRevolution(音ゲーです)のスコアを使って、遊んでみました!
簡単にはなりますが、こういう風にやってみたよということで記事にします。
実用化にはいろいろと課題はありますが、(そんな予定はないですw)
とりあえず出来たところまでで、書いてみました!
DanceDanceRevolution(DDR)とは
名前ぐらいは、ご存じの方もいるのではないでしょうか。
趣味はと聞かれたときに、DDRと言うと、「今でもあるんだ」と言われます…。
超簡単に言うと、足でやる音ゲーになります。
Power BIとは
こちらも簡単に言うと、データを加工して、おしゃれに見せるためのツールです。
Excelでグラフを作る経験をした人も多いと思いますが、それの超強化版みたいな感じです。
概要
課題と解決
DDR公式ページから、自身のスコアを参照することができるのですが、
各々の楽曲のスコアを見る分には問題ないのですが、それらを集計することはできません。
まとめてみたいというときには、DDR公式ページからスクレイピングして、それを加工する必要があります。
そのため「Ryo Watanabe」さん作成の「DDR Score Tracker」という非公式ツールを利用させていただき、DDR公式ページのスクレイピングをいたします。
このスクレイピング結果は、楽曲データはTSV、スコアデータはJSONデータになります。
TSVデータはこのままでよいのですが、
JSONデータは、不要なデータの削除と使いやすいように変換するために、
「./jq」を使って、CSVデータに加工します。
上記のTSVデータと、CSVデータを「Power BI」に読み込ませることで、
スコアデータをきれいに見せる!ことができるようになります。
データフロー図
データフロー図は以下になります。
①「DDR Score Tracker」で、「HTML」から「JSON」に
②「./jq」で、「JSON」から「CSV」に
③ Power BI Desktopで、「TSV」「CSV」よりグラフ作成
④ Power BI(クラウド)にアップロード
詳細は、この後で説明いたします。
DDRのスコアのデータ構造について
DDRのスコアのデータ構造をご存じない方も当然いるかと思いますので、ご説明します。
データ構造としてはシンプルになります。
LEVELは、1(易)~19(難)
難易度は、BEGGINER(易)、BASIC、DIFFICULT、EXPERT、CHALLENGE(難) ※一部例外あり
クリアランクは、NO_PLAY(未プレイ)~MARVELOUS_FULL_COMBO(理論値) 1
スコアは、0~1,000,000
スコアランクは、NO_PLAY(未プレイ)、E~AAA 2
フレアランクは、NONE(なし)、FLAREⅠ ~ FLAREⅨ、FLARE EX 3
(※左から右に行くほど、高評価)
準備
DDR Score Tracker
こちらのツールは、GoogleChromeの拡張機能になります。
GoogleChromeで、上記のサイトにアクセスし、右上の「Chromeに追加」を押すだけになります。
./jq
上記のサイトから、ダウンロードできます。
また、Web版もありますので、ダウンロードがめんどくさいという方は、上記からどうぞ。
Power BI Desktop
Microsoft Storeより、「Power BI」と検索し、
「Power BI Desktop」をインストールします。
※私はインストール済みのため、「開く」となっておりますが、
インストールしていない場合、「インストール」と表示されます。
Microsoft 365(クラウドにアップロードする場合)
単純にスコアを可視化するだけであれば不要です。
クラウドにアップロードしたい場合のみ、以下から登録ください。
登録の詳細については、スキップさせていただきます。
Power BI(クラウドにアップロードする場合)
こちらも単純にスコアを可視化するだけであれば不要です。
クラウドにアップロードしたい場合のみ、以下から登録ください。
登録の詳細については、スキップさせていただきます。
実装
①「DDR Score Tracker」で、「HTML」から「JSON」に
「DDR Score Tracker」を使って、DDR公式のスコアページより、スコアを取得します。
まず、DDR公式ページからデータが取れるように、DDR公式ページにログインして、スコアが取れるようにします。
次に、「DDR Score Tracker」から、「Menu」より「スコア情報を取得」ボタンを押します。
するとデータが自動的に取られていくので、全部取得できるのを待ちます。
全部取得出来たら、「Menu」>「デバックページ」より、「楽曲リストを出力」ボタンと、「スコアリストを出力」ボタンを押します。
それぞれ、「楽曲リスト」はTSV形式で、「スコアリスト」は、JSON形式で取得できます。
「楽曲リスト」(TSV形式)は、そのまま使いますが、
「スコアリスト」(JSON形式)は、使いやすいCSV形式に変換します。
②「./jq」で、「JSON」から「CSV」に
「スコアリスト」(JSON形式)を変換します。
今回は、Web版で実施します。
画面のイメージはこちら。
②-1. 上部の「QUERY」には、以下を入力してください
QUERY 全文
["musicId","musicType","difficultySpBeginnerScore","difficultySpBeginnerScoreRank","difficultySpBeginnerClearType","difficultySpBeginnerFlareRank","difficultySpBeginnerFlareSkill","difficultySpBasicScore","difficultySpBasicScoreRank","difficultySpBasicClearType","difficultySpBasicFlareRank","difficultySpBasicFlareSkill","difficultySpDifficultScore","difficultySpDifficultScoreRank","difficultySpDifficultClearType","difficultySpDifficultFlareRank","difficultySpDifficultFlareSkill","difficultySpExpertScore","difficultySpExpertScoreRank","difficultySpExpertClearType","difficultySpExpertFlareRank","difficultySpExpertFlareSkill","difficultySpChallengeScore","difficultySpChallengeScoreRank","difficultySpChallengeClearType","difficultySpChallengeFlareRank","difficultySpChallengeFlareSkill"],(.[]|
[
.musicId,
.musicType,
getpath(["difficulty", "0", "score"]) // 0,
getpath(["difficulty", "0", "scoreRank"]) // 0,
getpath(["difficulty", "0", "clearType"]) // 0,
getpath(["difficulty", "0", "flareRank"]) // 0,
getpath(["difficulty", "0", "flareSkill"]) // 0,
getpath(["difficulty", "1", "score"]) // 0,
getpath(["difficulty", "1", "scoreRank"]) // 0,
getpath(["difficulty", "1", "clearType"]) // 0,
getpath(["difficulty", "1", "flareRank"]) // 0,
getpath(["difficulty", "1", "flareSkill"]) // 0,
getpath(["difficulty", "2", "score"]) // 0,
getpath(["difficulty", "2", "scoreRank"]) // 0,
getpath(["difficulty", "2", "clearType"]) // 0,
getpath(["difficulty", "2", "flareRank"]) // 0,
getpath(["difficulty", "2", "flareSkill"]) // 0,
getpath(["difficulty", "3", "score"]) // 0,
getpath(["difficulty", "3", "scoreRank"]) // 0,
getpath(["difficulty", "3", "clearType"]) // 0,
getpath(["difficulty", "3", "flareRank"]) // 0,
getpath(["difficulty", "3", "flareSkill"]) // 0,
getpath(["difficulty", "4", "score"]) // 0,
getpath(["difficulty", "4", "scoreRank"]) // 0,
getpath(["difficulty", "4", "clearType"]) // 0,
getpath(["difficulty", "4", "flareRank"]) // 0,
getpath(["difficulty", "4", "flareSkill"]) // 0
])|
@csv
②-2 「QUERY」のOptionsは、「-r(Raw Output)」を選択します
②-3 左の「JSON」には、①で取得した「スコアリスト」(JSON形式)を貼り付けます
②-4 「OUTPUT」に、CSV形式に変換されたスコアが出てきますので、これをCSV形式で保存します。
「楽曲リスト」(TSV形式)は、以下のカラム構造になります。
「楽曲リスト」はヘッダがないので、以下のカラム名でヘッダを定義します。
「スコアリスト」(CSV形式)データサンプル
musicId,musicType,isDeleted,difficultySpBeginner,difficultySpBasic,difficultySpDifficult,difficultySpExpert,difficultySpChallenge,difficultyDpBasic,difficultyDpDifficult,difficultyDpExpert,difficultyDpChallenge,musicTitle
006ob1iI9b1I8dDl0dq1bqIOP8886li1,0,0,2,5,8,11,0,5,8,11,0,☆shining☆
0088dOQPiD0Qb0Dl8ol09D98IOllI1id,0,0,3,5,10,13,0,5,10,13,0,take me higher
00Qbd9qoI681Q0biQOIiI08bI91i080l,0,1,1,3,8,11,0,3,8,11,0,I Want You To Know
00ibl6biOOOdDd96OP0P0i8iObo8i09d,0,1,3,6,11,14,0,6,11,14,0,Realize
・・・
カラム名 | 説明 |
---|---|
musicId | ランダムな文字列(スコアリストと結合) |
musicType | 楽曲タイプ(今回は使用しません) |
isDeleted | 削除済みか(今回は使用しません) |
difficultySpBeginner | SP BEGINNERのLEVEL |
difficultySpBasic | SP BASICのLEVEL |
difficultySpDifficult | SP DIFFICULTのLEVEL |
difficultySpExpert | SP EXPERTのLEVEL |
difficultySpChallenge | SP CHALLENGEのLEVEL |
difficultyDpBasic | DP BASICのLEVEL |
difficultyDpDifficult | DP DIFFICULTのLEVEL |
difficultyDpExpert | DP EXPERTのLEVEL |
difficultyDpChallenge | DP CHALLENGEのLEVEL |
musicTitle | 楽曲名 |
「スコアリスト」(CSV形式)は、以下のカラム構造になります。
「楽曲リスト」(TSV形式)データサンプル
"musicId","musicType","playStyle","difficulty","Score","ScoreRank","ClearType","FlareRank","FlareSkill"
"00obPO6oPIPOoD9qb0dIl6q6D8P6o9bI",0,"SP","Beginner",0,0,0,0,0
"00obPO6oPIPOoD9qb0dIl6q6D8P6o9bI",0,"SP","Basic",950700,15,3,5,604
"00obPO6oPIPOoD9qb0dIl6q6D8P6o9bI",0,"SP","Difficult",823130,11,3,0,575
"00obPO6oPIPOoD9qb0dIl6q6D8P6o9bI",0,"SP","Expert",0,0,0,0,0
"00obPO6oPIPOoD9qb0dIl6q6D8P6o9bI",0,"SP","Challenge",0,0,0,0,0
・・・
カラム名 | 説明 |
---|---|
musicId | ランダムな文字列(スコアリストと結合) |
musicType | 楽曲タイプ(今回は使用しません) |
playStyle | SP(シングルプレイ)か、DP(ダブルプレイ)か |
difficulty | 難易度 |
Score | スコア |
ScoreRank | スコアランク |
ClearType | クリアタイプ |
FlareRank | フレアランク |
FlareSkill | フレアスキル(今回は使用しません) |
③ Power BI Desktopで、「TSV」「CSV」よりグラフ作成
③-1. 「楽曲リスト」(TSV形式)、「スコアリスト」(CSV形式)を読み込み
-
「Power BI Desktop」を起動します
-
「スコアリスト」(CSV形式)を選択します
-
同様に、「楽曲リスト」(TSV形式)についても、同様に2.~4.を実施します
③-2. 「スコアリスト」のデータに、付加情報を加える
データを便利に使うために、既存の列を加工し、新しい列を追加します。
③-2-1. ランクの表記を、数字から、テキストに
既存の列だとスコアが「0」「1」「2」…と、ただの数字になるため、
新しい列として、「0_NO_PLAY」「1_FAILED」「2_ASSISTED_CLEAR」…の列を追加します。
クリアタイプの文字列
clearTypeText =
SWITCH(
TRUE,
[ClearType] = 0, "0_NO_PLAY",
[ClearType] = 1, "1_FAILED",
[ClearType] = 2, "2_ASSIST_CLEAR",
[ClearType] = 3, "3_CLEAR",
[ClearType] = 4, "4_LIFE4",
[ClearType] = 5, "5_GOOD_FC",
[ClearType] = 6, "6_GREAT_FC",
[ClearType] = 7, "7_PERFECT_FC",
[ClearType] = 8, "8_MARVELOUS_FC"
)
スコアランクの文字列
scoreRankText =
SWITCH(
TRUE,
[ScoreRank] = 0, "00_NO_PLAY",
[ScoreRank] = 1, "01_E",
[ScoreRank] = 2, "02_D",
[ScoreRank] = 3, "03_D+",
[ScoreRank] = 4, "04_C-",
[ScoreRank] = 5, "05_C",
[ScoreRank] = 6, "06_C+",
[ScoreRank] = 7, "07_B-",
[ScoreRank] = 8, "08_B",
[ScoreRank] = 9, "09_B+",
[ScoreRank] = 10, "10_A-",
[ScoreRank] = 11, "11_A",
[ScoreRank] = 12, "12_A+",
[ScoreRank] = 13, "13_AA-",
[ScoreRank] = 14, "14_AA",
[ScoreRank] = 15, "15_AA+",
[ScoreRank] = 16, "16_AAA"
)
フレアランクの文字列
FlareRankText =
SWITCH(
TRUE,
[FlareRank] = 0, "00_NONE",
[FlareRank] = 1, "01_FLARE_1",
[FlareRank] = 2, "02_FLARE_2",
[FlareRank] = 3, "03_FLARE_3",
[FlareRank] = 4, "04_FLARE_4",
[FlareRank] = 5, "05_FLARE_5",
[FlareRank] = 6, "06_FLARE_6",
[FlareRank] = 7, "07_FLARE_7",
[FlareRank] = 8, "08_FLARE_8",
[FlareRank] = 9, "09_FLARE_9",
[FlareRank] = 10, "10_FLARE_EX"
)
③-2-2. LEVEL列を追加
「スコアデータ」(CSV形式)には、LEVELのデータがありません。
代わりに「曲ID」と、「難易度(BEGINNER、BASICなど)」があるので、
この情報から、「楽曲データ」(TSV形式)内を検索し、LEVELを取得します。
③-2-1. と同じようにLEVEL列を追加します
LEVELの数字
difficultyNumber =
SWITCH(
[difficulty],
"Beginner", LOOKUPVALUE(musicList[difficultySpBeginner], musicList[musicId], [musicId]),
"Basic", LOOKUPVALUE(musicList[difficultySpBasic], musicList[musicId], [musicId]),
"Difficult", LOOKUPVALUE(musicList[difficultySpDifficult], musicList[musicId], [musicId]),
"Expert", LOOKUPVALUE(musicList[difficultySpExpert], musicList[musicId], [musicId]),
"Challenge", LOOKUPVALUE(musicList[difficultySpChallenge], musicList[musicId], [musicId])
)
③-3. スライサーの追加
特定のLEVELだけのグラフを表示するために、スライサーを追加します。
これで選択したレベルのみのグラフが表示されるようになります。
- 「ビジュアルのビルド」より、「スライサー」のアイコンを押下します
- フィールドに「difficultyNumber」(③-2-2で追加)をセットします
- フィルターに、「difficultyNumber」が「1より大きい」をセットします
- 「ビジュアルの書式設定」のアイコンを選択します
- 「スライサーの設定」>「オプション」>「スタイル」を、「タイル」にします
- 「スライサーの設定」>「選択項目」>「[すべて選択]オプション」にチェックを入れます
- (オプション)「値」>「値」>「フォント」のサイズを32にします
③-4. グラフの追加
グラフを使って、「スコアデータ」を綺麗に表現していきます。
③-4-1. 円グラフを追加
お馴染みの円グラフを使って、対象楽曲(任意のLEVELなど)の中から、
各スコア(「NO_PLAY」「CLEAR」…)がどんな割合かを表現します。
このグラフから、LEVEL10の楽曲はまだまだ未プレイ(「NO_PLAY」)が多いなとかが分かるようになります。
- 「ビジュアルのビルド」より、「円グラフ」のアイコンを押下します
- 凡例に「clearTypeText」(③-2-2で追加)をセットします
- 値に「clearTypeText」(③-1-1で追加)をセットします(自動的に「clearTypeText」のカウントになります)
- 「ビジュアルの書式設定」のアイコンを選択します
- (オプション)「凡例」>「フォント」のサイズを24にします
- (オプション)「値」>「フォント」のサイズを24にします
- 「値」>「表示単位」を、「なし」にします
- グラフの右上の「…」>「軸の並べ替え」を、「clearTypeText」「昇順で並べ替え」にします
③-4-2. 積み上げグラフを追加
円グラフでは、対象楽曲の中から、各スコアがどんな割合かを表現しました。
積み上げグラフを使うことで、1次元増やすことが出来ます。
そうすることで、全てのLEVELに対して、各スコア(「NO_PLAY」「CLEAR」…)がどんな割合かを表現することが出来ます。
これにより、LEVELが上がるとスコアが下がっていくなというのが、分かるようになりました。
- 「ビジュアルのビルド」より、「100% 積み上げ面グラフ」のアイコンを押下
- X軸に「difficultyNumber」(③-2-2で追加)をセットします
- Y軸に「clearTypeText」(③-1-1で追加)をセットします(自動的に「clearTypeText」のカウントになります)
- 凡例に「clearTypeText」(③-1-1で追加)をセットします
- フィルターに、「difficultyNumber」が「1より大きい」をセットします
- 「ビジュアルの書式設定」のアイコンを選択します
- 「X軸」>「型」、「カテゴリ別」にします
- グラフの右上の「…」>「軸の並べ替え」を、「difficultyNumber」「昇順で並べ替え」にします
- グラフの右上の「…」>「凡例の並べ替え」を、「降順で並べ替え」にします
③-5. テーブルの追加
ここでは単純に、各スコアについての詳細情報を表現するテーブルを用意します。
- 「ビジュアルのビルド」より、「テーブル」のアイコンを押下します
- 列に「difficultyNumber」「difficulty」「musicTitle」「clearTypeText」「Score」「scoreRankText」「FlareRankText」をセットします
- フィルターに、「difficultyNumber」が「1より大きい」をセットします
- 「ビジュアルの書式設定」のアイコンを選択します
③-6. まとめ
ほかにもいろんな表現の仕方がありそうですが、思いついたところでになります。
④ Power BI(クラウド)にアップロード(おまけ)
需要はないような気もしますが、「Power BI Desktop」で表現したので、
クラウド上の「Power BI」にアップロードしたいと思います。
- もし、サインインしていなければ、右上のアイコンからサインインしてください。
- 「発行」ボタンを押します
- 任意のワークスペースを選択します。ここではデフォルトの「マイワークスペース」を選択します
- 成功したら、「Power BIで~」を押します
- これでWebからも見れるようになります
同じ所属(メールアドレスの@以降が同じ)の他の人に共有することもできますが、ここではスキップします。
課題
追加したい機能としては、以下になります。
・手動箇所が多いので、自動化したい(Power Appsでいい感じにできる?)
・日ごとのグラフを作りたい(「スコアリスト」をもとに、その日の各スコアを集計し、別のテーブルにする?)
まとめ
ということで、以上になります!ここまで読んでいただきありがとうございます!
今回Power BIを使ってみて、データさえしっかり用意できれば、簡単にいい感じのグラフができるし、いろんなグラフも試すことができて、面白かったです。
普段遊んでいるスコアをグラフできれいに表現できると、「おおっ」ってなったりして、興味のあるデータを使うのはよかったです。
LEVELが上がると、スコアが下がるのを見ると「ああ、やっぱりそうなるよね」ってなったり、まだまだプレイしていない曲も多いなっていうのがわかったり、可視化するっていうのは、有意義だなと思いました。
-
NO_PLAY(未プレイ)、FAILED(失敗)、ASSIST_CLEAR(補助ありクリア)、CLEAR(通常クリア)、LIFE4(MISS4回未満)、GOOD_FULL_COMBO(フルコンボ)、GREAT_FULL_COMBO(全てGREAT評価以上でフルコンボ)、PERFECT_FULL_COMBO(全てPERFECT評価以上でフルコンボ)、MARVELOUS_FULL_COMBO(全てMARVELOUS評価でフルコンボ=理論値) ↩
-
NO_PLAY、E、D、D+、C-、C、C+、B-、B、B+、A-、A、A+、AA-、AA、AA+、AAA ↩
-
NONE、FLAREⅠ、FLAREⅡ、FLAREⅢ、FLAREⅣ、FLAREⅤ、FLAREⅥ、FLAREⅦ、FLAREⅧ、FLAREⅨ、FLARE EX ↩