Introduction
The graphics view uses the canvas API of JavaFX. This is due to the complex nature of a Gantt chart and due to the large data volumes often observed inside of them. Directly rendering large quantities of activities into a bitmap is much faster than constantly updating the scene graph and reapplying CSS styling. FlexGanttFX implements a pluggable renderer architecture where renderer instances can be mapped to activity types, very similar to the way Swing was doing it.
The following code is an example of how to register a custom renderer for a given "Flight" activity type. Please note that the graphics view is capable of displaying activities in different layouts, hence the layout type must also be passed to the method.
GraphicsBase<?> graphics = ganttChart.getGraphics(); graphics.setActivityRenderer( Flight.class, GanttLayout.class, new FlightRenderer(graphics));
We usually also pass the graphics view to the renderer at construction time. This is needed as renderers will invoke a redraw on the graphics when any of its properties changes. This is very different to the Swing approach. This also implies that renderer instances should only be used for a single graphics view, the one that was passed to their constructor.
The following methods on GraphicsBase are used for working with renderers:
Method | Description |
---|---|
void setActivityRenderer(...); |
Registers a new renderer for the given activity and layout type. |
ActivityRenderer getActivityRenderer(...); |
Returns a renderer for the given activity and layout type. |
Drawing
Activity renderers have a single entry point for drawing, a method called draw(). This method is final and can not be overriden. Once invoked it will call various protected methods to perform the actual drawing. The call hierarchy looks like this:
- public final draw() .... calls ...
- protected ActivityBounds drawActivity()
- protected void drawBackground()
- protected void drawBorder()
- protected ActivityBounds drawActivity()
Subclasses are free to override any of the three protected methods to customize the activity appearance.
All drawXXX() methods have the same arguments:
ActivityRef<A> activityRef, // the activity to draw Position position, // agenda layout only (first, middle, last, only) GraphicsContext gc, // the graphics context into which to draw double x, // the location of the start time of the activity double y, // the y coordinate (0 when drawn on row or line location) double w, // end time location minus start time location double h, // row or line height boolean selected, // is activity currently selected? boolean hover, // is mouse cursor currently hovering over it? boolean highlighted, // is activity currently blinking? boolean pressed) // is user currently pressing on it?
Default Renderers
The following table lists the various activity renderers that are provided by default.
Renderer Class | Description |
---|---|
ActivityRenderer |
The most basic renderer for activities. Draws a filled rectangle at the location of the activity. All default renderers are subclasses of this type. |
ActivityBarRenderer |
Draws a bar instead of filling the entire area. The height of the bar can be specified. Also supports text in several locations inside and outside the bar. |
ChartActivityRenderer |
Draws a ChartActivity vertically depending on its chart value. |
CompletableActivityRenderer |
Subclass of the bar renderer. Draws a CompletableActivity as a bar with a section of its background filled with another color. The size of the section depends on the percentage complete value of the activity. |
These default renderers are attached to this page and can be downloaded here:
Activity Bounds
Every activity renderer is responsible for returning an instance of ActivityBounds after drawing the activity. These bounds are an essential piece for the framework and many operations will only work properly if these bounds are valid. They are being used for editing activities, for hitpoint detection, for laying out links, for context menus, and so on. The following table lists the attributes of the ActivityBounds class.
Attribute | Description |
---|---|
activity | The activity for which these are the bounds. |
activityRef | An activity referene pointing to the activity. |
layer | The layer on which the activity was drawn. |
layout | The layout that was used when the activity was drawn. |
lineIndex | The index of the line on which the activity is located (-1 if activity is on the row, not a line). |
position | The position of the bounds when the activity was drawn in agenda layout (first, middle, layout). This is needed becaue the same activity might be rendered in several pieces across several days. |
row | The row where the activity was drawn. |
Please ignore the attributes overlapColumn, overlapCount, and the list overlapBounds. These are all used internally for agenda layout related operations.
Properties
All renderers define several properties that can be used to customize their apperance. Many of these properties are depenent on the "pseudo state" of the activity: hover, pressed, selected, highlighted. To make it easier to lookup the right color at the right time several convenience methods are available:
Renderer | Method | Description |
---|---|---|
Renderer |
protected Paint getFill(boolean selected, boolean hover, boolean highlighted, boolean pressed); |
Returns the color to use for the activity background depending on pseudo states passed. |
ActivityRenderer |
protected Paint getStroke(boolean selected, boolean hover, boolean highlighted, boolean pressed); |
Returns the color to use for the activity border depending on pseudo states passed. |
ActivityBarRenderer |
protected Paint getTextFill(boolean selected, boolean hover, boolean highlighted, boolean pressed); |
Returns the color to use for text depending on pseudo states passed. |
Attachments:
ActivityRenderer.java (text/plain)
ActivityBarRenderer.java (text/plain)
CompletableActivityRenderer.java (text/plain)