Features

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, include DayPilot and Vue.js libraries using <script> tags:

<!-- DayPilot library -->
<script src="js/daypilot/daypilot-all.min.js"></script>

<!-- Vue.js -->
<script src="https://unpkg.com/vue"></script>

Vue.js Gantt Chart Component

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

We will create a simple wrapper that registers the Gantt chart as a Vue.js component. During the component initialization (in "mounted" event handler), we create a DayPilot.Gantt instance linked to the <div> placeholder (see the HTML template). The Gantt chart is configured it using the values specified in the "config" property.

After initialization, the DayPilot.Gantt instance will be stored as "control" property of the Vue component object.

Vue.component('gantt', {
  props: ['id', 'config'],
  template: '<div :id="id"></div>',
  mounted: function() { this.control = new DayPilot.Gantt(this.id, this.config).init(); }
});

After the component registration, the Gantt chart will be available in the page HTML as <gantt> tag.

Gantt Chart Initialization

In order to insert the Vue.js Gantt chart component to your page simply add the <gantt> tag to the application HTML:

<div id="gantt-app">
  <gantt id="dp" :config="initConfig" ref="gantt"></gantt>
</div>

The id attribute specifies the id of the placeholder <div>.

The config attribute specifies the object that holds the initial configuration (properties and event handlers) of the Gantt chart.

We also store the component reference using ref attribute so we can access the component object later.

Here is an example initConfig object that configures the Gantt chart:

new Vue({
  el: '#gantt-app',
  data: {
    initConfig: {
      timeHeaders: [{"groupBy":"Month"},{"groupBy":"Day","format":"d"}],
      scale: "Day",
      days: DayPilot.Date.today().daysInMonth(),
      startDate: DayPilot.Date.today().firstDayOfMonth(),
      // ...
    }
  },
  // ...
});

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:

  • updateTasks()
  • updateLinks()

Loading Tasks

updateTasks()

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

updateLinks()

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 <gantt> tag we have made the component instance accessible using a ref attribute.

<gantt id="dp" :config="initConfig" 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

index.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Vue.js Chart Chart Tutorial</title>

        <style type="text/css">
            p, body, td { font-family: Tahoma, Arial, Helvetica, sans-serif; font-size: 10pt; }
            body { padding: 0px; margin: 0px; background-color: #ffffff; }
            a { color: #1155a3; }
            .space { margin: 10px 0px 10px 0px; }
            .header { background: #003267; background: linear-gradient(to right, #011329 0%,#00639e 44%,#011329 100%); padding:20px 10px; color: white; box-shadow: 0px 0px 10px 5px rgba(0,0,0,0.75); }
            .header a { color: white; }
            .header h1 a { text-decoration: none; }
            .header h1 { padding: 0px; margin: 0px; }
            .main { padding: 10px }
        </style>

        <!-- DayPilot library -->
        <script src="js/daypilot/daypilot-all.min.js"></script>
        
        <!-- Vue.js -->
        <script src="https://unpkg.com/vue"></script>

    </head>
    <body>
        <div class="header">
            <h1><a href='https://code.daypilot.org/80967/vue-js-chart-chart-tutorial'>Vue.js Chart Chart Tutorial</a></h1>
            <div><a href="https://javascript.daypilot.org/">DayPilot for JavaScript</a> - AJAX Calendar/Scheduling Widgets for JavaScript/HTML5/jQuery/AngularJS</div>
        </div>

        <div class="main">

            <div id="gantt-app">
                <gantt id="dp" :config="initConfig" ref="gantt"></gantt>
            </div>

        </div>

        <script>
          Vue.component('gantt', {
            props: ['id', 'config'],
            template: '<div :id="id"></div>',
            mounted: function() { this.control = new DayPilot.Gantt(this.id, this.config).init(); }
          });

          new Vue({
            el: '#gantt-app',
            data: {
              initConfig: {
                cellWidthSpec: "Fixed",
                cellWidth: 40,
                timeHeaders: [{"groupBy":"Month"},{"groupBy":"Day","format":"d"}],
                scale: "Day",
                days: DayPilot.Date.today().daysInMonth(),
                startDate: DayPilot.Date.today().firstDayOfMonth(),
                taskHeight: 30,
                rowHeaderHideIconEnabled: false,
                rowMoveHandling: "Update",
                onRowMoved: function (args) {
                  this.message("Row moved");
                },
                taskMoveHandling: "Update",
                onTaskMoved: function (args) {
                  this.message("Task moved");
                },
                linkCreateHandling: "Update",
                onLinkCreated: function (args) {
                  this.message("Link created");
                },
                rowCreateHandling: "Enabled",
                onRowCreate: function (args) {
                  this.tasks.add(new DayPilot.Task({
                    id: DayPilot.guid(),
                    text: args.text,
                    start: new DayPilot.Date().getDatePart(),
                    end: new DayPilot.Date().getDatePart().addDays(1)
                  }));
                },
              }
            },
            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();
            }
          });
        </script>
    </body>
</html>

See Also

History

  • April 27, 2018: Initial release