My tasks are manually scheduled and when the start date changes, the task "bar" is shifting the entire task even though end date does not change. It seems like it's trying to maintain the original timespan between the task. Is there any way to prevent this? If you run the code below and click "adjust start date" you can see what I mean.
import './App.css';
import { useState, useRef, useMemo, useEffect } from 'react';
import '@bryntum/gantt/gantt.stockholm.css';
import { BryntumGantt } from '@bryntum/gantt-react';
import styles from './myModule.module.scss';
const DateDisplay = ({ date }) => {
return <span>{date.toDateString()}</span>
}
function BryntumComponent({ data }) {
const ganttRef = useRef(null);
const tasksRef = useRef();
const tasks = useMemo(() => {
return data.map((task) => {
return {
...task,
startDate: task.start,
endDate: task.due,
manuallyScheduled: true
};
});
}, [data]);
const [config] = useState({
viewPreset: {
timeResolution: { unit: 'day', increment: 1 },
headers: [
{ unit: 'year', dateFormat: 'YYYY' },
{
unit: 'quarter',
dateFormat: 'Q',
renderer: (date, __, { value }) => {
return `Q${value} ${date.getFullYear()}`;
}
},
{
unit: 'month',
dateFormat: 'MMM'
}
]
},
subGridConfigs: { locked: { width: '40%' } },
autoAdjustTimeAxis: false,
fixedRowHeight: false,
cellEditFeature: false,
cellMenuFeature: false,
columnReorderFeature: false,
taskMenuFeature: false,
taskEditFeature: false,
rowReorderFeature: false,
columnLines: false,
projectLinesFeature: false,
headerMenuFeature: false,
zoomOnTimeAxisDoubleClick: false,
zoomOnMouseWheel: false,
dependenciesFeature: { allowCreate: false },
sortFeature: false,
startDate: new Date(2023, 0, 1),
endDate: new Date(2025, 11, 30),
})
const [columns] = useState([
{
type: 'name',
field: 'name',
id: 'name',
autoHeight: true,
width: 100,
renderer: (args) => {
return [{ text: args.value, class: styles.nameCell }];
},
sortable: false,
leafIconCls: null,
},
{
field: 'start',
id: 'start',
text: 'Start Date',
type: 'date',
width: 100,
renderer: ({ record, value }) => {
if (!value) {
return '';
}
return <DateDisplay date={value} />;
}
},
{
field: 'due',
id: 'due',
text: 'Due Date',
type: 'date',
width: 100,
renderer: ({ record, value }) => {
if (!value) {
return '';
}
return <DateDisplay date={value} />;
}
},
]);
useEffect(() => {
if (ganttRef.current && tasksRef.current !== tasks) {
ganttRef.current.instance.taskStore.data = tasks;
tasksRef.current = tasks;
}
}, [tasks]);
return (
<div>
<BryntumGantt
ref={ganttRef}
columns={columns}
{...config}
/>
</div>
);
}
function App() {
const [data, setData] = useState([]);
useEffect(() => {
const load = async () => {
await new Promise(resolve => setTimeout(resolve, 1000));
setData([{ id: 1, name: 'task 1', start: new Date(2024, 0, 1), due: new Date(2024,6, 30)}]);
}
load();
}, []);
return (
<div style={{ height: '100%', display: 'flex', flexDirection: 'column', padding: 10}}>
<BryntumComponent data={data} />
<button onClick={(e) => setData(prev => [{ ...prev[0], start: new Date(2023, 6, 1)}])} style={{ width: 200 }}>Adjust start date</button>
</div>
);
}
export default App;