LoginSignup
7
8

More than 1 year has passed since last update.

Laravelにガントチャートを実装する方法

Last updated at Posted at 2021-08-12

Laravelでガントチャートを実装するにあたり丸1日かかったので、次回から困らないように備忘録として残します。

目次

環境
ライブラリ
手順
1.ガントチャートで使うコントローラーなどを作成
2.ガントチャートを表示するページのルーティング
3.ガントチャートを表示するためのコントローラー
4.ビューを作成
5.ガワが表示されるか確認
6.テーブルを作成
7.データベースにテストデータを追加
8.データベースから値を取得してJSONで返す処理
9.api.phpにもAPI用のルーティング
10.ガントチャートが表示されるか確認
11.ガントチャートの保存・変更・削除
12.保存・変更・削除ができるか確認
おまけ

環境

・iMac Big Sur
・Laravel8
・MAMP

ライブラリ

DHTMLX Ganttの無料版

手順

1.ガントチャートで使うコントローラーなどを作成

ターミナルに以下をそのまま打ち込んでください。

php artisan make:model Task -m -s
php artisan make:model Link -m
php artisan make:model Gantt -c

※末尾の-m-s-cmigrateseedercontrollerをそれぞれ一緒に作れという命令です。

2.ガントチャートを表示するページのルーティング

web.phpにルーティングを記述します。
今回は/sample/dhtmlx/gantにアクセスするとガントチャートが表示されるようにします。

web.php
use App\Http\Controllers\GanttController;
// (中略)
Route::get('/sample/dhtmlx/gantt', [GantController::class, 'view_gantt'])->name('sample.dhtmlx.gant')

3.ガントチャートを表示するためのコントローラー

GanttController.phpに以下を記述します。

GanttController.php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Gantt;

class GanttController extends Controller
{
  // ガントチャートのページを表示
  public function view_gantt()
  {
    return view('sample.dhtmlx.gantt');
  }
}

4.ビューを作成

/views内に/sample/dhtmlxとフォルダを作成し、その中にgantt.blade.phpを新規作成し、以下をそのまま記述します。

gantt.blade.php
<!DOCTYPE html>

<head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
    {{-- CDNから読み込み --}}
    <script src="https://cdn.dhtmlx.com/gantt/edge/dhtmlxgantt.js"></script>
    <link href="https://cdn.dhtmlx.com/gantt/edge/dhtmlxgantt.css" rel="stylesheet">
    <style>
        html,
        body {
            height: 100%;
            padding: 0px;
            margin: 0px;
            overflow: hidden;
        }

    </style>
</head>

<body>
    <div id="gantt_here" style='width: 100%; height: 100%;'>
        {{-- 描写エリア ここから --}}

        {{-- 描写エリア ここまで --}}
    </div>
    <script>
        gantt.config.date_format = "%Y-%m-%d %H:%i:%s"; // オプション:日付フォーマット設定
        gantt.i18n.setLocale("jp"); // オプション:言語設定
        gantt.init("gantt_here"); // 表示 ※最低限この行だけあれば表示は可能
    </script>
</body>

ちなみに、階層(URL含む)を変更する場合はGanttController.phpのreturn view(...)の中身と、web.phpのget()とname()の中身を書き換えてください。

5.ガワが表示されるか確認

/sample/dhtmlx/ganttにアクセスして、画像のように表示されれば、ここまでは成功です。
スクリーンショット 2021-08-12 10.23.12.png

6.テーブルを作成

create_tasks_table.phpに以下を記述します。

create_tasks_table.php
public function up()
  {
    Schema::create('tasks', function (Blueprint $table) {
      $table->id();
      $table->string('text');
      $table->integer('duration');
      $table->float('progress');
      $table->dateTime('start_date');
      $table->integer('parent');
      $table->timestamps();
    });
  }

create_links_table.phpに以下を記述します。

create_links_table.php
public function up()
  {
    Schema::create('links', function (Blueprint $table) {
      $table->id();
      $table->string('type');
      $table->integer('source');
      $table->integer('target');
      $table->timestamps();
    });
  }

ターミナルに以下を打ち込んでマイグレートと実行します。

$ php artisan migrate

7.データベースにテストデータを追加

TaskSeeder.phpに以下2つを記述します。

TaskSeeder.php
use App\Models\Task;
TaskSeeder.php
Task::insert([
  [
    'id' => 1, 'text' => 'テスト案件', 'start_date' => '2021-06-01 00:00:00',
    'duration' => 5, 'progress' => 0.8, 'parent' => 0
  ],
  [
    'id' => 2, 'text' => 'テスト作業1', 'start_date' => '2020-06-02 00:00:00',
    'duration' => 4, 'progress' => 0.5, 'parent' => 1
  ],
  [
    'id' => 3, 'text' => 'テスト作業2', 'start_date' => '2020-06-12 00:00:00',
    'duration' => 6, 'progress' => 0.7, 'parent' => 1
  ],
  [
    'id' => 4, 'text' => 'テスト作業3', 'start_date' => '2020-06-18 00:00:00',
    'duration' => 2, 'progress' => 0, 'parent' => 1
  ],
  [
    'id' => 5, 'text' => 'テスト作業1-1', 'start_date' => '2020-07-18 00:00:00',
    'duration' => 5, 'progress' => 0.34, 'parent' => 2
  ],
  [
    'id' => 6, 'text' => 'テスト作業1-2', 'start_date' => '2020-07-20 00:00:00',
    'duration' => 4, 'progress' => 0.5, 'parent' => 2
  ],
  [
    'id' => 7, 'text' => 'テスト作業2-1', 'start_date' => '2020-07-24 00:00:00',
    'duration' => 5, 'progress' => 0.2, 'parent' => 3
  ],
  [
    'id' => 8, 'text' => 'テスト作業2-2', 'start_date' => '2020-07-26 00:00:00',
    'duration' => 4, 'progress' => 0.9, 'parent' => 3
  ]
]);

DatabaseSeeder.phpに以下を記述します。

DatabaseSeeder.php
public function run()
{
  $this->call(TaskSeeder::class);
}

ターミナルで以下を打ち込んでseederを実行します。

$ php artisan db:seed

8.データベースから値を取得してJSONで返す処理

controller/GanttController.phpを開いて以下2つを追加してください。

GanttController.php
use App\Models\Task;
use App\Models\Link;
GanttController.php
public function get_json()
  {
    $tasks = new Task();
    $links = new Link();

    return response()->json([
      "data" => $tasks->all(),
      "links" => $links->all(),
    ]);
  }

9.api.phpにもAPI用のルーティング

web.phpではなくroutes/api.phpです。
api.phpに以下を追加します。

api.php
Route::get('/data', [GanttController::class, 'get_json']);

10.ガントチャートが表示されるか確認

画像のように表示されていれば、チャートの表示も成功しました。
スクリーンショット 2021-08-12 11.59.00.png

11.ガントチャートの保存・変更・削除

ガントチャートは基本的に保存・変更・削除ができないと役に立たないので、この3つの動作を実装します。

まずはTaskController.phpに以下を追加します。

TaskController.php

LinkControllerに以下を追加します。

LinkController.php

api.phpに以下を追加します。

api.php
Route::resources([
  'task' => TaskController::class,
  'link' => LinkController::class,
]);

// または

Route::resource('task', TaskController::class);
Route::resource('link', LinkController::class);

gantt.blade.phpのスクリプトに以下を追加します。

gantt.blade.php
<script>
  // (前略)

  // チャートの保存・変更・削除
  let dp = new gantt.dataProcessor("/api");
  dp.init(gantt);
  dp.setTransactionMode("REST");
</script>

12.保存・変更・削除ができるか確認

/sample/dhtmlx/ganttにアクセスし、保存・変更・削除ができるか確認して終了。
Chromeの翻訳機能もDeepL並の精度にならないかな(チラチラスクリーンショット 2021-08-12 11.59.00.png

通知表の英語、最高でも3だったけどDeepLのおかげで海外のサイトもどうにか読めた。

おまけ

上記スクリプトのgantt.i18n.setLocale("jp");の次くらいに以下を追加します。

タスク名をドラッグ&ドロップで並び替える

// 手動並び替え:有効
gantt.config.order_branch = true;
gantt.config.order_branch_free = true;

行の高さをドラッグで調整する

// 行の高さをドラッグで調整:有効
gantt.config.resize_rows = true;
// 行の最小の高さを指定
gantt.config.min_task_grid_row_height = 45;

ドラッグアンドドロップ中に利用可能なドロップ場所を強調表示する

gantt.config.order_branch = true;// order tasks only inside a branch
gantt.init("gantt_here");
gantt.parse(demo_tasks);

var drag_id = null;
gantt.attachEvent("onRowDragStart", function(id, target, e) {
    drag_id = id;
    return true;
});
gantt.attachEvent("onRowDragEnd", function(id, target) {
    drag_id = null;
    gantt.render();
});

gantt.templates.grid_row_class = function(start, end, task){
    if(drag_id && task.id != drag_id){
        if(task.$level != gantt.getTask(drag_id).$level)
            return "cant-drop";
        }
    return "";
};
7
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
8