dhtmlxGantt와 PHP: Laravel 연동
이 튜토리얼은 dhtmlxGantt를 Laravel 애플리케이션에 통합하는 방법을 설명합니다.
서버 사이드 통합을 위한 다른 플랫폼의 튜토리얼도 제공됩니다:
- dhtmlxGantt와 ASP.NET MVC
- dhtmlxGantt와 ASP.NET Core 사용하기
- dhtmlxGantt와 Python
- dhtmlxGantt와 Node.js 연동하기
- dhtmlxGantt와 PHP:Slim 연동하기
- dhtmlxGantt와 Salesforce LWC 연동하기
- dhtmlxGantt와 Ruby on Rails 연동하기
전체 소스 코드는 GitHub에서 확인할 수 있습니다.
또한, PHP Laravel로 Gantt 차트를 만드는 방법을 보여주는 동영상 가이드도 있습니다.
1단계. 프로젝트 초기화
프로젝트 생성
먼저, Composer를 사용하여 새로운 Laravel 애플리케이션을 생성합니다:
composer create-project laravel/laravel gantt-laravel-app
이 과정은 필요한 모든 파일을 다운로드하고 설정하는 데 잠시 시간이 걸릴 수 있습니다. 설정이 완료되면 다음 명령어를 통해 정상적으로 설치되었는지 확인할 수 있습니다:
cd gantt-laravel-app
php artisan serve
이제 기본 Laravel 환영 페이지가 표시됩니다:

2단계. 페이지에 Gantt 추가
뷰(View) 추가
다음으로, dhtmlxGantt가 포함된 새로운 페이지를 앱에 추가합니다. resources/views 디렉토리로 이동하여 gantt.blade.php라는 새 뷰 파일을 생성합니다:
resources/views/gantt.blade.php
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charSet="utf-8"">
<script src="https://cdn.dhtmlx.com/gantt/edge/dhtmlxgantt.js"></script>
<link href="https://cdn.dhtmlx.com/gantt/edge/dhtmlxgantt.css" rel="stylesheet">
<style type="text/css">
html, body{
height:100%;
padding:0px;
margin:0px;
overflow: hidden;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script type="text/javascript">
gantt.init("gantt_here");
</script>
</body>
이 코드는 기본 HTML 레이아웃을 구성하고, CDN에서 dhtmlxGantt 리소스를 불러오며, init 메서드를 사용해 gantt 차트를 초기화합니다.
문서의 body와 gantt 컨테이너 모두 100% 높이로 설정되어 있습니다. gantt는 컨테이너 크기에 맞춰 동적으로 조정되기 때문에 이러한 크기 지정이 중요합니다.
기본 라우트 변경
새 페이지를 추가한 후, 브라우저에서 접근할 수 있도록 해야 합니다. 이 예제에서는 gantt 페이지를 앱의 기본 페이지로 설정합니다.
routes/web.php 파일을 열고 기본 라우트를 다음과 같이 수정합니다:
routes/web.php
<?php
Route::get('/', function () {
return view('gantt');
});
앱을 재시작한 후 gantt 페이지가 나타나는지 확인합니다:

3단계. 모델 및 마이그레이션 생성
gantt 차트가 표시되면, 다음 단계는 데이터베이스와 연결하여 데이터를 불러오는 것입니다.
데이터베이스 생성
먼저 .env 파일에서 데이터베이스 설정을 업데이트하세요. 예시:
.env
DB_CONNECTION="mysql"
DB_HOST="127.0.0.1"
DB_PORT="3306"
DB_DATABASE="gantt-test"
DB_USERNAME="root"
DB_PASSWORD=
그 다음, Artisan 명령어를 사용하여 모델 클래스와 마이그레이션을 생성합니다:
php artisan make:model Task --migration
그리고
php artisan make:model Link --migration
이제 database/migrations 폴더에서 마이그레이션 파일을 찾아 데이터베이스 스키마를 정의합니다.
gantt에서 기대하는 데이터베이스 스키마는 여기에서 확인할 수 있습니다.
Tasks 테이블에 대한 마이그레이션 예시는 다음과 같습니다:
database/migrations/_create_tasks_table.php
<?php
use IlluminateSupportFacadesSchema;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateDatabaseMigrationsMigration;
class CreateTasksTable extends Migration
{
public function up()
{
Schema::create('tasks', function (Blueprint $table){
$table->increments('id');
$table->string('text');
$table->integer('duration');
$table->float('progress');
$table->dateTime('start_date');
$table->integer('parent');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('tasks');
}
}
Links 테이블에 대한 마이그레이션 예시는 아래와 같습니다:
database/migrations/_create_links_table.php
<?php
use IlluminateSupportFacadesSchema;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateDatabaseMigrationsMigration;
class CreateLinksTable extends Migration
{
public function up()
{
Schema::create('links', function (Blueprint $table) {
$table->increments('id');
$table->string('type');
$table->integer('source');
$table->integer('target');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('links');
}
}
마이그레이션을 실행합니다:
php artisan migrate
설정하는 동안 테스트를 위해 샘플 데이터를 생성하는 것이 유용합니다. 다음 Artisan 명령어로 Seeder 클래스를 생성할 수 있습니다:
php artisan make:seeder TasksTableSeeder
php artisan make:seeder LinksTableSeeder
database/seeds 폴더가 없다면 생성한 후, 해당 폴더에서 TasksTableSeeder에 샘플 데이터를 추가합니다:
database/seeds/TasksTableSeeder.php
<?php
use IlluminateDatabaseSeeder;
class TasksTableSeeder extends Seeder
{
public function run()
{
DB::table('tasks')->insert([
['id'=>1, 'text'=>'Project #1', 'start_date'=>'2017-04-01 00:00:00',
'duration'=>5, 'progress'=>0.8, 'parent'=>0],
['id'=>2, 'text'=>'Task #1', 'start_date'=>'2017-04-06 00:00:00',
'duration'=>4, 'progress'=>0.5, 'parent'=>1],
['id'=>3, 'text'=>'Task #2', 'start_date'=>'2017-04-05 00:00:00',
'duration'=>6, 'progress'=>0.7, 'parent'=>1],
['id'=>4, 'text'=>'Task #3', 'start_date'=>'2017-04-07 00:00:00',
'duration'=>2, 'progress'=>0, 'parent'=>1],
['id'=>5, 'text'=>'Task #1.1', 'start_date'=>'2017-04-05 00:00:00',
'duration'=>5, 'progress'=>0.34, 'parent'=>2],
['id'=>6, 'text'=>'Task #1.2', 'start_date'=>'2017-04-11 00:00:00',
'duration'=>4, 'progress'=>0.5, 'parent'=>2],
['id'=>7, 'text'=>'Task #2.1', 'start_date'=>'2017-04-07 00:00:00',
'duration'=>5, 'progress'=>0.2, 'parent'=>3],
['id'=>8, 'text'=>'Task #2.2', 'start_date'=>'2017-04-06 00:00:00',
'duration'=>4, 'progress'=>0.9, 'parent'=>3]
]);
}
}
DatabaseSeeder.php를 수정하여 이 seeder들을 호출하도록 합니다:
database/seeds/DatabaseSeeder.php
<?php
use IlluminateDatabaseSeeder;
class DatabaseSeeder extends Seeder
{
public function run()
{
$this->call(TasksTableSeeder::class);
$this->call(LinksTableSeeder::class);
}
}
마지막으로, 명령줄에서 데이터베이스에 시드 데이터를 추가합니다:
php artisan db:seed
모델 클래스 정의
데이터는 Eloquent 모델 클래스를 통해 처리됩니다. 앞서 생성한 task와 link 클래스는 별도의 수정 없이 gantt에서 바로 사용할 수 있습니다.
단, 클라이언트에서 작업을 불러올 때 프로젝트 트리가 기본적으로 확장되어 있도록 하려면, Task 클래스의 JSON 응답에 open 속성을 추가할 수 있습니다. 그렇지 않으면 모든 브랜치가 처음에는 접혀서 표시됩니다.
Task 모델 예시는 다음과 같습니다:
/app/Task.php
<?php
namespace App;
use IlluminateDatabaseEloquentModel;
class Task extends Model
{
protected $appends = ["open"];/*!*/
public function getOpenAttribute(){/*!*/
return true;/*!*/
}/*!*/
}
Link 모델은 별도의 수정이 필요하지 않습니다:
/app/Link.php
<?php
namespace App;
use IlluminateDatabaseEloquentModel;
class Link extends Model
{
}
4단계. 데이터 불러오기
데이터베이 스와 모델이 준비되었으니, 이제 gantt 차트에 데이터를 불러올 수 있습니다. 클라이언트는 특정 포맷의 날짜를 기대하므로, 이에 맞는 JSON을 반환하는 컨트롤러 액션을 생성합니다:
app/Http/Controllers/GanttController.php
<?php
namespace AppHttpControllers;
use AppTask;
use AppLink;
class GanttController extends Controller
{
public function get(){
$tasks = new Task();
$links = new Link();
return response()->json([
"data" => $tasks->all(),
"links" => $links->all()
]);
}
}
이 액션을 클라이언트에서 요청할 수 있도록 api.php 라우트 파일에 라우트를 추가합니다:
routes/api.php
<?php
use IlluminateHttpRequest;
use AppHttpControllersGanttController;
Route::get('/data', 'GanttController@get');/*!*/
마지막으로, 뷰를 수정하여 이 엔드포인트를 호출하도록 합니다:
resources/views/gantt.blade.php
gantt.config.date_format = "%Y-%m-%d %H:%i:%s";/*!*/
gantt.init("gantt_here");
gantt.load("/api/data");/*!*/
gantt.load 메서드는 지정된 URL로 AJAX 요청을 보내고, JSON 응답을 기대합니다.
또한, date_format을 지정하면 gantt가 데이터 소스의 날짜 형식을 인식하여 클라이언트에서 올바르게 파싱할 수 있습니다.
이제 앱을 확인하면 gantt 차트에 작업이 표시됩니다:

5단계. 변경사항 저장
현재 gantt 차트는 백엔드에서 데이터를 읽어옵니다. 다음 단계는 변경사항을 데이터베이스에 저장할 수 있도록 하는 것입니다.
클라이언트는 REST 모드로 동작하며, 작업 및 링크에 대한 POST/PUT/DELETE 요청을 보냅니다. gantt에서 사용하는 요청 포맷과 라우트는 여기에서 확인할 수 있습니다.
이를 지원하려면 두 모델 모두에 대해 CRUD 작업을 처리하는 컨트롤러를 생성하고, 라우트를 정의하며, 클라이언트에서 데이터 저장을 활성화해야 합니다.