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.
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.
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)
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.
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?
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.
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.
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).
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.