Our state of the art Gantt chart


Post by Qwerty »

I have all tasks set as manuallyScheduled. I have been looking for a way to detect if the tasks are in a position that violates any dependencies attached to them (And would have been moved if automatic scheduling was used).

I wasn't able to find such a function on the dependency or task models. Is there a way to get this info?


Post by arcady »

There is no such function I'm afraid, but that's a pretty straightforward thing to implement. Something like this:

import { DependencyType } from "./Gantt/lib/Engine/scheduling/Types.js"

// Collects violated dependencies
function getViolatedDependencies(task) {
    const
        incomingDeps = task.incomingDeps,
        result = [];

// collect violated dependencies
for (const dependency of incomingDeps) {
    const
        predecessor = dependency.fromEvent;

    switch (dependency.type) {
        case DependencyType.EndToEnd:
            if (predecessor.earlyEndDate > task.endDate) {
                result.push(dependency);
            }
            break;

        case DependencyType.EndToStart:
            if (predecessor.earlyEndDate > task.startDate) {
                result.push(dependency);
            }
            break;

        case DependencyType.StartToEnd:
            if (predecessor.earlyStartDate > task.endDate) {
                result.push(dependency)
            }
            break;

        case DependencyType.StartToStart:
            if (predecessor.earlyStartDate > task.startDate) {
                result.push(dependency);
            }
            break;
    }
}

return result;
}

I'm out of context how you plan to use this functionality ..if you need it to be always up to date w/ the engine data state you need to "yield" engine calculated fields, so I'd move the code to a method on the task and changed smth like this:

export class MyTask extends TaskModel {

// Collects violated dependencies
* getViolatedDependencies(task) {
    const
        incomingDeps = yield task.$.incomingDeps,
        result = [];

    for (const dependency of incomingDeps) {
        const
            predecessor = yield dependency.$.fromEvent;

        switch (dependency.type) {
            case DependencyType.EndToEnd:
                if ((yield predecessor.$.earlyEndDate) > (yield task.$.endDate)) {
                    result.push(dependency);
                }
                break;

            case DependencyType.EndToStart:
                if ((yield predecessor.$.earlyEndDate) > (yield task.$.startDate)) {
                    result.push(dependency);
                }
                break;

            case DependencyType.StartToEnd:
                if ((yield predecessor.$.earlyStartDate) > (yield task.$.endDate)) {
                    result.push(dependency)
                }
                break;

            case DependencyType.StartToStart:
                if ((yield predecessor.$.earlyStartDate) > (yield task.$.startDate)) {
                    result.push(dependency);
                }
                break;
        }
    }

    return result;
}

}

Post by arcady »

And I've just realized that my code doesn't take into account dependency lag. So instead of this code for example:

if ((yield predecessor.$.earlyEndDate) > (yield task.$.endDate)) {

there should be smth like this:

const
    lag      = yield dependency.$.lag,
    lagUnit  = yield dependency.$.lagUnit,
    calendar = yield dependency.$.calendar

if (calendar.calculateEndDate(yield predecessor.$.earlyEndDate, lag, lagUnit) > (yield task.$.endDate)) {

Post by Qwerty »

That works great. Thanks a lot for the example.


Post Reply