ガントチャートとはプロジェクトの進捗を管理するためのスケジュール表のことでであり、機械工学者で経営コンサルタントのヘンリー・ガントによって考案されました。縦軸に作業項目、横軸に時間軸を棒グラフで表すことにより、視覚的に全体像を掴めるようになります。

Excelなどの表計算ソフトやプロジェクト管理用のソフトも数多く存在するのですが、ここではあえてC#でつくることにします。このブログには「鳩でもわかるC#」という名前をつけてしまった以上、多少無理矢理感があってもやります。そうでなくてもNode.jsネタが増えてきてC#がおろそかになっているので・・・。

最初にデザイナで以下のようなものをつくります。フォームにPanelを貼り付けているだけです。最上部に日付を表示させたいのですが、チャートが縦に長くなってスクロールしなければならなくなったときに日付は見えるようにしておきたいからです。

TaskUserControlクラス

UserControlからTaskUserControlクラスをつくります。

上のTextBoxがタスク名、下が担当者の名前です。その横に開始日、終了日がグラフのように表示されます。開始日と終了日はタスクのそれとチャート全体のそれがあります。チャート全体の開始日、終了日はすべて同じになるので静的なフィールド変数にします。タスクの開始日、終了日はタスクによって違うので個別のフィールド変数をもちます。

それからタスクの開始日、終了日の表示色と日付の境界線を変更することができるようにします。今日がチャート全体のどの部分かも一目でわかるように別の色で表示します。

以下はチャート全体の開始日、終了日を変更するためのメソッドです。

描画処理

あとは各フィールド変数をセットして更新すればチャートが描画されます。

チャートを描画するにあたってチャートの開始位置、各日付間の幅、タスクの期間として塗りつぶす開始位置と終了位置を求めなければなりません。

チャートの開始位置はTextBoxの右端よりもちょっとだけ右側とします。

これがチャートを描画するためのメソッドです。

チャートの再描画をする処理を外部から実行できるように更新のためのメソッドを定義します。フォームのサイズが変更されたことにともなってチャートの幅が変更された場合はチャートの再描画が必要です。

チャート全体の開始日、終了日は今日の日付との相対位置で設定したいので、BandStartDayとBandEndDayと今日の日付との関係がわかるようなメソッドを準備しておきます。

Form1クラスにおける処理

作成したTaskUserControlをメインフォームに表示させます。

Form1クラス内にPanelMain(Panel)を貼り付け、フォームのサイズが変わると同じようにサイズ変更がおこなわれるようにします。また隅にチャート設定用のボタンも貼り付けておきます。

タスクを追加するための処理

PanelMainを右クリックすると「タスクを追加」というメニューが表示されるようにします。

「タスクを追加」が選択されるとTaskUserControlのインスタンスを生成してPanelMainに貼り付けます。

日付と境界線の描画処理

タスクが追加されたりフォームの大きさが変更された場合は一番上に日付の境界線を描画します。

日付の境界線を描画すべきX座標を取得する処理を示します。TaskUserControlが存在するなら取得し、そのDateBordersXを調べます。ここに格納されている値はTaskUserControl上のX座標なのでForm1上のX座標に変換します。

フォームの大きさが変更されたら日付の境界線の位置が変わるので再描画が必要です。このときTaskUserControlが再描画されてからでないと日付の境界線の位置を取得することができないので、0.1秒待機してからInvalidateメソッドを呼び出します。