Auto-scheduling behavior of Gantt Chart components

To enable auto-scheduling behavior on GanttChartDataGrid or GanttChartView component of Gantt Chart Light Library for Silverlight™ and WPF, Gantt Chart Hyper Library for HTML5/JavaScript®, or Gantt Chart Web Library for ASP .NET, you may set AreTaskDependencyConstraintsEnabled property of settings.areTaskDependencyConstraintsEnabled field to true.

When auto-scheduling is turned on and the end user updates scheduling fields for a task managed by the component, all dependent tasks will also be rescheduled accordingly. For example, if the end user updates finish date of Task A, and Task B has Task A set as its predecessor with Finish-to-Start dependency type, the component will automatically ensure that start date of Task B is the same as finish of Task A or a date later, if the date was in the past, it updates it accordingly. Moreover, if other tasks depend on Task B, they are also rescheduled, as needed, and this process goes recursively until all project is validated against dependency constraints. Therefore, it is recommended to keep the dependency chains as short as possible.

When tasks are grouped within summary tasks (optionally using multiple indentation levels), dependencies may be defined between summary tasks in the hierarchy also. Because summary items have start and finish dates defined as aggregating minimum and maximum start and finish dates of the child items they contain, auto-scheduling needs to apply dependency constrains on all target child items. For example, if in the context above, Task B was a summary item that included Task B1 and Task B2 underneath, the dependency between Task A and Task B is treated as if there were two dependencies: one between Task A and Task B1, and another one between Task A and Task B2. Therefore, it is recommended to have less dependent summary items and keep summary task dependency chains as short as possible.

Multiple dependency types are supported between two tasks, namely the source and target tasks (target task is the holder of the predecessor item, and source task is the task that it depends of):

Supplementary, a lag time may be defined on the predecessor item, meaning that the dependent task’s date must be in the future or in the past with that further working time span, generating a gap between the involved dates and times. If the lag time is negative, the gap between task dates is in the opposite direction, allowing tasks to overlap during the working time span it indicates.

By design, when -to-Start dependencies are set, both start and finish dates are updated for the target task, preserving its duration (similar to a task bar move). However, when -to-Finish dependencies are set, only finish date is updated for the target task, allowing its duration to change (similar to a task bar resize). When duration of the target task would become negative, in effect of a -to-Finish dependency constraint, finish date is instead set to the same value of start date, leaving duration set to zero (this doesn’t turn the task to a milestone, tough.)

For all updates, working time is computed using the individual schedule definition of the target task, when available, or otherwise using the schedule definition of the component (indicating working week and day start and finish days and times of day, and nonworking intervals.)

When multiple dependencies are defined between the same two items with different dependency types, they are applied in order and as indicated above. This is important if you are trying to define end-to-end dependencies, using both Start-to-Start and Finish-to-Finish dependency types between the same two tasks.

When auto-scheduling is enabled by initialization code, its effects will only occur when task data loading actually takes place. If you set it later, the currently loaded tasks are checked and some would be rescheduled at the time of the setting.

Auto-scheduling algorithm requires valid dependency chains, and no circular dependencies, considering both direct chains and summary item implied chains, as presented above. By default, the algorithm performs an initial task data check and removes some predecessor definitions if they generate circular dependencies (the victim predecessor items are chosen randomly.) If your data source ensures itself that you won’t have circular dependencies, though, you can set AreCircularDependenciesAllowed to true if you initialize auto-scheduling from initialization time, and avoid this data check (the check will always be run if you enable auto-scheduling after data is loaded). In this case, you’ll also need to write custom code to ensure that dependencies are not allowed to be created if they would generate circularities, by handling CreatingDependencyLine event and checking for pre-existing dependencies between the involved items using DependsOf method there.

Note that dependencies are assumed to be defined respecting the order of tasks, i.e. tasks at the bottom depend on tasks at the top. Inverse dependency chains are also supported, but mixing dependency chain types may affect some algorithms, such as the heuristics based auto-scheduling and resource leveling which were developed considering this assumption, conducting to partial, imperfect (yet, most of the time, good enough) solutions (WPF component allows balancing the number of supported dependency chain ordering changes to performance by using the AreTaskDependencyConstraintsEnabledMaxSteps setting).

Note also that when minimum and maximum start and/or finish values (time constraints) are set for tasks, these take precedence over dependency constraints, i.e. they have higher priority and are only ignored if it logically impossible otherwise (and this can happen for finish values only).

Finally, it is important to understand that each task item has an internal preferred start date set to the same value as start when the end user changes that start value or to the initial start value from data loading time if the user hasn’t yet updated that task. Whenever the auto-scheduling algorithm changes the start value of a target task, the preferred start is maintained to the original value, i.e. the start value that was previously set by the end user or from the load time. When the end user reschedules the source task and auto-scheduling would need to reschedule the target task’s start date to a date in the past due to the new constraint, it will ensure it doesn’t go beyond the preferred start value. This is very useful to provide this behavior by design: supposing that the end user moves Task A to the future, Task B moves to the future accordingly; when the end user moves Task A back to the original time (without updating Task B himself or herself), Task B also gets back to the original time (if Task B was moved by the end user too, then it won’t move again to the past, since its preferred start was updated in the meantime and must be respected by the algorithm).