What’s New In Gantt 4.0

Today we are super happy to announce to you the 4.0.0 version of Bryntum Gantt. The release includes cool new features, lots of of bug fixes as well as the usual house cleaning and refactoring under the hood. To learn about all the changes, as always please see the change log and we also recommend you to carefully read the upgrade guide to help you update to this version.

Version bump from 2.0 to 4.0

Gantt’s version was bumped from 2.0 up to 4.0 to bring it inline with Grid, Scheduler, Scheduler Pro and Calendar. This was done to make it clearer which versions belong together. Moving forward the plan is to keep the versions of all our components in sync.

New faster calculation engine

The scheduling engine of the Gantt chart has been upgraded. It is now based on the latest version of the underlying graph based calculation engine ChronoGraph. The API is very similar to the old version, but it has much better performance. In our bigdataset demo Gantt 4.0 displays 10,000 tasks about 2-3 times faster than the 3.0 version (Y-scale is seconds, lower is better):

  • Time to render 10k tasks

Stay tuned for a separate blog post on performance improvements.

Client side MS Project export

The Gantt chart is now capable of exporting to an XML file format importable in MS Project, which you can enable with the MspExport feature. The new feature is accompanied by a new msprojectexport demo:

MS Project export demo

Resource histogram

A new ResourceHistogram widget (inherited from Scheduler Pro, included in Gantt) to visualize the workload for resources. Showcased in a new resourcehistogram demo:

Resource histogram demo

Combining Gantt with Scheduler Pro

Since Scheduler Pro can consume a Gantt project, visualizing the same data in both products simultaneously is now super easy. Any change in one is reflected instantly in the other. Be sure to check out the new gantt-schedulerpro demo:

Gantt + Scheduler Pro combination demo

Gantt is now a Panel

For convenience, Gantt’s base class was changed to Panel. This allows it to hold top (tbar) and bottom (bbar) toolbars by itself without the need of adding it to an external Panel.

const gantt = new Gantt({
     tbar : [
       { text : 'New event' },
       ...
     ],
     ...
});

You can see this in action in the updated advanced demo:

Gantt with toolbar

Easier to customize context menus

Naming and customization of the different context menus in Gantt was simplified. Each menu is represented by a feature, available features are:

Each feature was refactored to be much easier to customize. It is now possible to add new items or modify/remove built in items in a single config, see for example the items config for TaskMenu:

const gantt = new Gantt({
     features : {
       taskMenu : {
         items : {
           // hide the built in "Delete task" item 
           deleteTask : false,
           
           // customize the "Edit task" item
           editTask : {
             icon : 'b-fa b-fa-edit'
           },

           // add a custom item
           myItem : {
             text : 'My very own menu item',
             icon : 'b-fa b-fa-candy-cane'
           }
         }
       }
     },
     ...
});

Take a look at the updated taskmenu demo to see it in use:

Customized task menu

New demo showing how to customize the task bar rendering

Over the last year, we received lots of questions on how to customize the look of the task bar so we decided to build a new demo showing you how easy it is. In the demo, the taskRenderer is used to read the assigned resources of each task and output an avatar for every resource. Also the progress bar has been compressed and moved to the top as a thin line achieving a modern look with minimal effort.

Custom taskbar rendering

taskRenderer({ taskRecord, renderData }) {
    if (taskRecord.isLeaf && !taskRecord.isMilestone) {
        // For leaf tasks we return some custom elements, described as DomSync config objects.
        // Please see https://bryntum.com/docs/gantt/#Core/helper/DomHelper#function-createElement-static for more information.
        return [
            {
                tag   : 'div',
                class : 'taskName',
                html  : taskRecord.name
            },
            ...taskRecord.resources.map(resource => ({
                tag     : 'img',
                src     : this.resourceImagePath + resource.name.toLowerCase() + '.jpg',
                dataset : {
                    resourceId : resource.id
                }
            })
            )
        ];
    }
}

Easier to customize the task editor

Customizing the task editor has been simplified in a similar was as for context menus. Tabs and fields can be added, modified and removed using the items config:

const gantt = new Gantt({
     features : {
       taskEdit : {
         items : {
           // customize a built in tab and its fields
           generalTab : {
             title : 'Common',
             items : {
                // hide the endDate field
                endDateField : false,

                // add a custom field
                deadlineField : {
                  type  : 'datefield',
                  name  : 'deadline',
                  label : 'Deadline'
                }
             }
           },
           // hide the notes tab
           notesTab  : false,
           // add a custom tab
           customTab : {
             title : 'Job',
             items : {
               ...
             }
            }
         }
       }
     },
     ...
});

Check it out in the updated taskeditor demo:

Customized task editor

Experimental support for Salesforce Lightning Locker Service

Version 4.0 contains a special bundle to use the Gantt chart inside Lightning web components. We have also made a new demo which you can find in the /examples/salesforce folder.

// Gantt component
export default class Gantt_component extends LightningElement {
    renderedCallback() {
        if (this.bryntumInitialized) {
            return;
        }
        this.bryntumInitialized = true;

        Promise.all([
            loadScript(this, GANTT + "/gantt.lwc.module.js"),
            loadStyle(this, GANTT + "/gantt.stockholm.min.css")
        ])
            .then(() => {
                this.createGantt();
            })
            .catch(error => {
                this.dispatchEvent(
                    new ShowToastEvent({
                        title: "Error loading Bryntum Gantt",
                        message: error,
                        variant: "error"
                    })
                );
            });
    }

    createGantt() {
        bryntum.gantt.init(this.template);

        const GanttToolbar = GanttToolbarMixin(bryntum.gantt.Toolbar);

        const project = new bryntum.gantt.ProjectModel({
            calendar: data.project.calendar,
            startDate: data.project.startDate,
            tasksData: data.tasks.rows,
            resourcesData: data.resources.rows,
            assignmentsData: data.assignments.rows,
            dependenciesData: data.dependencies.rows,
            calendarsData: data.calendars.rows
        });

        const gantt = new bryntum.gantt.Gantt({
            project,
            startDate: "2019-01-12",
            endDate: "2019-03-24",
            columns: [
                { type: "wbs" },
                { type: "name", width: 250 },
                { type: "startdate" },
                { type: "duration" },
                { type: "resourceassignment", width: 120 },
                { type: "percentdone", showCircle: true, width: 70 },
                {
                    type: "predecessor",
                    width: 112
                }
            ],

            features: {
                rollups: {
                    disabled: true
                },
                baselines: {
                    disabled: true
                },
                progressLine: {
                    disabled: true,
                    statusDate: new Date(2019, 0, 25)
                },
                taskMenu: {
                    items: {
                        convertToMilestone: true
                    },
                    processItems({ taskRecord, items }) {
                        if (taskRecord.isMilestone) {
                            items.convertToMilestone = false;
                        }
                    }
                },
                filter: true,
                dependencyEdit: true,
                timeRanges: {
                    showCurrentTimeLine: true
                },
                labels: {
                    left: {
                        field: "name",
                        editor: {
                            type: "textfield"
                        }
                    }
                }
            }
        });

        window.panel = new bryntum.gantt.Panel({
            appendTo: this.template.querySelector(".container"),
            height: '100%',
            tbar: new GanttToolbar({ gantt })
        });
    }
}

Salesforce Locker Service Gantt Integration DemoMore information about this integration will follow in a later blog post.

Renamed themes

The Default theme was renamed to Classic, to highlight that we actually changed our default theme to be Stockholm back in version 2. Since Light and Dark themes was variations of the Default theme they too were renamed to show that they belong together. Their new names are Classic-Light and Classic-Dark.

Renamed themes

Dropped support for Edge 18

In 4.0 we are dropping support for Edge 18 and older. Please note that older Edge versions likely will continue to work, but we are no longer actively testing it or adding any browser specific fixes for it. Also note that the new blink based Edge is supported.

Learn more

The new features and examples we add are almost exclusively a result of the feedback received from our community. We hope you will enjoy these new features and please keep the feedback coming. For full details please see the Gantt change log.

Download Free Trial

Leave a Reply

avatar
  Subscribe  
Notify of