Maintain zoom-to-fit in Angular Gantt component

18 Oct 20257 minutes to read

The zoom-to-fit functionality in the Angular Gantt component ensures the entire project timeline fits within the viewport, providing an optimal view of all tasks. When using the zoomToFit toolbar item, editing actions (e.g., cell edit, dialog edit, taskbar edit) or dynamic dataSource changes can cause the timeline to refresh, potentially losing the zoomed view. By leveraging the fitToProject method, you can maintain the zoom-to-fit state seamlessly. For editing actions, call fitToProject in the actionComplete and taskbarEdited events to reapply zoom-to-fit after modifications like updating task durations or dependencies. For dynamic dataSource changes, such as adding or removing tasks, invoke fitToProject in the dataBound event to adjust the timeline automatically. Ensure ToolbarService is injected and toolbar includes zoomToFit to enable this feature, with valid timelineSettings configured for accurate rendering. This approach maintains a consistent project overview, integrating with task scheduling, dependencies, and critical path for efficient project management.

The following example demonstrates how to use fitToProject after performing edit actions:

import { Component, ViewEncapsulation, OnInit, ViewChild } from '@angular/core';
import { GanttModule, GanttComponent, ActionCompleteArgs, ITaskbarEditedEventArgs, ToolbarItem, EditSettingsModel, EditService, SelectionService, ToolbarService } from '@syncfusion/ej2-angular-gantt';
import { projectNewData } from './data';

@Component({
  imports: [GanttModule],
  providers: [EditService, SelectionService, ToolbarService],
  standalone: true,
  selector: 'app-root',
  template:
    `<ejs-gantt #gantt id="ganttDefault" height="430px" [dataSource]="data" [taskFields]="taskSettings"[toolbar]="toolbar" [editSettings]="editSettings" (actionComplete)="actionComplete($event)" (taskbarEdited)="taskbarEdited($event)"></ejs-gantt>`,
  encapsulation: ViewEncapsulation.None
})

export class AppComponent implements OnInit {
  @ViewChild('gantt', { static: true }) public ganttInstance?: GanttComponent;
  public data?: object[];
  public taskSettings?: object;
  public toolbar?: ToolbarItem[];
  public editSettings?: EditSettingsModel;

  public ngOnInit(): void {
    this.data = projectNewData;
    this.taskSettings = {
      id: 'TaskID',
      name: 'TaskName',
      startDate: 'StartDate',
      endDate: 'EndDate',
      duration: 'Duration',
      progress: 'Progress',
      dependency: 'Predecessor',
      parentID: 'ParentID',
    };
    this.editSettings = {
      allowEditing: true,
      allowTaskbarEditing: true,
    };
    this.toolbar = ['Edit', 'ZoomToFit'];
  }

  public actionComplete(args: ActionCompleteArgs) {
    if ((args.action === "CellEditing" || args.action === "DialogEditing") && args.requestType === "save") {
      (this.ganttInstance as GanttComponent).dataSource = projectNewData;
      (this.ganttInstance as GanttComponent).fitToProject();
    }
  };
  public taskbarEdited(args: ITaskbarEditedEventArgs) {
    if (args) {
      (this.ganttInstance as GanttComponent).dataSource = projectNewData;
      (this.ganttInstance as GanttComponent).fitToProject();
    }
  };
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

The following example demonstrates how to use fitToProject after dynamically changing the data source:

import { Component, ViewEncapsulation, OnInit, ViewChild } from '@angular/core';
import { GanttModule,ToolbarItem, GanttComponent, ToolbarService} from '@syncfusion/ej2-angular-gantt';
import { ButtonModule } from '@syncfusion/ej2-angular-buttons';
import { projectNewData, data } from './data';

@Component({
    imports: [GanttModule, ButtonModule],
    providers: [ToolbarService],
    standalone: true,
    selector: 'app-root',
    template:
        `<button ejs-button id='changeData' (click)='changeData()'>Change Data</button>
       <br><br>
       <ejs-gantt #gantt id="ganttDefault" height="430px" [dataSource]="data" [taskFields]="taskSettings"[toolbar]="toolbar" (dataBound)="dataBound($event)"></ejs-gantt>`,
    encapsulation: ViewEncapsulation.None
})

export class AppComponent implements OnInit {
    @ViewChild('gantt', { static: true }) public ganttInstance?: GanttComponent | any;
    public data?: object[];
    public taskSettings?: object;
    public toolbar?: ToolbarItem[];

    public ngOnInit(): void {
        this.data = projectNewData;
        this.taskSettings = {
            id: 'TaskID',
            name: 'TaskName',
            startDate: 'StartDate',
            endDate: 'EndDate',
            duration: 'Duration',
            progress: 'Progress',
            dependency: 'Predecessor',
            parentID: 'ParentID',
        };
        this.toolbar = ['ZoomToFit'];
    }

    public dataBound(args: object) {
        this.ganttInstance.fitToProject();
    };

    public changeData(): void {
        this.ganttInstance.dataSource = data;
    };
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

See also