Premium support for our pure JavaScript UI components


Post by jit@flowit.dk »

Hi,

I'm using the "native gantt" with React. I can't figure out something as simple as configuring the width of the left side grid view. I have searched through documentation (this would be a good place to write about it: https://www.bryntum.com/docs/gantt/guide/Gantt/basics/sizing) and the forum, but to no avail.

I need the grid view to contain 8-12 columns, but they take up too much space. So I'd like to set the grid view to a width that only displays the Title column - and perhaps the Start Date and End Date as well. The user can then drag the grid view wider to access additional columns.

How do we achieve this? Preferably using react props.

-- Thanks :-)

Best regards
Jimmy Thomsen


Post by tasnim »

To achieve it, please check this https://bryntum.com/docs/gantt/api/Gantt/view/Gantt#config-subGridConfigs

Here is a sample of how you can use it:

subGridConfigs : {
	locked : { width: 200 }
}

Good Luck :),
Tasnim


Post by jit@flowit.dk »

Hi Tasnim.

Gantt fails with the following error when subGridConfigs is defined:

gantt.module.js:119490 Uncaught TypeError: Cannot read properties of undefined (reading 'normal')
    at Gantt.changeSubGridConfigs (gantt.module.js:119490:1)
    at Gantt.set (gantt.module.js:1986:1)
    at applyPropValue (WrapperHelper.js:97:1)
    at WrapperHelper.js:179:1
    at Array.forEach (<anonymous>)
    at shouldComponentUpdate (WrapperHelper.js:177:1)
    at BryntumGantt.shouldComponentUpdate (BryntumGantt.js:476:37)
    at checkShouldComponentUpdate (react-dom.development.js:12525:1)
    at updateClassInstance (react-dom.development.js:13039:1)
    at updateClassComponent (react-dom.development.js:17432:1)

It does work on the online demos though (e.g. https://bryntum.com/examples/gantt/aggregation-column/).
Our gantt was working fine before adding subGridConfigs. Could you investigate what causes this misbehaviour? It happens with both version 5.1.0 and 5.1.2.

Best regards
Jimmy Thomsen


Post by jit@flowit.dk »

... and declaring normal does not solve the problem - a new error is thrown:

subGridConfigs : {
    locked : { width: 200 },
    normal : { width : 100 }
}
gantt.module.js:19472 Uncaught Error: Id b-gantt-1-lockedSubgrid already in use
    at SubGrid.registerInstance (gantt.module.js:19472:1)
    at SubGrid.updateId (gantt.module.js:19437:1)
    at SubGrid.updateId (gantt.module.js:46448:1)
    at SubGrid.set (gantt.module.js:1999:1)
    at SubGrid.get (gantt.module.js:2051:1)
    at DomHelper.createElement (gantt.module.js:15059:1)
    at SubGrid.changeElement (gantt.module.js:45913:1)
    at SubGrid.changeElement (gantt.module.js:119128:1)
    at SubGrid.set (gantt.module.js:1986:1)
    at SubGrid.get (gantt.module.js:2051:1)

Best regards
Jimmy Thomsen


Post by tasnim »

I just investigate, and it works fine in react/react-typescript. Could you please provide your config code here? so we can check. It would be better if you could provide a runnable test case so we can debug it easily and can give you the result right away.


Post by jit@flowit.dk »

After investigating a bit further I'm starting to believe it might be related to Gantt being re-rendered multiple times. The error is thrown the 2nd time Gantt is rendered. This should not be a problem for React components though. Is Bryntum Gantt known to handle re-renders poorly?

The following works:

gantt.instance.subGrids.locked.width = 200

Best regards
Jimmy Thomsen


Post by marcio »

Hey Jimmy,

This is not exactly related to the re-rendered. As it's displayed in the documentation, subGridsConfig is a config, which means that they can only be set before the Gantt is rendered, you shouldn't try to update it after the component is rendered.

As you already notice with your working solution, to change that during runtime you need to change a property, like subGrids https://www.bryntum.com/docs/gantt/api/Grid/view/mixin/GridSubGrids#property-subGrids

Best regards,
Márcio


Post by jit@flowit.dk »

Hi Marcio.

Thanks for your input.

I was not aware that properties ending in Config could only be set once - good to know. I suppose this merely means that the values can't change - or that it won't be reflected in gantt at least. Surely declaring them on every render can't be a problem. That would be very anti React. Don't you agree ?

While the runtime solution works, I'd rather figure out why the React approach is not working. We have had several issues with the React wrapper where we've had to resolve to using the JS API instead, which completely defeats the purpose of using React. So I think its important that we figure out if we can make this thing work properly or not. If not, we would have to reconsider using React Gantt. The lack of types is also a major concern at this point (viewtopic.php?f=51&t=22225).

We are in the process of establishing a development server so we can provide you with a runnable example demonstrating the problem.

Best regards
Jimmy Thomsen


Post by saki »

Some thoughts of re-rendering:

Gantt is a very complex component, not only from the UI point of view (a lot of html tags, many listeners installed on them, etc.) but also data pulled from the server could be huge. Furthermore, the scheduling engine runs every time when data is loaded or changed.

That means that upon creation of Gantt we send request to the server, receive data, run the scheduling engine, create html markup, install listeners, etc. All these action can take a considerable time, not speaking about preserving user changes between re-renders.

This is the reason why we try to avoid create-destroy cycle as much as possible, ideally we would have only one create, then the same instance lifetime and finally one destroy.

However, React does not work this way but its render method (or component function) runs many, many times during the component lifetime.

The Bryntum wrapper accounts for that and implements shouldComponentUpdate method (the wrapper is implemented as React class component) which practically always returns false to prevent the React re-render (destroy and re-create) but it updates the existing instance. The code in the wrapper is:

function shouldComponentUpdate(component: any, nextProps: Readonly<any>, nextState: Readonly<any>): boolean {
    const { props, instance, propertyNames, configNames } = component;
    const { instanceClass } = component.constructor;

    propertyNames.forEach((prop: string) => {
        if (props[prop] !== nextProps[prop]) {
            applyPropValue(instance, prop, nextProps[prop], false);
            // Check if property is a config and notify
            if (configNames.includes(prop)) {
                devWarningUpdateProp(instanceClass.$name, prop);
            }
        }
    });

    // Reflect JSX cell changes
    return nextState?.generation !== component.state?.generation;
}

Therefore, if you have decided to go w/o wrapper (which we do not recommend not only for the above) then you need to take care of the situation yourself. The summary of the situation is: React wants to render often, Bryntum wants to render once.

Some thoughs on config/property:

Config options are intended to be used only during Gantt creation. Config options are, for example, definitions of columns (columns become a column store on component creation), subGridConfigs are also meant as configuration for creation of Gantt left and right parts. Properties, on the other hand, are usually smaller such as rowMargin or similar and they are meant to be changeable at runtime (as long as they're not marked as read-only in documentation).

If you really cannot avoid changing of config option at runtime, you can use https://bryntum.com/docs/gantt/api/Core/Base#function-setConfig function.

I hope this sheds some light to the problem.


Post by jit@flowit.dk »

Very enlightening - thank you, Saki. It sounds like the React wrapper is designed in a way that should handle re-renders properly. I'll get back to you with a runnable example demonstrating how defining subGridConfigs using React props doesn't work. Hopefully we can identify the cause of the problem then.

Best regards
Jimmy Thomsen


Post Reply