Ganttis
Published in

Ganttis

Customizing Ganttis charts

Regional background, baseline times, allocation-based bar heights and anything else you’d want — using (new) settings and GanttChartContentPresenter delegate

OK. You’ve already got a Gantt chart instance set up, everything looks fine, your app runs great. Your customer, however, has just come up with new requirements, such as: regional backgrounds around summary items, showing smaller bars depending on resource assignments just like in a load chart, and/or drawing secondary bars for each item, representing baseline time ranges, for example.

You start to worry, but you shouldn’t. Ganttis components have got you covered well. All you need to do is to customize drawing a bit.

Some things can be easily configured with component or item level settings. Such as using the new regional background color properties that we’ve added since Ganttis version 2.1.12 — see below. For others, you might need to customize presentation with code; but even for that case, we’ve prepared a protocol you can easily follow to update the way drawing goes.

Regional background

The regional background color can be set, for example, for all summary items at once:

ganttChartContentController.style.regionalBackgroundColorForType[.summary] = Color(red: 0.65, green: 0.65, blue: 0.65, alpha: 0.35)

Or you can do it for a single item (or in an item loop), for example based on a style definition object that also controls the item’s standard bar fill, with (a lot of) transparency:

item.style.regionalBackgroundColor = Color(taskStyleDefinition.barFill?.withAlphaComponent(0.15))

Baseline bars

Regional backgrounds, like a lot of other drawing aspects, is also fully customizable if you implement GanttChartContentPresenter protocol and delegate “yourself” as the presenter object of the GanttChartContentController object of a GanttChart instance.

For example, you can draw baseline bars — like those marked with orange ovals in the first screenshot above — as “regional background” too.

Note: these bars need to be drawn as such (and not together with drawing the actual bars — see below) because they can be anywhere on the screen from the horizontal point of view, while for optimization purposes Ganttis would not perform drawing bars much outside of their intended place in the standard drawing method:

As you can see in the code above, the GanttChartContentPresenter implementation is taking a few lines, but it is pretty straightforward: it will delegate most things to the underlying content view, and inject new code wherever it wants to customize the details.

drawRegionalBackground function above will actually call the custom, private drawBaseline method to supplementary draw “baseline” rectangles wherever the item context’s interval indicates.

The latter does require 10 lines of code or so itself, too, but it’s still a breeze because we can eventually use content view’s drawBar function to actually draw the final rectangle rather than manually filling a rectangle into the drawing context properly — but that is supported too if you need low level, much finer, control.

Don’t forget to eventually create and bind a presenter instance to the content controller:

override func viewDidLoad() {

contentController.presenter = customGanttChartContentPresenter
}
private lazy var customGanttChartContentPresenter = CustomGanttChartContentPresenter(viewController: self)

But there is still a caveat: also due to performance optimizations, the Gantt chart content controller will not draw regional backgrounds (at all) unless there is a color set up for the items it needs to display.

We may have set regional background colors for all or individual summary items, but standard ones should also have baselines, so they should also have regional background colors set. Even if we don’t want anything visible, we can just set clear color as the main regional background style setting, and we’re done:

contentController.style.regionalBackgroundColor = Ganttis.Color(red: 0.5, green: 0.5, blue: 0.5, alpha: 0)

Allocation based bar heights

Finally, let’s see how you can draw bars of different heights for items. Such as based on allocation values mapped to individual objects (through specific context instances):

This alternative GanttChartContentPresenter implementation calls drawCustomHeightBar from the “internal” drawBar method, eventually delegating the actual drawing of the bar to the content view again. This time, however, the output rectangle is obtained from the original one, adding top and bottom margins to lower down the height of the bar according to the context.allocation value of the item.

The maximum supported allocation percentage is 125% — bound to the original rectangle’s height — everything higher being truncated to that maximum height value instead.

Of course, you can fully customize the drawing, if needed, instead. Just remember to draw only inside the original rectangle.

And like above, don’t however forget to create and bind a presenter instance to the content controller:

contentController.presenter = customGanttChartContentPresenter

Note, as well, that you can combine regional backgrounds, including baseline bars, custom bar heights, and everything else you’d like, by just merging the setting definitions and CustomGanttChartContentPresenter implementations above. Exactly as you need. Exactly as your customer requests.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
DlhSoft

DlhSoft

Passionate team. Quality software.