Our state of the art Gantt chart


Post by Jerther »

Hi!!

In a previous post, I mentioned there are multiple ways of getting an error in calculateDurationPure, and this is one of them. It was really hard to pin down, especially because it relies on a reply after a sync request, but I finally got it :geek: . Problems are indicated by a :!: Here are the steps:

  • Run the demo attached here
  • Scroll to row 134 and expand it
  • Edit the task at row 138, and go to the resources tab
  • Add a new resource, select "Resource id 15"
  • Click outside the grid to pre-apply the change. Notice the Gantt bars change, but that's all.
  • Now hit save.
  • A sync request is made and a reply is received.
  • :!: Rows 139 and 140 have their efforts raised from 8 hours each to 24 hours each. That shouldn't happen since they both are "Effort driven" and "Fixed Units"
  • Now edit the task at row 139 and go to the resources tab
  • Add a new resource and select "Resource 15"
  • Click outside the grid to pre-apply the change.
  • :!: an error occurs at ClassDefEx.calculateDurationPure

Post by alex.l »

HI Jerther,

Thank you for more info regarding this issue. We are investigating it and will keep you updated.

All best,
Alex

All the best,
Alex


Post by Jerther »

Hi Alex,

It's been a while, anything yet? We're still having this issue :(


Post by arcady »

I've partially processed your test case and fixed a couple of issues I found while checking it (mostly hitting performance ones) but then I had to jump to some other critical tickets.
I'm sorry for delay I'll prioritize this investigation and soon let you know of results.


Post by Jerther »

Thanks! :)


Post by arcady »

Jerther wrote: Tue Jun 23, 2020 3:38 pm
  • :!: Rows 139 and 140 have their efforts raised from 8 hours each to 24 hours each. That shouldn't happen since they both are "Effort driven" and "Fixed Units"

You are correct that it's caused by the response. Thing is you provide new start/end dates for those tasks in the response ..and it causes that recalculation.

What's the reason your backend suggests those new values? Do you have some server side logic that performs scheduling?

I'm not sure yet what should happen when a task w/ fixed units & effort gets updated with new start/end dates considering they are supposed to be calculated in this mode. :)
One option off the top of my head is the provided dates should be simply ignored in favour of calculated values. But we'll discuss the problem.
I've made a ticket so you could track the issue status: https://github.com/bryntum/support/issues/1316


Post by Jerther »

Good point. So it's the same issue I described here and it's already fixed. We haven't had anymore exceptions at calculateDurationPure since then, except once yesterday which might be related to this issue I reported earlier.

The reason our backend returned new date values was because of precision. Dates are stored with seconds precision so milliseconds, which Bryntum Gantt obviously makes use of, were dropped. Since we don't do any calculation with those values (yet...), I now just store them as plain string values so they are stored and loaded as is.

I'll consider this topic resolved for us. Still, please take a look at the other issue I mentioned.


Post by arcady »

Ah, so you don't need milliseconds info in date values.
I think that can be achieved easier and without those side effects caused by returning adjusted dates back to client.

How about using date formats without milliseconds mask? I've adjusted advanced demo Task model class (Gantt/examples/advanced/lib/Task.js file) this way:

import TaskModel from '../../../lib/Gantt/model/TaskModel.js';
import DateHelper from '../../../lib/Core/helper/DateHelper.js';

// let's make serialize function for date fields that will use the format defined on the fields
// to serialize Dates into Strings when passing data to the server
const serializeDate = function(date) {
    if (date instanceof Date) {
        date = DateHelper.format(date, this.format || this.dateFormat);
    }

    return date;
};


// here you can extend our default Task class with your additional fields, methods and logic
export default class Task extends TaskModel {

    static get fields() {
        return [
            // Override date fields on the Task model to use date format w/o milliseconds when reading/sending data to the server
            { name : 'startDate', type : 'date', format : 'YYYY-MM-DDTHH:mm:ssZ', serialize : serializeDate },
            { name : 'endDate', type : 'date', format : 'YYYY-MM-DDTHH:mm:ssZ', serialize : serializeDate  },
            { name : 'constraintDate', type : 'date', format : 'YYYY-MM-DDTHH:mm:ssZ', serialize : serializeDate  },
            ...

After these changes the Gantt will send the fields values to the server w/o milliseconds info ..it will also expect to get values w/o milliseconds from the server (so you'll need to adjust your server response accordingly).
I think that approach should work better in your case.

Providing values from the server as reaction on "sync" request is a valid use case ..yet it's mean to be used in cases when you have some advanced logic on server like:
1) server side scheduling
2) concurrency sessions when server replies with some delta changes came from another session
etc.
And responding fields involved in scheduling process automatically triggers chained rescheduling so need to be careful with such things. :)


Post by Jerther »

Neat! Thanks!


Post Reply