Dear Bryntum:
I have a question about how the startDate and endDate fields work in React Gantt? From the data we provide the tasksData -- I would expect the Gantt to render the startDate and endDate based on the values that we supply for each individual milestone or task?
However, I'm experiencing all startDates begin on the same date -- you can see from the screenshot of Gantt display provided (highlighted in red - START DATE column)?
Can you please explain to me if my configuration for the tasksData object is not setup correctly? I have supplied for your reference the gantt configuration, and a screenshot of the data that we are feeding into the tasksData object. This is labeled as the "GANTT DATA".
I have highlighted in a red box the first milestone ("Uncle Leo"). You will see that the startDate for this milestone is given as "2022-11-29". But the startDate is rendering everything as "2022-11-28" (see screenshot of the rendered Gantt chart -- start date column is all set at 11/28/2022 -- for each milestone and task)? I'm confused why this would be the case -- and hope you can explain. Am I supplying the wrong data -- or not formatting correctly? Please advise? Please note that the "Due Date" column (endDate) is also not showing proper dates compared to data supplied? The duration values are different?
Below is the gantt configuration file. You will see for the tasksData object -- we are feeding it the ganttData object (as shown in screenshot). I'm wondering if I'm doing this wrong -- or if this is some type of bug or issue with how gantt is rendering the data?
Please note the ganttData is the object I show in the screenshot attachment for the data that we are feeding into the tasksData (as shown).
I would appreciate your help with this.
Thanks so much!
import React, { useEffect, useRef, useState } from 'react'
import '@bryntum/gantt/gantt.stockholm.css'
import { useGetGantt } from '~/views/hooks/Gantt/useGetGantt'
import { withRouter } from '~/views/hooks/useRouter'
import dynamic from 'next/dynamic'
import Loader from '~/views/components/ui/Loader'
const Gantt = dynamic(() => import('./components/Gantt/Gantt'), {
ssr: false,
})
const PlanTimelineView = (milestone) => {
const ganttRef = useRef()
const [ganttData, setGanttData] = useState(null)
const [delayed, setDelayed] = useState(true)
const projectId = milestone.router.query.projectId
const { data } = useGetGantt({
projectId,
})
useEffect(() => {
if (data) {
setDelayed(false)
setGanttData((ganttConfig.project.tasksData = data.ganttChartTimelines))
}
}, [data])
const onSettingsRowHeightChange = ({ value }) => {
ganttRef.current.instance.rowHeight = value
}
const onSettingsMarginChange = ({ value }) => {
ganttRef.current.instance.barMargin = value
}
const ganttConfig = {
project: {
autoLoad: true,
hoursPerDay: 24,
daysPerWeek: 5,
daysPerMonth: 20,
validateResponse: true,
tasksData: ganttData,
},
taskMenu: {
items: {
indent: false,
outdent: false,
convertToMilestone: false,
},
},
tbar: {
items: [
{
type: 'buttonGroup',
items: [
{
ref: 'expandAllButton',
icon: 'b-fa b-fa-angle-double-down',
tooltip: 'Expand all',
onAction: () => {
ganttRef.current.instance.expandAll()
},
},
{
ref: 'collapseAllButton',
icon: 'b-fa b-fa-angle-double-up',
tooltip: 'Collapse all',
onAction: () => {
ganttRef.current.instance.collapseAll()
},
},
{
ref: 'zoomInButton',
icon: 'b-fa b-fa-search-plus',
tooltip: 'Zoom in',
onAction: () => {
ganttRef.current.instance.zoomIn()
},
},
{
ref: 'zoomOutButton',
icon: 'b-fa b-fa-search-minus',
tooltip: 'Zoom out',
onAction: () => {
ganttRef.current.instance.zoomOut()
},
},
{
ref: 'zoomToFitButton',
icon: 'b-fa b-fa-compress-arrows-alt',
tooltip: 'Zoom to fit',
onAction: () => {
ganttRef.current.instance.zoomToFit({
leftMargin: 50,
rightMargin: 50,
})
},
},
{
ref: 'previousButton',
icon: 'b-fa b-fa-angle-left',
tooltip: 'Previous time span',
onAction: () => {
ganttRef.current.instance.shiftPrevious()
},
},
{
ref: 'nextButton',
icon: 'b-fa b-fa-angle-right',
tooltip: 'Next time span',
onAction: () => {
ganttRef.current.instance.shiftNext()
},
},
],
},
{
type: 'buttonGroup',
items: [
{
type: 'button',
ref: 'settingsButton',
icon: 'b-fa b-fa-cogs',
text: 'Settings',
tooltip: 'Adjust settings',
toggleable: true,
menu: {
type: 'popup',
anchor: true,
cls: 'settings-menu',
layoutStyle: {
flexDirection: 'column',
},
onBeforeShow: 'up.onSettingsShow',
items: [
{
type: 'slider',
ref: 'rowHeight',
text: 'Row height',
width: '12em',
showValue: true,
min: 30,
max: 70,
onInput: (rowHeight) => {
onSettingsRowHeightChange(rowHeight)
},
},
{
type: 'slider',
ref: 'barMargin',
text: 'Bar margin',
width: '12em',
showValue: true,
min: 0,
max: 10,
onInput: (barMargin) => {
onSettingsMarginChange(barMargin)
},
},
],
},
},
],
},
{
type: 'button',
color: 'b-blue',
text: 'Export PDF/PNG',
icon: 'b-fa-file-export',
ref: 'exportButton',
tooltip: 'Export PDF/PNG',
onAction: () => {
ganttRef.current?.instance.features.pdfExport.showExportDialog()
},
},
{
type: 'button',
color: 'b-blue',
text: 'Export as .xslx',
ref: 'excelExportBtn',
icon: 'b-fa-file-export',
tooltip: 'Export Excel file',
onAction: () => {
const filename =
ganttRef.current?.instance.project.taskStore.first &&
ganttRef.current?.instance.project.taskStore.first.name
ganttRef.current?.instance.excelExporterFeature.export({
filename,
})
},
},
{
type: 'button',
color: 'b-red',
ref: 'criticalPathsButton',
icon: 'b-fa b-fa-fire',
text: 'Critical paths',
tooltip: 'Highlight critical paths',
toggleable: true,
onAction: () => {
ganttRef.current.instance.features.criticalPaths.disabled =
!ganttRef.current.instance.features.criticalPaths.disabled
},
},
],
},
columns: [
{ type: 'name', field: 'name', width: 230 },
{ type: 'date', field: 'startDate', text: 'Start Date', width: 50 },
{ type: 'date', field: 'endDate', text: 'Due Date', width: 50 },
{ type: 'duration', width: 70 },
{ type: 'effort', width: 70 },
],
viewPreset: {
base: 'weekAndDay',
displayDateFormat: 'YYYY-MM-DD',
},
barMargin: 10,
headerMenuFeature: true,
minHeight: 1000,
autoHeight: true,
excelExporterFeature: {
dateFormat: 'YYYY-MM-DD HH:mm',
},
pdfExportFeature: {
exportServer: 'http://localhost:3000',
translateURLsToAbsolute: 'http://localhost:3000',
clientURL: 'http://localhost:3000',
},
features: {
filter: true,
criticalPaths: {
disabled: true,
},
},
}
return !delayed ? (
<>
<Gantt ganttRef={ganttRef} {...ganttConfig} />
</>
) : (
<>
<Loader />
</>
)
}