Our state of the art Gantt chart


Post by leanit »

Hi,
We're encountering some inconsistent behavior when editing the task duration in the duration column. Specifically, we're trying to round the duration value when the unit is set to hours, as we don't want to allow decimal precision in this case.

Our approach has been to listen to the focusOut event of the durationField editor and round the value if the conditions are met. However, the solution works as expected intermittently—sometimes it rounds correctly, but other times it doesn't.

This is the piece of code we used:

{
                    id: 'duration', type: 'duration', editor: new DurationField({
                        allowedUnits: 'hour,day,week,month,quarter,year',
                        listeners: {
                            focusOut: (eventData) => {
                                const durationField = (eventData.source as any);
                                const durationFieldValue = durationField.value;

                            if (durationFieldValue.unit === 'hour' && !Number.isInteger(durationFieldValue.magnitude)) {
                                durationFieldValue.magnitude = Math.round(durationFieldValue.magnitude);
                            }
                        }
                    }
                })
            },

And also here's a video demonstrating the issue:

DurationStrangeBehaviour.mp4
(2.27 MiB) Downloaded 7 times

Is this the right approach to do something like this? Or are we doing something wrong?
We also tried changing the task duration, instead of the durationField magnitude, but it didn't seem to solve the issue.

Thank you, Luca.

Last edited by leanit on Tue Sep 17, 2024 3:02 pm, edited 1 time in total.

Post by tasnim »

Hi,

To achieve it, you should use the duration column renderer function https://bryntum.com/products/gantt/docs/api/Scheduler/column/DurationColumn#config-renderer

        {
            type : 'duration',
            renderer({ value }) {
                if (value.magnitude) {
                    const duration = value.magnitude;
                    const unit = duration > 1 ? value.unit + 's' : value.unit;
                    return `${unit === 'hours' ? Math.round(duration) : duration} ${unit}`;
                }
            }
        }

Hope it helps.

Best regards,
Tasnim


Post by leanit »

Hi Tasnim,
sorry for the confusion. What we're aiming for is not just to modify what the user sees, but to round the actual value of the duration magnitude itself.
With the solution you proposed, we only change the display for the user, while the underlying value still retains decimal precision.

I hope this clarifies things better.


Post by tasnim »

Hi,

To achieve it, you'd need to override the duration from the TaskModel

To override it use this approach

class Task extends TaskModel {
    static $name = 'Task';
    get duration() {
        return this.durationUnit === 'hour' ? Math.round(super.duration) : super.duration;
    }
}

And then set that class to https://bryntum.com/products/gantt/docs/api/Gantt/model/ProjectModel#config-taskModelClass

project : {
	taskModelClass : Task
}

And you should be good to go.

Best regards,
Tasnim


Post by leanit »

Hi Tasnim,
Thank you for your help. I’ve tried using the code you provided, but I’m encountering these two errors:

TaskError1.png
TaskError1.png (65.63 KiB) Viewed 104 times
TaskError2.png
TaskError2.png (87.63 KiB) Viewed 104 times

I’m working with TypeScript in the Angular framework. Could you help me understand what I might be doing wrong?


Post by tasnim »

Hi,

Please try using this

    // @ts-ignore
    get duration() {
        // @ts-ignore
        return this.durationUnit === 'hour' ? Math.round(super.duration) : super.duration;
    }

And this should be working.

Best regards,
Tasnim


Post by leanit »

Hi Tasnim,
thank you, it works now. We only had to add also this method:

   set duration(value: number) {
        this.duration = value;
    } 

Post Reply