ScheduleJS 1.4 release notes. A step forward towards modern Angular app building.
In this article, we will discover a step-by-step implementation on how to use the ScheduleJS API to synchronize multiple graphics together and use a single timeline for two or more graphics.
To keep things simple let’s set our objective first:
<demo-schedule-booking> demonstration component. This component is capable of displaying a ScheduleJS Gantt chart.Note that the same approach can be used with two completely different graphics.
A good idea is to use a containerized version of our graphics to be able to handle the display of multiple graphics with ease, using components.
Now let’s start by creating a dual-gantt component and try out our <demo-schedule-booking> component.
<!-- Let's start with one graphic at a time -->
<demo-schedule-booking><demo-schedule-booking/> Fow now, if our <demo-schedule-booking> component is functional, our dual-gantt component will display the following screen, which is in fact identical to the original component.
Now we can create a <div> and use our <demo-schedule-booking> component twice in our brand new dual-gantt component:
<!-- Let's assemble two ScheduleJS demo bookings in our component -->
<div class="gantts-container">
<demo-schedule-booking class="first-gantt"></demo-schedule-booking>
<demo-schedule-booking class="second-gantt"></demo-schedule-booking>
</div> We added CSS classes to properly display one graphic above the other and separate them with a border. Here, the gantts-container class handles the display while the first-gantt and the second-gantt classes handle specificities, like the separation border.
We now have two unsynchronized graphics inside our new dual-gantt component:
To further improve the display, we adapted our <demo-schedule-booking> component to accept two new input properties:
displayTimeline: True by default, as we are going to use a single timeline, it is not necessary to repeat the timeline in both graphics.displayButtonBar: True by default, will let us hide the button bar to only keep one button bar for both graphics.As a ScheduleJS Gantt component, <demo-schedule-booking> also accepts additional inputs by default. Here we will use the dragToResizeInfoColumnPrevented input property to prevent any individual info-column resize for both graphics. The result should get rid of the button bar and timeline for the second graphics:
<!-- Let's add a few properties to better handle the dual-gantt display -->
<div class="gantts-container">
<demo-schedule-booking class="first-gantt"
[dragToResizeInfoColumnPrevented]="true">
</demo-schedule-booking>
<demo-schedule-booking class="second-gantt"
[displayTimeline]="false"
[displayButtonBar]="false"
[dragToResizeInfoColumnPrevented]="true">
</demo-schedule-booking>
</div>
We want to create a new timeline object and pass it down to our graphics once our dual-gantt component mounts. Here is the source code of our dual-gantt component:
// Our dual-gantt component
import {Component, Injector} from "@angular/core";
import {Timeline} from "schedule";
@Component({
selector: "dual-gantt",
templateUrl: "./dual-gantt.component.html",
styleUrls: ["./dual-gantt.component.scss"]
})
export class DualGanttComponent {
// Here we create a single timeline, which requires the Angular Injector
readonly timeline: Timeline = new Timeline(this._injector);
// Use dependency injection to provide an instance of the Angular Injector
constructor(private readonly _injector: Injector) { }
} Now we have to pass down our new timeline object as an input to our <demo-schedule-booking> ScheduleJS Gantt component in the dual-gantt component template:
<!-- Pass our freshly instanciated timeline object for registration in both components -->
<div class="gantts-container">
<demo-schedule-booking class="first-gantt"
[timeline]="timeline"
[dragToResizeInfoColumnPrevented]="true">
</demo-schedule-booking>
<demo-schedule-booking class="second-gantt"
[timeline]="timeline"
[displayTimeline]="false"
[displayButtonBar]="false"
[dragToResizeInfoColumnPrevented]="true">
</demo-schedule-booking>
</div> The last step is to register the timeline in the <demo-schedule-booking> component.
To do so, we decided to create a setter method, which will run the registration code when the input is passed down to the component:
export class DemoBookingComponent extends DefaultScheduleTreeGanttComponentBase<ResourceRow, DefaultScheduleGanttGraphicTreeComponent<ResourceRow>> {
// [...]
// Register the given timeline or do nothing
@Input()
set timeline(timeline: Timeline | undefined) {
if (timeline) {
this.gantt.setTimeline(timeline);
this.gantt.getGraphics().setTimeline(timeline);
}
}
// [...]
} The following video shows the synchronized graphics:
This example is just a simple implementation of synchronized graphics. The goal of this article is to illustrate how you can quickly combine multiple graphics to build a unique screen. You can use the same principles to combine different kinds of graphics (histogram, Gantt, curve) as we do in the ScheduleJS Viewer for example!
ScheduleJS 1.4 release notes. A step forward towards modern Angular app building.
Angular 16 vs Angular 18 comparison: discover what's new in Angular, the arrival of signals, Zoneless mode, zone coalescing, and their impact on your projects.
Discover the Angular Rome Conference: workshops, domain-driven design, signals, state management, micro frontends.
Discover Angular 18: zoneless mode, zone coalescing, native await, and TypeScript 5.4 compatibility.
The TOP 3 JavaScript Gantt chart. Discover their features, advantages, and disadvantages to choose the best tool for your project.
Discover how ScheduleJS seamlessly integrated with Selligent CRM, enhancing scheduling efficiency for a leading beauty brand's consultants.
This article showcases the integration of a ScheduleJS component into an external Ag-Grid table, to demonstrate the flexibility of ScheduleJS.
How to build an interactive context menu? A deep dive into ScheduleJS event handling and recommended practice to build your own context menu.
This article shows how to implement dynamic rendering depending on the current zoom-level of the graphics.
This article proposes a step-by-step implementation of an animation mechanism using JavaScript Date API for your activities.