Migrate easily thanks to the compatibility of
ScheduleJS public API with the FlexGanttFX API
SAME NAME OF THE MODEL CLASSES
SAME METHODS AND PARAMETERS
SAME GENERIC TYPING CAPABILITIES
FlexGanttFX Implementation | ScheduleJS Implementation | |
---|---|---|
Iterators | Some methods are returning Java Iterators | Same API returns Javascript Arrays |
Constructors | Some classes have multiple constructors with different sets of parameters | In Typescript, it is only possible to have one constructor per class but Typescript allows to use default arguments |
Time management | Java Instant class are used to represent all timings | Javascript "number" are used to represent all timings. We are using JodaJs specific library to manage timezone conversions and formatting to obtain texts |
Method overriding | Java allows to define multiple methods with the same name when using different sets of parameters | In Typescript, it is not possible to define multiple methods with the same name. Default arguments allow to mitigate this limitation but some methods had to be named differently for specific implementations |
JavaFX ObservableList | In some cases FlexGanttFX is using ObservableList | In ScheduleJS, in most of the cases, the function returns an array |
JavaFX Properties | In FlexGanttFX, most of the elements of the framework that can be customized by the developers are exposed as JavaFx Properties objects. These properties are used to allow the framework to automatically take into account the new values and redraw the screen automatically | In ScheduleJS, after updating a property, the developer will need to ask the framework to redraw the screen |
The TypeScript superset implements mandatory types in JavaScript. The ScheduleJS syntax is in fact as close as it can get to its FlexGanttFX counterpart. We managed to smoothly translate all the existing FlexGanttFX APIs to preserve the framework flexibility and ease of use.
The TypeScript code main role is to handle data structures and interactions within the graphics. The following example shows how to implement a simple aircraft Gantt from scratch in both FlexGanttFX and ScheduleJS.
Check out the differences between those two blocks of code: it is minimal!
public void start(Stage stage) {
GanttChart<Aircraft> gantt = new GanttChart<Aircraft>(new Aircraft("ROOT"));
Layer layer = new Layer("Flights");
gantt.getLayers().add(layer);
gantt.getRoot().getChildren().setAll(generateCustomData(layer));
Timeline timeline = gantt.getTimeline();
timeline.showTemporalUnit(ChronoUnit.DAYS, 50);
GraphicsBase<Aircraft> graphics = gantt.getGraphics();
graphics.setActivityRenderer(Flight.class, GanttLayout.class,
new ActivityBarRenderer<>(graphics, "Flight Renderer"));
graphics.showEarliestActivities();
...
}
readonly gantt: GanttChart<Aircraft> = new GanttChart<Aircraft>(new Aircraft("ROOT"));
public start(): void {
const layer: Layer = new Layer("Flights");
this.gantt.getLayers().push(layer);
this.gantt.addRows(...this.generateCustomDataSet(layer, true));
const timeline = this.gantt.getTimeline();
timeline.showTemporalUnit(ChronoUnit.DAYS, 50);
const graphics = this.gantt.getGraphics();
graphics.setActivityRenderer(Flight, GanttLayout,
new ActivityBarRenderer(graphics, "Flight Renderer"));
graphics.showEarliestActivities();
}
ScheduleJS is made of HTML, JS, and CSS. On top of what the web has to offer, the library proposes a set of high-value components to customize your graphics the way you like. Developers can build fantastic UI/UX scenarios by using both the possibilities granted by web technologies and the ScheduleJS components.
public void start(Stage stage) {
...
Scene scene = new Scene(gantt);
stage.setScene(scene);
stage.sizeToScene();
stage.centerOnScreen();
stage.show();
}
<div class="tutorial-aircraft-flight-content-container">
<div class="tutorial-aircraft-flight-time-line-info-filler">
</div>
<div class="tutorial-aircraft-flight-time-line">
<schedule-date-line class="tutorial-aircraft-flight-date-line"
[gantt]="gantt">
</schedule-date-line>
<schedule-event-line class="tutorial-aircraft-flight-event-line"
[gantt]="gantt">
</schedule-event-line>
</div>
<default-schedule-gantt-graphic class="tutorial-aircraft-flight-graphic"
[gantt]="gantt"
[ganttContainerElement]="nativeElement">
</default-schedule-gantt-graphic>
<default-schedule-button-bar class="tutorial-aircraft-flight-actions-bar"
[gantt]="gantt">
</default-schedule-button-bar>
</div>
protected ActivityBounds drawActivity(
ActivityRef<NetworkBookingActivity> activityRef, Position position,
GraphicsContext gc, double x, double y, double w, double h,
boolean selected, boolean hover, boolean highlighted,
boolean pressed) {
NetworkBookingActivity activity = activityRef.getActivity();
ScheduleNetworkBookingBean booking = activity.getUserObject();
y += 0;
/*
* Do not use entire height, align with top.
*/
h -= 5;
setBarHeight(h);
if (isNetworkBooking(booking)) {
gc.setFill(Color.STEELBLUE);
} else {
gc.setFill(Color.LIGHTSTEELBLUE);
}
gc.fillRect(x, y, w, h);
if (isPossibleToDrawText(w)) {
gc.setFontSmoothingType(FontSmoothingType.LCD);
setTextFill(Color.BLACK);
drawText(activityRef, booking.getLabel(),
TextPosition.CENTER, gc, x,
y, w, h, selected, hover, highlighted, pressed);
}
// border
gc.setStroke(Color.BLACK);
gc.strokeRect(x, y, w, h);
return new ActivityBounds(activityRef, x, y, w, h);
}
protected drawActivity(
activityRef: ActivityRef<NetworkBookingActivity>, position: ViewPosition,
ctx: CanvasRenderingContext2D, x: number, y: number, w: number, h: number,
selected: boolean, hover: boolean, highlighted: boolean,
pressed: boolean): ActivityBounds {
const activity = activityRef.getActivity();
const booking = activity.getUserObject();
y += 0;
/*
* Do not use entire height, align with top.
*/
h -= 5;
this.setBarHeight(h);
if (this.isNetworkBooking(booking)) {
ctx.fillStyle = Color.STEELBLUE.toCssString();
} else {
ctx.fillStyle = Color.LIGHTSTEELBLUE.toCssString();
}
ctx.fillRect(x, y, w, h);
if (this.isPossibleToDrawText(w)) {
this.setTextFill(Color.BLACK);
this.drawText(activityRef, booking.name,
ActivityBarRendererTextPosition.CENTER, ctx, x,
y, w, h, selected, hover, highlighted, pressed);
}
// border
ctx.strokeStyle = Color.BLACK.toCssString();
ctx.strokeRect(x, y, w, h);
return new ActivityBounds(activityRef, x, y, w, h);
}