Premium support for our pure JavaScript UI components


Post by dwr »

We're seeing unexpected end dates when you have a finish to finish relationship and a negative lag. For example, you can go to https://bryntum.com/products/gantt/examples/frameworks/angular/advanced/dist/advanced/, and generate an example like this:

Image

Steps to reproduce:

  1. Delete all the tasks there and then just add 2 new ones A and B.

  2. Make A a 6 day task starting on Monday. It will finish end of day the following Monday. Make B a 1 day task and add a finish to finish from A to B with a 1 day lag.

Note that task B works one day (Friday), but it gets stretched out across the weekend, showing a day of work followed by two days on non work and an end date past the point where work stops. We would like the task end date to reflect the end of work on Friday.

Attachments
image (3).png
image (3).png (150.96 KiB) Viewed 573 times

Post by marcio »

Hey dwr,

I tried to reproduce the behavior that you described but didn't make it. I recorded a video of how I tried to reproduce, Am I following the right steps?? Could you provide more info about how to reproduce that?

Attachments
Bryntum Gantt - Advanced demo (Angular) - 3 May 2023.mp4
(568.23 KiB) Downloaded 23 times

Best regards,
Márcio


Post by arcady »

Note that task B works one day (Friday), but it gets stretched out across the weekend, showing a day of work followed by two days on non work and an end date past the point where work stops. We would like the task end date to reflect the end of work on Friday.

A Finish-To-Finish dependency with -1 day lag forces the successor to start not earlier than a day before the predecessor finishes:
successor.endDate >= predecessor.endDate - 1 day

The predecessor finishes 22 Jan 2019 so minus one day gives Mon 21 Jan 2019. Were the successor date 19 Jan 2019 the dependency would be violated.


Post by dwr »

@marcio your video was correct right up until the last step. It should be a negative lag (-1 day).

@arcady I think you mean "forces the successor to finish not earlier than a day". Your explanation makes sense, but we see a distinction between work days and calendar days. The task is finishing 1 work day before, and 3 calendar days before.


Post by arcady »

If you want to change the dependencies logic to allow invalid dependencies you can override the code.

It's located inEngine/quark/model/scheduler_pro/ScheduledByDependenciesEarlyEventMixin.ts file. The related methods are calculateEarlyStartDateConstraintIntervals and calculateEarlyEndDateConstraintIntervals. The calculateEarlyEndDateConstraintIntervals has code looking like this:

                    const interval : DateInterval       = dependencyConstraintIntervalClass.new({
                        owner       : dependency,
                        startDate   : calendar.calculateEndDate(
                            predecessorDate,
                            yield* project.$convertDuration(lag, lagUnit, TimeUnit.Millisecond)
                        ),
                        endDate     : null
                    })

The above code makes a constraining interval for the task based on its incoming dependency. You just need to skip non-working time after the date is calculated based on lag value:

                        startDate   : calendar.skipNonWorkingTime(
                            calendar.calculateEndDate(
                                predecessorDate,
                                yield* project.$convertDuration(lag, lagUnit, TimeUnit.Millisecond)
                            ),
                            lag <= 0
                        )

Post by dwr »

Great, thanks for the suggestion! We'll look into that.


Post by dwr »

Hello forum team! I have taken the advanced angular example and added the override, but it is not working for me. I still see the predecessor task spanning non work time for it's finish.

I downloaded the currently shipping 5.3.6 code and started with the code in examples/frameworks/angular/advanced I made these changes:

  1. tsconfig.json: changed to target": "es2020"
  2. src/styles.scss: added imports for bryntum styling
  3. src/app/gantt/gantt.config.ts: added enddate column, changed data to load to assets/data/nonWorkExample.json
  4. Add nonWorkExample.json which is a simple 3 task example showing the issue
  5. Added override to app.component.ts

The attached file has all the code.

Could you please let me know why it's not working correctly. Console logging the endDateNonWorkingTime value it looks correct, it's 2 days earlier than the "normal" endDate. Thanks!

Attachments
Archive.zip
(340.07 KiB) Downloaded 25 times

Post by arcady »

The code is wrong. Your code first calls the overridden method which fills intervals array with constraining intervals.

And then you additionally add new intervals to the array. So you basically doubled number of intervals and they all are taken into account when calculating the task dates.

The old interval restricts Setup load balancer task to start >= Monday 00:00 and your new interval to start >= Saturday 00:00. So the intersection of the intervals is >= Monday 00:00 which eventually wins.

You need to override the intervals built by the old code. Like this for example:

* calculateEarlyEndDateConstraintIntervals() {
    const intervals = yield* this._overridden.calculateEarlyEndDateConstraintIntervals.call(this);

    for (const interval of intervals) {
        const dependency = interval.owner;

        // if that's an interval built based on an incoming dependency
        if (dependency.isDependencyModel) {
            const lag = yield dependency.$.lag;
            const calendar = yield dependency.$.calendar;

            // adjust calculated value by skipping non-working time
            interval.startDate = calendar.skipNonWorkingTime(interval.startDate, lag >= 0);
        }
    }

    return intervals;
}

Post by dwr »

Thanks! This is looking good for the quick test example:

workDayFix.png
workDayFix.png (76.72 KiB) Viewed 333 times

Post by arcady »

FYI I've made a feature request for this behavior: https://github.com/bryntum/support/issues/6926


Post Reply