3 - Elements
4 - Model
We recommend structuring your Angular project as described in 2.1 - Angular.
You can download the starting point of this demo here:
Alternatively, here is the complete source code of the Simple Aircraft Gantt example:
You now have an Angular component to host your new schedule. Now, most of the coding will happen in our simple-aircraft-gantt.component.ts file.
FlexGanttFX(JavaFX) code snippets are given if you are migrating to ScheduleJS.
If you want to take a quick peek at this example, you can have a look at the code (4 files).
The model will define the whole data structure of the project. In this tutorial, we will build a simple GanttChart representing the activities of two Aircraft.
The Row class is being used to define a hierarchical data structure with the help of three type arguments: the first one specifies the type of the parent row, the second one the type of the children's rows, and the third one the type of activities that will be shown on the right-hand side of the Gantt chart.
An extension ModelObject of a Row could look like this:
In this Gantt chart, we want to display a schedule of a few simple aircraft flights. Instances of Flight will be shown as a horizontal bar in the graphics area, while Aircraft will be displayed vertically in the tree table area.
Here, we will create a new file to hold our Aircraft and Flight classes and store them in a new folder that we will name model. This folder will have models and classes useful for our Gantt. Note that this architecture is just a recommendation.
Let's create a new model folder under /src/app/simple-aircraft-gantt/ and declare our Aircraft and Flight classes in it in a new aircraft.model.ts file:
We will now extend DefaultScheduleGanttComponentBase with our Gantt Row type <Aircraft> to inherit the boilerplate code of the default Gantt class.
If you are new to generic typings, more informations about type variables can be found on this page.
Now let's create the Gantt variable in the following file: /src/app/simple-aircraft-gantt/simple-aircraft-gantt.component.ts.
After editing the file, you should end up with this:The GanttChart uses the start() method to initialise its lifecycle. We will put our configuration code in here.
The ActivityBase class is used for read only data. If we want to edit flights, our Flight activity will need to extend the class MutableActivityBase instead of ActivityBase. Additionally we can attach a user object to any Activity. Here, we are going to attach our FlightData by building a class representing the data.
The minimal requirements for the MutableActivityBase are the name of the activity and its duration, represented by a start time and an end time. You can then attach any additional data using the FlightData class by linking it using the activity.setUserObject(data: object) method.
All that is left to do now is to add Activities (here, Flights) to the Aircrafts. For this we can simply call the method Row.addActivity(Layer, Activity).
Rows do not store activities themselves, instead they are delegating all activity-related functionality to a data field of type ActivityRepository. The default repository is of type IntervalTreeRepository. Applications can implement their own repositories and register them by calling Row.setRepository().
Model Layers are used to create groups of activities so that they can be shown or hidden together. In our example we want to group Flights based on their service type. (cargo, charter, training, etc...)
Now the Gantt chart knows on which Model Layers it needs to render the Activities and we can now link the Activities to the Model Layers. This is done by adding the Activities to the Rows (Here, adding Flights to Aircraft) and specifying the target Model Layer at the same time. We will then add each Aircraft to the GanttChart using this.gantt.addRows(...rows). Finally, for this example we will set the Timeline to display a day on 400px using this.gantt.getTimeline().showTemporalUnit(ChronoUnit.DAYS, 400).
Current Result Overview
In the following code sample we are combining all of the steps from above and creating our component: SimpleAircraftGanttComponent.
For now, our component includes 4 files:
1 - The Angular HTML Template file: It will display the Timeline composed of a <schedule-date-line> and a <schedule-event-line>.
Below, it will display the Gantt using <default-schedule-gantt-graphic>.
2 - The Template SCSS file:
3 - The Model definition file:
4 - The main Typescript file:
The image below shows the three Flights of the two Aircraft we just created.
This result is not bad for just a few lines of code, however the rendering of the Flights is the default one. We can customise the rendering appearance by registering a different ActivityRenderer for the activity type Flight. This is done by calling the method graphics.setActivityRenderer(). The graphics element is the right-hand side of the Gantt chart. It will be responsible for rendering all Flights. We can now register our activity renderer like in the following example (see line 28).
This replaces the default activity renderer with a renderer that draws a fixed-height bar. What's interesting about this code is that we are not only passing the activity type and the renderer instance but also a layout type. We don't want to spend too much time on layouts in the context of this quick start guide but let's just say that ScheduleJS is capable of displaying activities in several different ways (as time bars, as chart entries). If you want to build a more complex ActivityRenderer that will differentiate each Model Layer, you can implement the renderer given in 3.3.5 - Activity Rendering.
Our example now looks like this:
We can now add a DefaultScheduleButtonBar to the example. This allows us to perform actions on the chart and also to verify that the layers have been added properly. The following lines of code are needed for this.
You should see the different Model Layers when clicking on the Layers button, and you could redefine their orders and opacity. Note that their order effects which layer is going to be drawn above or below. The following screen shows the Layer View and how looks the Model Layer specific ActivityRenderer.
Now that we have visualised our data we obviously want to interact with it and we want to be informed about the changes that we make. Our activities are, by default, editable. This means we can drag them horizontally. To receive events we need to subscribe to an Angular observable to receive an ActivityEvent object describing the event. To get more information about the event, you could do the following in your simple-aircraft-gantt.component.ts file (see line 26):
When we run our application, moving an Activity will now log the following output in the browser console.
You will notice the three different event types ..._STARTED, ..._ONGOING, and ..._FINISHED. The first one gets fired when the user initiates an action, the second while the action is still in progress, and the third one when the action has finished. You can subscribe to other observables about the Timeline, the Eventline... etc.
Make sure to take a look at the various event types defined in the ActivityEvent class to find out how much information you can receive when the user performs editing operations.
All right! Your first scheduling application is up and running. To go more into details and see what's possible to build with ScheduleJS, please check out 3 - Elements, 4 - Model and 5. Styling (CSS).