Features

  • Vue.js Gantt Chart component created using DayPilot Vue.js Gantt Chart

  • You can connect the Gantt chart to any backend using REST API (this sample project uses static initialization)

  • The Vue.js project was generated using Gantt Chart UI Builder (online configurator)

  • Includes a trial version of DayPilot Pro for JavaScript (see also License below)

License

Licensed for testing and evaluation purposes. Please see the license agreement included in the sample project. You can use the source code of the tutorial if you are a licensed user of DayPilot Pro for JavaScript. Buy a license.

JavaScript Dependencies

First, install daypilot-pro-vue package from npm.daypilot.org:

yarn add https://npm.daypilot.org/daypilot-pro-vue/trial/2020.4.4807.tar.gz

Vue.js Gantt Chart Component

Our Vue.js Gantt chart component is created using Vue.js Gantt Chart from DayPilot Pro for JavaScript.

We will create a simple wrapper component that instantiates the <DayPilotGantt> Vue component and customizes the Gantt chart appearance and behavior.

We need to register the DayPilotGantt component in the components section:

<script>
import {DayPilot, DayPilotGantt} from 'daypilot-pro-vue'

export default {
  name: 'Gantt',
  components: {
    DayPilotGantt
  },
}
</script>

Now we can add it to the component <template>:

<template>
  <DayPilotGantt id="dp"/>
</template>

<script>
import {DayPilot, DayPilotGantt} from 'daypilot-pro-vue'

export default {
  name: 'Gantt',
  components: {
    DayPilotGantt
  },
}
</script>

The Gantt chart can be configured using an object specified by the :config attribute - we will use a new config object.

<template>
  <DayPilotGantt id="dp" :config="config" ref="gantt" />
</template>

<script>
import {DayPilot, DayPilotGantt} from 'daypilot-pro-vue'

export default {
  name: 'Gantt',
  data: function() {
    return {
      config: {
        timeHeaders: [{"groupBy":"Month"},{"groupBy":"Day","format":"d"}],
        scale: "Day",
        days: DayPilot.Date.today().daysInMonth(),
        startDate: DayPilot.Date.today().firstDayOfMonth(),      
        // ...
      },
    }
  },
  components: {
    DayPilotGantt
  },
}
</script>

After initialization, the DayPilot.Gantt instance is available as control property of the Vue Gantt chart component object. We will make it available as a computed gantt property:

<template>
  <DayPilotGantt id="dp" :config="config" ref="gantt" />
</template>

<script>
import {DayPilot, DayPilotGantt} from 'daypilot-pro-vue'

export default {
  name: 'Gantt',
  data: function() {
    return {
      config: {
        timeHeaders: [{"groupBy":"Month"},{"groupBy":"Day","format":"d"}],
        scale: "Day",
        days: DayPilot.Date.today().daysInMonth(),
        startDate: DayPilot.Date.today().firstDayOfMonth(),      
        // ...
      },
    }
  },
  components: {
    DayPilotGantt
  },
  computed: {
    // DayPilot.Gantt object - https://api.daypilot.org/daypilot-gantt-class/
    gantt: function () {
      return this.$refs.gantt.control;
    }
  },
}
</script>

Gantt Chart Configurator

vue-js-gantt-chart-configurator.png

There is also an easier way to start using the Vue.js Gantt chart component in your application - an online configurator tool that generates a project template:

This app lets you customize the Gantt chart appearance and behavior and preview the changes immediately. The preview Gantt chart object is live and fully functional (you can add/remove/update tasks and milestones, add links, change the hierarchy and order of tasks).

The UI Builder generates a configuration object which you can use in your application. You can also download a complete Vue.js project with all dependencies

Loading Gantt Chart Data

You can load the Gantt chart data using DayPilot.Gantt.update() method. This method will load the supplied data and redraws the Gantt chart.

In our Vue.js application, we have two methods that use the update() method to load tasks and links:

  • loadTasks()

  • loadLinks()

Loading Tasks

The loadTasks() method load the Gantt chart tasks:

methods: {
  loadTasks: function() {
    // placeholder for an AJAX call
    var data = [
      {
        id: 1,
        start: DayPilot.Date.today().firstDayOfMonth().addDays(3),
        end: DayPilot.Date.today().firstDayOfMonth().addDays(10),
        text: "Task 1",
        complete: 60
      },
      // ...
    ];
    this.gantt.update({tasks: data});
  },
  // ...
},

In a real application, you'll want to load the tasks from the server using a REST API. In this example, we use a static array to show the expected data structure. It's an array of task objects with the structure described in DayPilot.Task.data property documentation.

Loading Links

The loadLinks() method loads the task link data:

methods: {

  loadLinks: function() {
    var data = [
      { from: 1, to: 2, type: "FinishToStart"}
    ];
    this.gantt.update({links: data});
  },

  // ...
},

Accessing the DayPilot.Gantt Object

Both updateTasks() and updateLinks() methods use update() method of DayPilot.Gantt class. To call the Gantt object methods we need access to the component instance.

When adding the <DayPilotGantt> tag we have made the component instance accessible using a ref attribute.

<DayPilotGantt id="dp" :config="config" ref="gantt"></gantt>

This will allow us to access the component as this.$refs.gantt. We will create a shortcut property called gantt (as a computed Vue.js property) to access the underlying DayPilot.Gantt object:

new Vue({
  computed: {
    // DayPilot.Gantt object
    // https://api.daypilot.org/daypilot-gantt-class/
    gantt: function() { return this.$refs.gantt.control; }
  },

  // ..

});

Now you can access the API directly using this.gantt anywhere in the Vue.js application:

vue-js-gantt-chart-component-hello-world.png

methods: {
  helloWorld: function() {
    this.gantt.message("Hello, World!");
  }
},

Full Source Code

Here is the full source code of our Gantt.vue component:

<template>
  <DayPilotGantt id="dp" :config="config" ref="gantt" />
</template>

<script>
import {DayPilot, DayPilotGantt} from 'daypilot-pro-vue'

export default {
  name: 'Gantt',
  data: function() {
    return {
      config: {
        cellWidthSpec: "Fixed",
        cellWidth: 40,
        timeHeaders: [{"groupBy":"Month"},{"groupBy":"Day","format":"d"}],
        scale: "Day",
        days: DayPilot.Date.today().daysInMonth(),
        startDate: DayPilot.Date.today().firstDayOfMonth(),
        rowHeaderHideIconEnabled: false,
        rowMoveHandling: "Update",
        onRowMoved: args => {
          this.gantt.message("Row moved: " + args.source.text());
        },
        taskMoveHandling: "Update",
        onTaskMoved: args => {
          this.gantt.message("Task moved: " + args.task.text());
        },
        linkCreateHandling: "Update",
        onLinkCreated: args => {
          this.gantt.message("Link created: " + args.type);
        },
        rowCreateHandling: "Enabled",
        onRowCreate: args => {
          this.gantt.tasks.add({
            id: DayPilot.guid(),
            text: args.text,
            start: new DayPilot.Date().getDatePart(),
            end: new DayPilot.Date().getDatePart().addDays(1)
          });
        },
      },
    }
  },
  props: {
  },
  components: {
    DayPilotGantt
  },
  computed: {
    // DayPilot.Gantt object - https://api.daypilot.org/daypilot-gantt-class/
    gantt: function () {
      return this.$refs.gantt.control;
    }
  },
  methods: {
    loadTasks: function() {
      // placeholder for an AJAX call
      var data = [
        {
          id: 1,
          start: DayPilot.Date.today().firstDayOfMonth().addDays(3),
          end: DayPilot.Date.today().firstDayOfMonth().addDays(10),
          text: "Task 1",
          complete: 60
        },
        {
          id: 2,
          start: DayPilot.Date.today().firstDayOfMonth().addDays(10),
          end: DayPilot.Date.today().firstDayOfMonth().addDays(15),
          text: "Task 2",
          complete: 0
        },
        {
          id: 3,
          start: DayPilot.Date.today().firstDayOfMonth().addDays(15),
          type: "Milestone",
          text: "Milestone 1"
        }
      ];
      this.gantt.update({tasks: data});
    },
    loadLinks: function() {
      var data = [
        { from: 1, to: 2, type: "FinishToStart"}
      ];
      this.gantt.update({links: data});
    }
  },
  mounted: function() {
    this.loadTasks();
    this.loadLinks();

    this.gantt.message("Welcome!");
  }
}
</script>

See Also

History

  • December 21, 2020: Upgraded to package-based project, Vue 2, DayPilot Pro 2020.4.4807

  • April 27, 2018: Initial release