3.3 - Graphics
Introduction
The graphics element is responsible for the rendering of activities and system layers, editing of activities, event notifications, hit detection, system layer management, and for context menu support.
Rendering
The graphics element uses the Canvas API. This is due to the large data volumes often displayed by Gantt charts. The graphics element uses a pluggable renderer architecture where renderer instances can be mapped to activity types. The following code is an example of how to register a custom renderer for a given "Flight" activity and layout type. Please note that the graphics element is capable of displaying activities in two different layouts, hence the layout type must also be passed to the method.
const graphics = this.gantt.getGraphics();
graphics.setActivityRenderer(
Flight, // The type of activities that will be rendered.
GanttLayout, // The type of layout where the renderer will be used.
new FlightRenderer(graphics) // The actual renderer instance.
);
System Layers
Activities are not the only thing that can be displayed. There are also the current time now line layer, grid lines layer, inner lines layer, chart lines layer, and so on. All of these things are rendered by so-called system layers. You can have access to these layers list by calling graphics.get<layers name>(). The graphics manages six lists of these layers.
1. TransversalBelowViewSystemLayers
2. TransversalBelowRowSystemLayers
3. BackgroundLayers
4. ForegroundLayers
5. TransversalAboveRowSystemLayers
6. TransversalAboveViewSystemLayers
BackgroundLayers are drawn "behind" activities, ForegroundSystemLayers are drawn "in front of" activities. Each one of these lists are already pre-populated but can be changed by the application. For more information on the available system layers, please refer to their individual documentation.
System layers can be turned on and off directly via the API of the graphics element. For example, there is an opacity property for each layer. The value of these properties can be set by calling the method layer.setOpacity(number).
Editing
Two different callbacks are used to control the editing behaviour of Activities. The first maps a mouse event / mouse location to a EditMode and can be registered by calling graphics.setEditModeCallback(Activity, Layout, Callback: event => EditModeEnum). The ActivityEditingCallback is used to determine whether a given editing mode / operation can be applied to an activity at all. This callback is registered by calling graphics.setActivityEditingCallback(Activity, Callback: event => boolean) where returning true indicates that it can be edited. Most applications will only need to work with the ActivityEditingCallback and would keep the defaults for the EditModeCallback. (right edge used to change end time, left edge used to change start time...)
Events
Events of type ActivityEvent are sent whenever the user performs a change inside the graphics element. Components that want to receive these events can subscribe to an Angular Observable like this:
start(): void {
// ...
this.subscribe(graphics.getActivityEventObs(), (event) => console.log(event)); // Subscription.
// ...
}
Subsciptions made using this.subscribe are optimised and handle the unsubscription process depending on the component lifecycle.
Available observables : LassoEventsObs, MaxPixelRatioObs, ActivityEventsObs, TimelineModelChangeObs, EventLineModelChangeObs.
Events are fired when the actions begins, while the change is being performed and once it has been completed. The ActivityEvent class lists event types with three different endings: START, CHANGING and CHANGED.
Hitpoint Detection
The graphics element provides support for finding out information about a given activity. The ActivityBounds are represented with coordinates that represent an Activity. You can create an ActivityRef using given instances of Row, Layer and Activity. The time at an x-coordinate can be looked up by calling graphics.getTimeAt(x-coord: number). The opposite operation is also available: a x-coordinate can be found for a given time by calling graphics.getLocation(time: number).
// ...
const activityRef = new ActivityRef(aircraft1, trainingLayer, flight1);
const bounds = graphics.getActivityBounds(ActivityRef); // Return aircraft1, flight1 ActivityBounds.
graphics.getTimeAt(200); // Time at x = 200px.
graphics.getLocation(TimeUtil.now()); // Now coordinates.
// ...
Context Menu
By calling graphics.setContextMenuOpenRequestCallback(event => callback) a context menu specific callback can be registered with the graphics element. This callback will be invoked when the user triggers the context menu. A callback parameter object will be passed to the callback already populated with the most important values that might be relevant for building a context menu.