FlutterでGitHubのContributionグラフを作ってみた

Contributionグラフとは?

エンジニアやプログラマーの方ならお馴染みGithubの自分のprofile画面に表示されている↓の様なグラフです。

このグラフを見ることで自分がどれくらいソースコードをコミットしているのかを把握することができます。

コミットした回数によって色付けされてる色が濃くなっていくので、このグラフを一目見ることで自分がいつ、どれくらいコミットをしたのかをすぐに把握する事ができてモチベーション向上に繋がるので個人的には凄くありがたいUIです。

そしてこのUIは何かの蓄積、積み上げを視覚化したい時に凄く使い勝手が良く便利です。

サンプルコード


動作確認したバージョンは以下のとおりです。

  • Flutter 3.0.1
  • Dart 2.13.3
main.dart
import 'package:flutter/material.dart';
import 'dart:math' as math;

class Commit {
  int count;

  Commit(this.count);
}

class Home extends StatefulWidget {
  @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
  // 日にちごとのコミット回数を格納する用
  List<Commit> commit = [];

  @override
  void initState() {
    // 現在の日付データを取得
    DateTime dt = DateTime.now();
    // dt.weekday : 曜日を数字で取得できる。(月:1, 火:2, 水:3, 木:4, 金:5, 土:6, 日:7)
    int weekDay = dt.weekday + 1;

    for (int i = 0; i < 7 * weekDay; i++) {
      commit.add(Commit(math.Random().nextInt(10)));
    }

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text(
          'GitHubのcontributionsグラフUI',
        ),
      ),
      body: Center(
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: SizedBox(
            height: 130,
            child: Row(
              children: [
                Expanded(
                  flex: 1,
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    // 曜日
                    children: [
                      Spacer(flex: 3),
                      Text('Mon'),
                      Spacer(flex: 2),
                      Text('Wed'),
                      Spacer(flex: 2),
                      Text('Fri'),
                      Spacer(flex: 3),
                    ],
                  ),
                ),
                Expanded(
                  flex: 11,
                  child: Center(
                    child: GridView.builder(
                      itemCount: commit.length,
                      shrinkWrap: true,
                      scrollDirection: Axis.horizontal,
                      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                        crossAxisCount: 7,
                        mainAxisSpacing: 4,
                        crossAxisSpacing: 4,
                      ),
                      padding: const EdgeInsets.all(8),
                      itemBuilder: (BuildContext context, int i) {
                        return Container(
                          decoration: BoxDecoration(
                            color: buildColor(commit[i].count),
                            borderRadius: BorderRadius.circular(2),
                          ),
                        );
                      },
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

  Color? buildColor(int count) {
    if (count == 0) {
      return Colors.grey[300];
    } else if (count <= 2) {
      return Colors.green[200];
    } else if (count <= 4) {
      return Colors.green[400];
    } else if (count <= 6) {
      return Colors.green[600];
    } else {
      return Colors.green[800];
    }
  }
}

ビルドしてみるとこんな感じです。

おわり

今回はネタでFlutterでGithubのContributionグラフを実装してみました。
このUI自体とても汎用性があって使いやすいと思うので是非自分のアプリで応用してみてください。
このブログでは他にもFlutter初心者向けの記事を多く上げていますのでそちらの方も良ければ参考にしてみてください。
ご質問やご指摘もお待ちしてます。