Our state of the art Gantt chart


Post by phil714 »

Hello,

I'm having a lot of trouble updating the gantt data after every changes. We're trying to make a realtime feature where multiple users can look at the gantt and see the changes of everybody else in realtime. Right now it's working well for a single user because we feed the data the first time and then the gantt works by itself but the changes are not reflected to the other users until they refresh the whole page.

export const projectModel = new ProjectModel({
  validateResponse: true,
  autoSync: true,
});

// in the react component
const ganttResult = useGanttDataByProjectIdSubscription({ // graphql subscription
    variables: {
      projectId,
    },
    fetchPolicy: 'no-cache',
  });
  const project = ganttResult.data?.project;
  
// ... useEffect(() => { if (project) { // if the project is loaded projectModel.id = project.id; projectModel.startDate = project.start; projectModel.endDate = project.end;
const inlineData = { eventsData: [...], dependenciesData: [...], }; projectModel.inlineData = inlineData } }, [project]); // ... <BryntumGantt {...ganttConfig} features={{ ...ganttConfig.features, criticalPaths: { disabled: !criticalPathEnabled }, }} columns={columns} project={projectModel} ref={ganttRef} />

The logic is that everytime the gantt is updated, we're doing a server call, saving the data and when the data comes back, we update the gantt. We're not using the Crud Manager, we're saving the data everytime there is a sync (by listening to a beforeSync event). inlineData seems to be working the first time when the data is loaded but after that, every update does nothing at all, no error.

I tried a solution where I was removing all the listener, removing all the data from both stores and adding back the new data using removeAll() and looping to do insert but I don't think that's the right solution.

Not sure if this is really related to React of if there is something fundamental that I don't understand about inlineData and how to handle the project model and the data. I have many other problems related to this that I will discuss in other posts.

Thanks for the help


Post by Maxim Gorkovsky »

Hello.
Have you tried using loadInlineData method? https://bryntum.com/docs/gantt/#Gantt/model/ProjectModel#function-loadInlineData This method replaces data in the stores and recalculates the project.


Post by phil714 »

Hi,

Yes I did, to the same result. One thing I tried also was to reload the data using the native gantt instance.

ganttRef.current.instance.project.loadInlineData(inlineData);

https://www.bryntum.com/docs/gantt/#Gantt/guides/integration/react.md#the-native-bryntum-gantt-instance

Do you know if there are any reason to use this if I already have access to a ProjectModel instance ?


Post by Maxim Gorkovsky »

I tried calling that method locally, it reloads the data each time as far as I can tell. Could you try reproducing this on one of our framework demos using your data samples?

Do you know if there are any reason to use this if I already have access to a ProjectModel instance ?

We expose gantt instance for user's convenience


Post by phil714 »

Hello, sorry for the late update, my examples were not working for some reason. Here's what I tried

I reproduced the problem using the example in frameworks/react/typescript/basic and changed the AppConfig.ts and App.tsx file. In AppConfig.ts, I only removed the configuration related to the project because we don't want to load data from the JSON. In App.tsx, I create a new ProjectModel with a bit of data and pass it to the <BryntumGantt /> component. This data is then updated each 5 seconds and add 1 day to the start and the end which I would expect the block to move on its own on my screen. I also added the library luxon just to handle the date manipulation.

I reproduced the problem using the example in frameworks/react/typescript/basic and changed the AppConfig.ts and App.tsx file. In AppConfig.ts, I only removed the configuration related to the project because we don't want to load data from the JSON. In App.tsx, I create a new ProjectModel with a bit of data and pass it to the <BryntumGantt /> component. This data is then updated each 5 seconds and add 1 day to the start and the end which I would expect the block to move on its own on my screen. I also added the library luxon just to handle the date manipulation.

// AppConfig.ts

/**
 * Application configuration
 */
import { GanttConfig } from '@bryntum/gantt/gantt.umd.js';

const ganttConfig: Partial<GanttConfig> = {
    columns: [{ type: 'name', field: 'name', width: 250 }],
    viewPreset: 'weekAndDayLetter',
    barMargin: 10
};

export { ganttConfig };
// App.tsx

/**
 * Main Application script
 */
// Polyfills for Edge <= 18. Remove this line if you don't need support for it.
import 'core-js/stable';

import React, { Fragment, FunctionComponent, useEffect } from 'react';

import { BryntumDemoHeader, BryntumThemeCombo, BryntumGantt } from '@bryntum/gantt-react';
import { ganttConfig } from './AppConfig';
import './App.scss';
import { ProjectModel } from '@bryntum/gantt/gantt.umd.js';
import { DateTime } from 'luxon';

const projectModel = new ProjectModel({
    validateResponse : true,
    eventsData: [{
        id: 1000,
        name: "Launch SaaS Product",
        percentDone: 50,
        startDate: "2019-01-01",
        endDate: "2019-01-03",
    }]
})

const App: FunctionComponent = () => {
    useEffect(() => {
        setInterval(() => {
            const newEventData = (projectModel.taskStore as any)._data.map((d: any) => ({ 
                ...d, 
                startDate: DateTime.fromISO(d.startDate).plus({ days: 1 }).toISODate(),
                endDate: DateTime.fromISO(d.endDate).plus({ days: 1 }).toISODate()
            }))

        console.log(newEventData)

        const newInlineData = {
            eventsData       : newEventData,
            resourcesData    : [],
            assignmentsData  : [],
            dependenciesData : [],
        }

        // projectModel.inlineData = newInlineData;
        projectModel.loadInlineData(newInlineData);
    }, 5000)
}, [])

return (
    <Fragment>
        <BryntumDemoHeader
            title="React Basic demo with TypeScript"
            href="../../../../../#example-frameworks-react-typescript-basic"
            children={<BryntumThemeCombo />}
        />
        <BryntumGantt {...ganttConfig} project={projectModel}/>
    </Fragment>
);
};

export default App;

Post by saki »

The reason for not seeing tasks to move on the screen is that for automatically scheduled tasks changing only startDate or endDate of the task have no effect after the project is initially calculated (after the load of first data).

All other data (such as percent done or duration) is updated as would be expected.

When the user moves tasks with D&D he does not only change startDate/endDate (which would be just ignored as above) but changes the tasks constraints which causes the task to move on the screen visually (and sets the relevant constraints fields in the task data).

There is a guide that explains task scheduling in all details here: https://bryntum.com/docs/gantt/#../engine/gantt_events_scheduling.md

I have prepared a small demo to demonstrate this behavior. It is app.js file that will replace our vanilla basic gantt demo and I’m attaching it.

Attachments
app.js.zip
(942 Bytes) Downloaded 63 times

Post Reply