Tutorial: Angular 2 Gantt Chart with PHP/MySQL Backend

This tutorial shows how to use DayPilot Gantt Chart with Angular 2 and PHP/MySQL backend.
Dec 13, 2016
angular2 gantt chart component

Features

Frontend (Angular 2)

  • Angular 2 CLI
  • Written in TypeScript
  • Loads Gantt Chart tasks from the server-side backend
  • Drag and drop support: task moving, resizing, row moving
  • Task creating (new row)
  • Task deleting (hover icon)
  • Uses Angular 2 Gantt Chart Component from DayPilot Pro for JavaScript package (trial)

Backend (PHP/MySQL)

  • Uses simple REST JSON API
  • Stores Scheduler data in a local SQLite database (or MySQL database)

Source code of the tutorial is available for download.

Example: Gantt Component Class

gantt.component.ts

import {Component, ViewChild} from '@angular/core';
import {DataService, MoveTaskParams, MoveRowParams, CreateRowParams} from "../backend/data.service";
import {DayPilot} from "daypilot-pro-angular";

@Component({
  selector: 'gantt-component',
  template: `
  <daypilot-gantt #gantt1 [config]="config"></daypilot-gantt>
  `,
  styles: [``]
})
export class GanttComponent {

  @ViewChild('gantt1') gantt1: DayPilot.Angular.Gantt;

  config: any = {
    scale: "Day",
    startDate: "2017-01-01",
    days: new DayPilot.Date("2017-01-01").daysInMonth(),
    timeHeaders: [
      {groupBy: "Month"},
      {groupBy: "Day", format: "d"}
    ],
    cellWidthSpec: "Auto",
    tasks: [],
    rowCreateHandling: "Enabled",
    onTaskMoved: args => {
      let params : MoveTaskParams = {
        id: args.task.id(),
        start: args.newStart.toString(),
        end: args.newEnd.toString()
      };
      this.ds.moveTask(params).subscribe(result => this.gantt1.control.message("Moved."));
    },
    onTaskResized: args => {
      let params : MoveTaskParams = {
        id: args.task.id(),
        start: args.newStart.toString(),
        end: args.newEnd.toString()
      };
      this.ds.moveTask(params).subscribe(result => this.gantt1.control.message("Resized."));
    },
    onRowMoved: args => {
      let params: MoveRowParams = {
        source: args.source.id(),
        target: args.target.id(),
        position: args.position
      };
      this.ds.moveRow(params).subscribe(result => this.gantt1.control.message("Moved."));
    },
    onRowCreated: args => {
      let start = new DayPilot.Date(this.gantt1.control.startDate);
      let end = start.addDays(1);
      let params: CreateRowParams = {
        start: start.toString(),
        end: end.toString(),
        name: args.text
      };
      this.ds.createRow(params).subscribe(result => {
        this.config.tasks.push({
          start: params.start,
          end: params.end,
          id: result.id,
          text: params.name
        });
        this.gantt1.control.message("Created.");
      });
    },
    onBeforeRowHeaderRender: args => {
      args.row.areas = [
        {
          right: 0,
          top: 0,
          height: 20,
          width: 20,
          action: "JavaScript",
          js: row => {
            console.log(row);
            this.ds.deleteTask({id: row.id}).subscribe(result => {
              var task = this.gantt1.control.tasks.find(row.id);
              this.gantt1.control.tasks.remove(task);
              this.gantt1.control.message("Deleted.");
            })
          },
          v: "Hover",
          style: "opacity: 0.5; cursor: pointer; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAALCAYAAACprHcmAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjExR/NCNwAAAI5JREFUKFNtkLERgCAMRbmzdK8s4gAUlhYOYEHJEJYOYOEwDmGBPxC4kOPfvePy84MGR0RJ2N1A8H3N6DATwSQ57m2ql8NBG+AEM7D+UW+wjdfUPgerYNgB5gOLRHqhcasg84C2QxPMtrUhSqQIhg7ypy9VM2EUZPI/4rQ7rGxqo9sadTegw+UdjeDLAKUfhbaQUVPIfJYAAAAASUVORK5CYII=) center center no-repeat;"
        }
      ];
    }
  };

  constructor(private ds: DataService) {
    ds.getTasks().subscribe(result => this.config.tasks = result);
    ds.getLinks().subscribe(result => this.config.links = result);
  }
}