Angular Standalone Smart.GanttChart

Smart.GanttChart as a standalone Angular component

This topic will show you how to use Smart.GanttChart and any other of our components in a combination of the new Angular's feature: standalone components. This feature was a preview in Angular 14 and now in Angular 15, it was introduced as a stable API.

What are standalone components?

The long-awaited feature: standalone components, allow the developer to create a component without declaring it in a NgModule. You can directly import the newly created component into another one. Standalone components can manage their template dependencies alone without NgModule. That reduces the need for NgModule and can make it optional. The goal is to shift the focus from NgModules to Components. A standalone component is marked as standalone with the property standalone: true The dependencies are directly specified in an imports array

Setup Angular Environment

To create new Angular project we need Angular cli:

npm install -g @angular/cli

the -g flag is for global. Once you install it you can use it everywhere, not only in this project.

Create a new project this way:

ng new smart-app

We do not need routing and we will use CSS, so press enter two times

Next navigate to smart-app

cd smart-app
  1. Delete src/app.component.spec.ts

    Delete src/app.module.ts

  2. Remove Everything from src/app.component.html

  3. Convert src/app/app.component.ts to standalone:

    @Component({
      selector: 'app-root',
      standalone: true,
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css'],
      imports: []
    })
  4. Bootstrap the AppComoponent in the main.ts file:

    // in the main.ts file
    import { bootstrapApplication } from '@angular/platform-browser';
    import { AppComponent } from './app/app.component';
    
    bootstrapApplication(AppComponent);

Setup Smart UI

Smart UI for Angular is distributed as smart-webcomponents-angular NPM package

  • Open the terminal and install the package:
    ng add smart-webcomponents-angular

    The command executes the following actions:

    1. Adds the smart-webcomponents-angular package as a dependency.
    2. Imports the Modules in the current application module.
    3. Registers the default Smart UI theme in the angular.json file.
    4. Adds all required peer dependencies to package.json
    5. Triggers npm install to install the theme and all peer packages that are added.

Import the GanttChartModule

Standalone components can use existing NgModules by directly importing them in the imports array.

To use Smart.GanttChart we should import our GanttChartModule in our application and since we are using a standalone component we will import it into the imports array:

Set the encapsulation to ViewEncapsulation.None for stylization purposes

import the GanttChartModule directly in app.component.ts

import { Component, ViewChild, ViewEncapsulation } from '@angular/core';
import { GanttChartModule } from 'smart-webcomponents-angular/ganttchart';

@Component({
  standalone: true,
  selector: 'app-root',
  imports: [GanttChartModule],
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  encapsulation: ViewEncapsulation.None
})

Initialize Smart.GanttChart

We did everything required to use Smart.GanttChart and it is time to create it:

Open app.component.html and use smart-gantt-chart component as shown:

<smart-gantt-chart 
  #gantt 
  [dataSource]="dataSource" 
  [durationUnit]="durationUnit" 
  [taskColumns]="taskColumns">
</smart-gantt-chart>

Now you must initialize the properties for the gantt chart

Open app.component.ts and paste the following inside the component's class:

export class AppComponent {
  title = 'smart-app';

  @ViewChild('gantt', { read: GanttChartComponent, static: false }) gantt!: GanttChartComponent;

  durationUnit = 'hour';

  taskColumns: GanttChartTaskColumn[] = [
    {
      label: 'Tasks',
      value: 'label',
      size: '60%'
    },
    {
      label: 'Duration (hours)',
      value: 'duration',
      formatFunction: (date: string) => parseInt(date)
    }
  ]

  dataSource = [];
}

We will style the tasks as you can see later, so open app.component.css and paste this:

smart-gantt-chart {
    height: auto;
}

.product-team {
    --smart-gantt-chart-task-color: rgb(94, 99, 181);
    --smart-gantt-chart-task-label-color: white;
    --smart-gantt-chart-task-label-color-selected: white;
}

.marketing-team {
    --smart-gantt-chart-task-color: rgb(43, 195, 190);
}

.dev-team {
    --smart-gantt-chart-task-color: rgb(242, 115, 112);
    --smart-gantt-chart-task-label-color: white;
    --smart-gantt-chart-task-label-color-selected: white;
}

.design-team {
    --smart-gantt-chart-task-color: rgb(255, 197, 53);
}

.qa-team {
    --smart-gantt-chart-task-color: rgb(99, 181, 144);
}

.release-team {
    --smart-gantt-chart-task-color: rgb(188, 150, 223);
    --smart-gantt-chart-task-label-color: white;
}

Injecting data service

You may have seen that the gantt chart is empty that is happening because in the dataSource we passed an empty array. Now we will create a data service for getting the data. This will show you how to use dependency injection with the standalone approach

  1. Open the terminal and run
    ng g service data
  2. Delete data.service.spec.ts
  3. Open data.service.ts and replace the
    @Injectable({
      providedIn: 'root'
    })
    with
    @Injectable()
  4. Import the GanttChartTask interface
    import { GanttChartTask } from 'smart-webcomponents-angular';
  5. Add this method inside the class:
    export class DataService {
    
      constructor() { }
    
      GetData(): GanttChartTask[] {
        
        const data: GanttChartTask[] = [
          {
            label: 'PRD & User-Stories',
            dateStart: '2019-01-10',
            dateEnd: '2019-02-10',
            class: 'product-team',
            type: 'task'
          },
          {
            label: 'Persona & Journey',
            dateStart: '2019-02-11',
            dateEnd: '2019-03-10',
            class: 'marketing-team',
            type: 'task'
          },
          {
            label: 'Architecture',
            dateStart: '2019-03-11',
            dateEnd: '2019-04-1',
            class: 'product-team',
            type: 'task'
          },
          {
            label: 'Prototyping',
            dateStart: '2019-04-02',
            dateEnd: '2019-05-01',
            class: 'dev-team',
            type: 'task'
          },
          {
            label: 'Design',
            dateStart: '2019-05-02',
            dateEnd: '2019-06-31',
            class: 'design-team',
            type: 'task'
          },
          {
            label: 'Development',
            dateStart: '2019-07-01',
            dateEnd: '2019-08-10',
            class: 'dev-team',
            type: 'task'
          },
          {
            label: 'Testing & QA',
            dateStart: '2019-08-11',
            dateEnd: '2019-09-10',
            class: 'qa-team',
            type: 'task'
          },
          {
            label: 'UAT Test',
            dateStart: '2019-09-12',
            dateEnd: '2019-10-01',
            class: 'product-team',
            type: 'task'
          },
          {
            label: 'Handover & Documentation',
            dateStart: '2019-10-02',
            dateEnd: '2019-11-01',
            class: 'marketing-team',
            type: 'task'
          },
          {
            label: 'Release',
            dateStart: '2019-11-01',
            dateEnd: '2019-12-31',
            class: 'release-team',
            type: 'task'
          }
        ];
    
        return data;
      }
    }
  6. The next step is to provide this service in our application, so open the main.ts file and add pass options to the bootstrapApplication method:
    bootstrapApplication(AppComponent, {
      providers: [
          DataService
      ]
    });

This is the way of using dependency injection with standalone components.

Filling Smart.GanttChart with data

Now since we have an injectable service, it is time to inject it in our AppComponent and use the GetData method to fill the Smart.GanttChart

Open app.component.ts and add the following constructor that will inject our service:

constructor(private dataService: DataService) {}

Now use the GetData function to pass records to the gantt chart

dataSource = this.dataService.GetData();

Result

Our Smart.GanttChart is ready and filled with data, this should be the result of the help topic: