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
、-c
はmigrate
、seeder
、controller
をそれぞれ一緒に作れという命令です。
###2.ガントチャートを表示するページのルーティング
web.php
にルーティングを記述します。
今回は/sample/dhtmlx/gant
にアクセスするとガントチャートが表示されるようにします。
use App\Http\Controllers\GanttController;
// (中略)
Route::get('/sample/dhtmlx/gantt', [GantController::class, 'view_gantt'])->name('sample.dhtmlx.gant')
###3.ガントチャートを表示するためのコントローラー
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
を新規作成し、以下をそのまま記述します。
<!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
にアクセスして、画像のように表示されれば、ここまでは成功です。
###6.テーブルを作成
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
に以下を記述します。
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つを記述します。
use App\Models\Task;
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
に以下を記述します。
public function run()
{
$this->call(TaskSeeder::class);
}
ターミナルで以下を打ち込んでseederを実行します。
$ php artisan db:seed
###8.データベースから値を取得してJSONで返す処理
controller/GanttController.php
を開いて以下2つを追加してください。
use App\Models\Task;
use App\Models\Link;
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
に以下を追加します。
Route::get('/data', [GanttController::class, 'get_json']);
###10.ガントチャートが表示されるか確認
画像のように表示されていれば、チャートの表示も成功しました。
###11.ガントチャートの保存・変更・削除
ガントチャートは基本的に保存・変更・削除ができないと役に立たないので、この3つの動作を実装します。
まずはTaskController.php
に以下を追加します。
LinkController
に以下を追加します。
api.php
に以下を追加します。
Route::resources([
'task' => TaskController::class,
'link' => LinkController::class,
]);
// または
Route::resource('task', TaskController::class);
Route::resource('link', LinkController::class);
gantt.blade.php
のスクリプトに以下を追加します。
<script>
// (前略)
// チャートの保存・変更・削除
let dp = new gantt.dataProcessor("/api");
dp.init(gantt);
dp.setTransactionMode("REST");
</script>
###12.保存・変更・削除ができるか確認
/sample/dhtmlx/gantt
にアクセスし、保存・変更・削除ができるか確認して終了。
Chromeの翻訳機能もDeepL並の精度にならないかな(チラチラ
通知表の英語、最高でも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 "";
};