Our state of the art Gantt chart


Post by alex.l »

Sure, I meant data model that we don't have to use this data format:

           "Id":"a0i7Q000000cXeeQAE",
           "Name":"P-000050",
           "Country__c":"NLD",
           "sitetracker__Project_Status__c":"Complete",
           "sitetracker__Project_Template__c":"New Station",
           "Construction_Budget_Code__c":"N/A",
           "GC_Budget_Code__c":"N/A",
           "sitetracker__Site__c":"a0p7Q000000YWUuQAO",
           "sitetracker__Project_Start_Date_A__c":"2015-01-21",
           "Start_of_construction_F__c":"1900-01-01",
           "sitetracker__ProjectTemplate__c":"a0h7Q000000c8RFQAY",
           "sitetracker__Project_Complete_A__c":"2015-11-27",
           "Grid_Connection_required__c":false,
           "Building_Permit_required__c":false,
           "GC_Budget_Value__c":0,
           "Legal_approval_validation_template_A__c":"1900-01-01",
           "Legal_approval_validation_template_F__c":"1900-01-01",
           "Place_substation_A__c":"1900-01-01",
           "Define_Business_case_F__c":"1900-01-01",
           "GPS_survey_F__c":"1900-01-01",
           "Sign_GC_contract_A__c":"2015-05-21",
           "Internal_Fastned_Approval_F__c":"1900-01-01",
           "Define_heads_of_terms_F__c":"1900-01-01",
           "Building_Permit_drawings_F__c":"1900-01-01",
           "Sign_energy_supply_contract_F__c":"1900-01-01",
           "Order_metering_F__c":"1900-01-01",
           "Negotiate_terms_with_landlord_F__c":"1900-01-01",
           "Approve_site_for_research_F__c":"1900-01-01",
           "Physical_evaluation_A__c":"1900-01-01",
           "Hand_in_final_Building_Permit_A__c":"1900-01-01",
           "Create_existing_situation_drawing_F__c":"1900-01-01",
           "Negotiate_location_design_A__c":"1900-01-01",
           "Make_Final_Execution_Drawings_F__c":"1900-01-01",
           "Create_existing_situation_drawing_A__c":"1900-01-01",
           "Building_Permit_drawings_A__c":"1900-01-01",
           "Define_Business_case_A__c":"1900-01-01",
           "Approve_GC_budget_F__c":"1900-01-01",
           "Receive_external_reports_F__c":"1900-01-01",
           "Sign_energy_supply_contract_A__c":"1900-01-01",
           "Order_metering_A__c":"1900-01-01",
           "Order_substation_F__c":"1900-01-01",
           "Pre_permit_application_process__c":false,
           "Concept_CAD_drawing_A__c":"1900-01-01",
           "Generate_drawings_for_GC_request_A__c":"1900-01-01",
           "Hand_in_final_Building_Permit_F__c":"1900-01-01",
           "Review_of_Execution_Drawings_F__c":"1900-01-01",
           "Negotiate_terms_with_landlord_A__c":"1900-01-01",
           "All_permits_for_construction_receive_A__c":"1900-01-01",
           "Make_Execution_Drawings_A__c":"1900-01-01",
           "Hand_in_pre_permit_application_F__c":"2017-04-20",
           "Approve_site_for_research_A__c":"1900-01-01",
           "Concept_CAD_drawing_F__c":"1900-01-01",
           "Make_Execution_Drawings_F__c":"1900-01-01",
           "Location_Agreement_signed_by_all_A__c":"2015-01-21",
           "Check_utilities_F__c":"1900-01-01",
           "Start_of_construction_A__c":"1900-01-01",
           "Prepare_contracts_F__c":"1900-01-01",
           "Negotiate_location_design_F__c":"1900-01-01",
           "Prepare_contracts_A__c":"1900-01-01",
           "Initial_capex_budget_F__c":"1900-01-01",
           "Define_heads_of_terms_A__c":"1900-01-01",
           "Amendments_required__c":false,
           "Economic_Evaluation_A__c":"1900-01-01",
           "Initial_capex_budget_A__c":"1900-01-01",
           "Order_substation_A__c":"1900-01-01",
           "Approve_GC_budget_A__c":"1900-01-01",
           "Receive_GC_contract_A__c":"1900-01-01",
           "Site_Visit_CM__c":false,
           "Energize_grid_connection_A__c":"1900-01-01",
           "Contract_drawing_A__c":"1900-01-01",
           "Initial_design_sketch_A__c":"1900-01-01",
           "Check_zoning_A__c":"1900-01-01",
           "Economic_Evaluation_F__c":"1900-01-01",
           "Contract_works_F__c":"1900-01-01",
           "All_reports_completed_A__c":"1900-01-01",
           "Approve_Construction_Budget_F__c":"1900-01-01",
           "Request_for_Quotations_for_works_A__c":"1900-01-01",
           "Sign_Heads_of_Terms_F__c":"2015-09-04",
           "Initial_design_sketch_F__c":"1900-01-01",
           "Receive_GC_contract_F__c":"1900-01-01",
           "All_reports_completed_F__c":"1900-01-01",
           "Opening_of_Site_A__c":"2015-11-27",
           "Contract_drawing_F__c":"1900-01-01",
           "Check_utilities_A__c":"1900-01-01",
           "Submit_amendments_to_Building_Permit_F__c":"2017-05-04",
           "Building_Permit_Approved_A__c":"2015-02-25",
           "Site_Visit_LD__c":false,
           "Approve_Construction_Budget_A__c":"1900-01-01",
           "Internal_Design_Approval_A__c":"1900-01-01",
           "Contract_signed_by_Fastned_A__c":"1900-01-01",
           "Request_GC_contract_A__c":"1900-01-01",
           "Review_of_Execution_Drawings_A__c":"1900-01-01",
           "Generate_drawings_for_GC_request_F__c":"1900-01-01",
           "All_permits_for_construction_receive_F__c":"1900-01-01",
           "Design_Approval_Substation_F__c":"1900-01-01",
           "GPS_survey_A__c":"1900-01-01",
           "Place_substation_F__c":"1900-01-01",
           "Internal_Design_Approval_F__c":"1900-01-01",
           "Contract_signed_by_Fastned_F__c":"1900-01-01",
           "Extended_procedure__c":false,
           "Internal_Fastned_Approval_A__c":"1900-01-01",
           "Receive_external_reports_A__c":"1900-01-01",
           "Request_GC_contract_F__c":"1900-01-01",
           "Check_zoning_F__c":"1900-01-01",
           "Contract_works_A__c":"1900-01-01",
           "Energize_grid_connection_F__c":"1900-01-01",
           "Make_Final_Execution_Drawings_A__c":"1900-01-01",
           "Physical_evaluation_F__c":"1900-01-01",
           "Design_Approval_Substation_A__c":"1900-01-01",
           "Contract_signed_by_all_A__c":"2017-01-30",
           "Request_for_Quotations_for_works_F__c":"1900-01-01",
           "Determine_BP_Scope_F__c":"1900-01-01",
           "Determine_BP_Scope_A__c":"1900-01-01",
           "Determine_scope_Execution_Drawing_F__c":"1900-01-01",
           "Determine_scope_Execution_Drawing_A__c":"1900-01-01",
           "Revise_BP_drawings_F__c":"1900-01-01",
           "Revise_BP_drawings_A__c":"1900-01-01",
           "Report_deviations_A__c":"1900-01-01",
           "Report_deviations_F__c":"1900-01-01",
           "Requested_Capacity__c":500,
           "Separate_Location_Agreement__c":true,
           "Signing_of_HoT_required__c":false,
           "Update_capex_budget_A__c":"1900-01-01",
           "Update_capex_budget_F__c":"1900-01-01",
           "Grid_Connection__c":"a2R7Q0000000q7XUAQ",
           "sitetracker__Site__r":{
              "Name":"Bospoort",
              "Id":"a0p7Q000000YWUuQAO"
           }
        },

And files that mentioned here and not attached

import { LightningElement, api, wire } from "lwc";
import { ShowToastEvent } from "lightning/platformShowToastEvent";
import { loadScript, loadStyle } from "lightning/platformResourceLoader";
import GANTT from "@salesforce/resourceUrl/bryntum_gantt";
import GanttToolbarMixin from "./lib/GanttToolbar";
import data from './data/launch-saas'
import getProjects from '@salesforce/apex/GanttChartApexHandler.getProjects';
import getGanttChartConfigurationsWrapper from '@salesforce/apex/GanttChartApexHandler.getGanttChartConfigurationsWrapper'
import { getObjectInfo } from 'lightning/uiObjectInfoApi';
import PHASE_EVENT_CONFIG_OBJECT from '@salesforce/schema/Phase_Event_Gantt_Chart__c';
import { NavigationMixin, CurrentPageReference } from 'lightning/navigation';

It will help a lot if you'll find our example for Salesforce (in examples/salesforce folder) and apply required changes to make possible using your data.

Thank you!

All the best,
Alex


Post by revill »

Hi Alex,
thank you for your tips. Here is the test case created from the Salesforce example, with the least changes possible.
I hope this will be enough to find the issue.

/* globals bryntum : true */
import { LightningElement } from "lwc";
import { ShowToastEvent } from "lightning/platformShowToastEvent";
import { loadScript, loadStyle } from "lightning/platformResourceLoader";
import GANTT from "@salesforce/resourceUrl/bryntum_gantt";
import GanttToolbarMixin from "./lib/GanttToolbar";
import data from './data/launch-saas'

export default class Gantt_component extends LightningElement {
    error;
    
projects = [ { "Id":"a0i7Q000000ctE3QAI", "Name":"P-000219", "sitetracker__Project_Start_Date_A__c":"2020-01-01", "Start_of_construction_A__c":"2023-02-01", "phases" : [{"Name":"P2", "startDate":"2020-03-03", "endDate":"2020-07-07"},{"Name":"P1", "startDate":"2022-01-01", "endDate":"2022-05-01"}], "events":[{"Name":"start","startDate":"2020-01-01", "endDate":"2020-01-02"},{"Name":"ev1","startDate":"2021-05-01", "endDate":"2021-05-02"}] }, { "Id":"a0i7Q000000ctE4QAI", "Name":"P-000220", "sitetracker__Project_Start_Date_A__c":"2020-01-01", "Start_of_construction_A__c":"2023-05-05", "phases" : [{"Name":"P1", "startDate":"2020-03-01", "endDate":"2020-06-01"},{"Name":"P2", "startDate":"2021-03-03", "endDate":"2021-10-04"}], "events":[{"Name":"ev1","startDate":"2023-01-01", "endDate":"2023-01-02"},{"Name":"start","startDate":"2020-01-01", "endDate":"2020-01-02"}] }, { "Id":"a0i7Q000000ctEhQAI", "Name":"P-000242", "sitetracker__Project_Start_Date_A__c":"2019-07-08", "Start_of_construction_A__c":"2023-08-01", "phases" : [{"Name":"P1", "startDate":"2021-01-01", "endDate":"2021-05-01"},{"Name":"P2", "startDate":"2020-03-03", "endDate":"2020-04-04"}], "events":[{"Name":"ev1","startDate":"2020-01-01", "endDate":"2020-01-02"},{"Name":"start","startDate":"2019-07-08", "endDate":"2019-07-09"}] } ]; renderedCallback() { if (this.bryntumInitialized) { return; } this.bryntumInitialized = true; Promise.all([ loadScript(this, GANTT + "/gantt.lwc.module.js"), loadStyle(this, GANTT + "/gantt.stockholm.css") ]) .then(() => { try { this.handleProjectLoad(); } catch (error) { console.log('error ', error); } }) .catch(error => { this.dispatchEvent( new ShowToastEvent({ title: "Error loading Bryntum Gantt", message: error, variant: "error" }) ); }); } createProjectRow(element, projectStartDate, projectEndDate, segments, earliestStartDate, idNumber) { let parsedDate = new Date(projectStartDate); let projectRow; let isoDate = parsedDate.toISOString().split('T')[0]; if (parsedDate.getDate() =='1' && parsedDate.getMonth() == '0' && parsedDate.getFullYear() == '1900') { projectRow = {"id" : idNumber, "startDate" : isoDate, "manuallyScheduled": true, "segments" : segments, "name" : element.Name, "endDate" : projectEndDate, "salesforceId" : element.Id}; } else { if (parsedDate < earliestStartDate) { earliestStartDate = parsedDate; } projectRow = {"id" : idNumber, "manuallyScheduled": true, "startDate" : String (projectStartDate), "projectEndDate" : String (projectEndDate), "segments" : segments, "name" : element.Name, "salesforceId" : element.Id}; } return projectRow; } createEventSegments (events,element, projectStartDate, projectEndDate, eventSegments) { if (!element) {return [];} for (const event of element.events) { let eventStartDate = event.startDate; if (eventStartDate != undefined && eventStartDate != null && (eventStartDate >= projectStartDate && eventStartDate < projectEndDate)) { let parsedDate = new Date(eventStartDate); if (parsedDate.getMonth() == '0' && parsedDate.getDate() == '1' && parsedDate.getFullYear() == '1900') { continue; } let newstartEventDate = new Date(eventStartDate); let endEventDate = new Date(eventStartDate); endEventDate.setDate(newstartEventDate.getDate() + 1); let startDateString = newstartEventDate.toISOString().split('T')[0]; let endDateString = endEventDate.toISOString().split('T')[0]; eventSegments.push({"name" : event.Name, "startDate" : String(startDateString), "endDate" : String(endDateString)}); } } } createPhaseSegments (phases, element, projectStartDate, projectEndDate, phaseSegments) { if (!element) {return [];} for ( const phase of element.phases) { let phaseStartDate = phase.startDate; let phaseEndDate = phase.endDate; if (((phaseEndDate != undefined && phaseEndDate != null) || (phaseStartDate != undefined && phaseStartDate != null)) && (phaseStartDate >= projectStartDate && phaseEndDate <= projectEndDate && phaseStartDate < projectEndDate && phaseEndDate > projectStartDate)) { let parsedDate = new Date(phaseStartDate); if (parsedDate.getMonth() == '0' && parsedDate.getDate() == '1' && parsedDate.getFullYear() == '1900') { continue; } phaseSegments.push({ "name" : phase.Name, "startDate" :phaseStartDate, "endDate" : phaseEndDate}); } } } handleProjectLoad() { let phases,events; let projectTasks = new Array; let idNumber = 1; let earliestStartDate = new Date(); for (const element of this.projects) { let projectStartDate = element.sitetracker__Project_Start_Date_A__c; let projectEndDate = element.Start_of_construction_A__c; if (projectEndDate != undefined && projectEndDate != null && projectStartDate != undefined && projectStartDate < projectEndDate) { let segments = []; this.createPhaseSegments(phases, element, projectStartDate, projectEndDate, segments); this.createEventSegments(events, element, projectStartDate, projectEndDate, segments); let sortedSegments = segments.sort(function(a,b){ return new Date(a.startDate) - new Date(b.startDate); }); let newstartEventDate = new Date(projectEndDate); let endEventDate = new Date(projectEndDate); newstartEventDate.setDate(endEventDate.getDate() -1); let startDateString = newstartEventDate.toISOString().split('T')[0]; let endDateString = endEventDate.toISOString().split('T')[0]; sortedSegments.push({"name" : 'Project End', "startDate" : String(startDateString), "endDate" : String(endDateString)}); let projectRow = this.createProjectRow(element, projectStartDate, projectEndDate, sortedSegments, earliestStartDate, idNumber); projectTasks.push(projectRow); idNumber++; } } console.log('tasks', projectTasks); this.createGantt(projectTasks); } createGantt(tasks) { const GanttToolbar = GanttToolbarMixin(bryntum.gantt.Toolbar); const project = new bryntum.gantt.ProjectModel({ calendar: data.project.calendar, startDate: data.project.startDate, tasksData: tasks, resourcesData: data.resources.rows, assignmentsData: data.assignments.rows, dependenciesData: data.dependencies.rows, calendarsData: data.calendars.rows }); const gantt = new bryntum.gantt.Gantt({ project, appendTo: this.template.querySelector(".container"), startDate: "2019-01-12", endDate: "2019-03-24", tbar: new GanttToolbar(), dependencyIdField: "sequenceNumber", columns: [ { type: "name", width: 250 }, { type: "startdate", field : 'startDate', format : 'YYYY-MM-DD'}, { type: "enddate", field : 'projectEndDate', format : 'YYYY-MM-DD'}, { type: "addnew" } ], subGridConfigs: { locked: { flex: 3 }, normal: { flex: 4 } }, columnLines: false, features: { rollups: { disabled: true }, baselines: { disabled: true }, progressLine: { disabled: true, statusDate: new Date(2019, 0, 25) }, filter: true, dependencyEdit: true, timeRanges: { showCurrentTimeLine: true }, labels: { left: { field: "name", editor: { type: "textfield" } } } }, tbar : [ { type : 'button', text : '<<', onClick : (event) => { const collapseEvent = event.source.up ('gantt'); collapseEvent.shiftPrevious(); } }, { type : 'button', text : '>>', onClick : (event) => { const collapseEvent = event.source.up ('gantt'); collapseEvent.shiftNext(); } }, { type : 'button', text : 'Zoom to fit', onClick : (event) => { const collapseEvent = event.source.up ('gantt'); collapseEvent.zoomToFit(); } }, { type : 'button', text : '+', onClick : (event) => { const collapseEvent = event.source.up ('gantt'); collapseEvent.zoomIn(); } },{ type : 'button', text : '-', onClick : (event) => { const collapseEvent = event.source.up ('gantt'); collapseEvent.zoomOut(); } } ] }); project.commitAsync().then(() => { // console.timeEnd("load data"); const stm = gantt.project.stm; stm.enable(); stm.autoRecord = true; // let's track scheduling conflicts happened project.on("schedulingconflict", context => { // show notification to user bryntum.gantt.Toast.show( "Scheduling conflict has happened ..recent changes were reverted" ); // as the conflict resolution approach let's simply cancel the changes context.continueWithResolutionResult( bryntum.gantt.EffectResolutionResult.Cancel ); }); }); } }

Thank you in advance!


Post by alex.l »

Thanks for the test case, I ran your code properly. But it's not clear what to do to reproduce the issue. I see no events on timeline after load. See the screenshot attached.

What are steps to reproduce, actual result and expected result?

Attachments
Screenshot 2023-01-11 at 16.51.25.png
Screenshot 2023-01-11 at 16.51.25.png (329.64 KiB) Viewed 376 times

All the best,
Alex


Post by revill »

Please, use the "fit to zoom" button so it should fit the screen to the project's timeline. Then each of them should have a few segments, but when we will zoom in using "+" button on the screen some of the segments are displayed in the whole width of the project, covering other segments. Then if we will zoom out, segments are again displayed properly.

Kind regards,
Revill


Post by alex.l »

Still nothing after "zoom to fit" clicked. Does it work well for you?

Attachments
Screenshot 2023-01-11 at 17.00.16.png
Screenshot 2023-01-11 at 17.00.16.png (411.25 KiB) Viewed 374 times

All the best,
Alex


Post by revill »

Yes, on my side it's working

Attachments
example.PNG
example.PNG (39.22 KiB) Viewed 373 times

Post by alex.l »

Could you please review the code once again and make sure you used same version? I copy-pasted your project and see nothing on the timeline. I also tried to find any obvious problems in the code, but looks like the problem in data.

Am I right you used latest released version of the Gantt?

Please make sure the data that you imported from './data/launch-saas' has not been changed on your side, or attach it to your reply.

All the best,
Alex


Post by revill »

Hi Alex,
I made another review and didn't found any issues or differences. I'm using last version bryntum gantt 5.2.7.
I tried also to create it once again, by removing all related changes from the org, then created new LWC component with the example code with steps from this instruction https://bryntum.com/products/gantt/docs/guide/Gantt/integration/salesforce/lwc (only difference is that I'm not using scratch org) and then replace the .js file with the code copied from this tread to be sure it's the same and it works for me, don't see anything which could be the issue.

Please, find in the attachment the code for the './data/launch-saas'

Best regards,
Revill

Attachments
launch-saas.js
(58.79 KiB) Downloaded 29 times

Post by alex.l »

I found the reason why I see no data.
In the method createProjectRow you collect all data together and create tasks. You set startDate for task, but don't set endDate or duration, so it won't be visible.
This line

projectRow = {"id" : idNumber, "manuallyScheduled": true, "startDate" : String (projectStartDate), "projectEndDate" : String (projectEndDate), "segments" : segments, "name" : element.Name, "salesforceId" : element.Id};

You also used manuallyScheduled flag, dates you used are in 2020-2023 period, but project's start date you passed from launch-sass is 2019-01-14.

Could you please review one more time segments start/end dates, fix start/end dates for tasks (i am not sure renaming projectEndDate to endDate will give me result that you expect to see, you should check it yourself) and check after that if you still see problems with segments scheduling.

All the best,
Alex


Post by revill »

Hi Alex,
Thanks for the tips. I have removed the startDate so it's not using anymore the startDate from the launch-sass. Also, I changed the projectEndDate to the endDate. Also, checked again te dates and all tasks and segments has starDate and endDate set. And still I have the same issue. Projects and segments are displayed properly for me, but there is a display problem when I'm zooming in, it didn't resolve the issues.

Here is the latest code:

/* globals bryntum : true */
import { LightningElement } from "lwc";
import { ShowToastEvent } from "lightning/platformShowToastEvent";
import { loadScript, loadStyle } from "lightning/platformResourceLoader";
import GANTT from "@salesforce/resourceUrl/bryntum_gantt";
import GanttToolbarMixin from "./lib/GanttToolbar";
import data from './data/launch-saas'

export default class Gantt_component extends LightningElement {
    error;
    
projects = [ { "Id":"a0i7Q000000ctE3QAI", "Name":"P-000219", "sitetracker__Project_Start_Date_A__c":"2020-01-01", "Start_of_construction_A__c":"2023-02-01", "phases" : [{"Name":"P2", "startDate":"2020-03-03", "endDate":"2020-07-07"},{"Name":"P1", "startDate":"2022-01-01", "endDate":"2022-05-01"}], "events":[{"Name":"start","startDate":"2020-01-01", "endDate":"2020-01-02"},{"Name":"ev1","startDate":"2021-05-01", "endDate":"2021-05-02"}] }, { "Id":"a0i7Q000000ctE4QAI", "Name":"P-000220", "sitetracker__Project_Start_Date_A__c":"2020-01-01", "Start_of_construction_A__c":"2023-05-05", "phases" : [{"Name":"P1", "startDate":"2020-03-01", "endDate":"2020-06-01"},{"Name":"P2", "startDate":"2021-03-03", "endDate":"2021-10-04"}], "events":[{"Name":"ev1","startDate":"2023-01-01", "endDate":"2023-01-02"},{"Name":"start","startDate":"2020-01-01", "endDate":"2020-01-02"}] }, { "Id":"a0i7Q000000ctEhQAI", "Name":"P-000242", "sitetracker__Project_Start_Date_A__c":"2019-07-08", "Start_of_construction_A__c":"2023-08-01", "phases" : [{"Name":"P1", "startDate":"2021-01-01", "endDate":"2021-05-01"},{"Name":"P2", "startDate":"2020-03-03", "endDate":"2020-04-04"}], "events":[{"Name":"ev1","startDate":"2020-01-01", "endDate":"2020-01-02"},{"Name":"start","startDate":"2019-07-08", "endDate":"2019-07-09"}] } ]; renderedCallback() { if (this.bryntumInitialized) { return; } this.bryntumInitialized = true; Promise.all([ loadScript(this, GANTT + "/gantt.lwc.module.js"), loadStyle(this, GANTT + "/gantt.stockholm.css") ]) .then(() => { try { this.handleProjectLoad(); } catch (error) { console.log('error ', error); } }) .catch(error => { this.dispatchEvent( new ShowToastEvent({ title: "Error loading Bryntum Gantt", message: error, variant: "error" }) ); }); } createProjectRow(element, projectStartDate, projectEndDate, segments, earliestStartDate, idNumber) { let parsedDate = new Date(projectStartDate); let projectRow; let isoDate = parsedDate.toISOString().split('T')[0]; console.log('parsed date ', parsedDate); projectRow = {"id" : idNumber, "manuallyScheduled" : true, "startDate" : String (projectStartDate), "endDate" : String (projectEndDate), "segments" : segments, "name" : element.Name, "salesforceId" : element.Id}; return projectRow; } createEventSegments (events,element, projectStartDate, projectEndDate, eventSegments) { if (!element) {return [];} for (const event of element.events) { let eventStartDate = event.startDate; if (eventStartDate != undefined && eventStartDate != null && (eventStartDate >= projectStartDate && eventStartDate < projectEndDate)) { let parsedDate = new Date(eventStartDate); if (parsedDate.getMonth() == '0' && parsedDate.getDate() == '1' && parsedDate.getFullYear() == '1900') { continue; } let newstartEventDate = new Date(eventStartDate); let endEventDate = new Date(eventStartDate); endEventDate.setDate(newstartEventDate.getDate() + 1); let startDateString = newstartEventDate.toISOString().split('T')[0]; let endDateString = endEventDate.toISOString().split('T')[0]; eventSegments.push({"name" : event.Name, "startDate" : String(startDateString), "endDate" : String(endDateString)}); } } } createPhaseSegments (phases, element, projectStartDate, projectEndDate, phaseSegments) { if (!element) {return [];} for ( const phase of element.phases) { let phaseStartDate = phase.startDate; let phaseEndDate = phase.endDate; if (((phaseEndDate != undefined && phaseEndDate != null) || (phaseStartDate != undefined && phaseStartDate != null)) && (phaseStartDate >= projectStartDate && phaseEndDate <= projectEndDate && phaseStartDate < projectEndDate && phaseEndDate > projectStartDate)) { let parsedDate = new Date(phaseStartDate); if (parsedDate.getMonth() == '0' && parsedDate.getDate() == '1' && parsedDate.getFullYear() == '1900') { continue; } phaseSegments.push({ "name" : phase.Name, "startDate" : phaseStartDate, "endDate" : phaseEndDate}); } } } handleProjectLoad() { let phases,events; let projectTasks = new Array; let idNumber = 1; let earliestStartDate = new Date(); for (const element of this.projects) { let projectStartDate = element.sitetracker__Project_Start_Date_A__c; let projectEndDate = element.Start_of_construction_A__c; if (projectEndDate != undefined && projectEndDate != null && projectStartDate != undefined && projectStartDate < projectEndDate) { let segments = []; this.createPhaseSegments(phases, element, projectStartDate, projectEndDate, segments); this.createEventSegments(events, element, projectStartDate, projectEndDate, segments); let sortedSegments = segments.sort(function(a,b){ return new Date(a.startDate) - new Date(b.startDate); }); let newstartEventDate = new Date(projectEndDate); let endEventDate = new Date(projectEndDate); newstartEventDate.setDate(endEventDate.getDate() -1); let startDateString = newstartEventDate.toISOString().split('T')[0]; let endDateString = endEventDate.toISOString().split('T')[0]; sortedSegments.push({"name" : 'Project End', "startDate" : String(startDateString), "endDate" : String(endDateString)}); let projectRow = this.createProjectRow(element, projectStartDate, projectEndDate, sortedSegments, earliestStartDate, idNumber); projectTasks.push(projectRow); idNumber++; } } console.log('tasks', projectTasks); this.createGantt(projectTasks); } createGantt(tasks) { const GanttToolbar = GanttToolbarMixin(bryntum.gantt.Toolbar); const project = new bryntum.gantt.ProjectModel({ calendar: { "calendar" : "general" }, // startDate: data.project.startDate, tasksData: tasks, calendarsData: data.calendars.rows }); const gantt = new bryntum.gantt.Gantt({ project, appendTo: this.template.querySelector(".container"), startDate: "2019-01-12", endDate: "2019-03-24", tbar: new GanttToolbar(), dependencyIdField: "sequenceNumber", columns: [ { type: "name", width: 250 }, { type: "startdate", field : 'startDate', format : 'YYYY-MM-DD'}, { type: "enddate", field : 'endDate', format : 'YYYY-MM-DD'}, { type: "addnew" } ], subGridConfigs: { locked: { flex: 3 }, normal: { flex: 4 } }, columnLines: false, features: { rollups: { disabled: true }, baselines: { disabled: true }, progressLine: { disabled: true, statusDate: new Date(2019, 0, 25) }, filter: true, dependencyEdit: true, timeRanges: { showCurrentTimeLine: true }, labels: { left: { field: "name", editor: { type: "textfield" } } } }, tbar : [ { type : 'button', text : '<<', onClick : (event) => { const collapseEvent = event.source.up ('gantt'); collapseEvent.shiftPrevious(); } }, { type : 'button', text : '>>', onClick : (event) => { const collapseEvent = event.source.up ('gantt'); collapseEvent.shiftNext(); } }, { type : 'button', text : 'Zoom to fit', onClick : (event) => { const collapseEvent = event.source.up ('gantt'); collapseEvent.zoomToFit(); } }, { type : 'button', text : '+', onClick : (event) => { const collapseEvent = event.source.up ('gantt'); collapseEvent.zoomIn(); } },{ type : 'button', text : '-', onClick : (event) => { const collapseEvent = event.source.up ('gantt'); collapseEvent.zoomOut(); } } ] }); project.commitAsync().then(() => { // console.timeEnd("load data"); const stm = gantt.project.stm; stm.enable(); stm.autoRecord = true; // let's track scheduling conflicts happened project.on("schedulingconflict", context => { // show notification to user bryntum.gantt.Toast.show( "Scheduling conflict has happened ..recent changes were reverted" ); // as the conflict resolution approach let's simply cancel the changes context.continueWithResolutionResult( bryntum.gantt.EffectResolutionResult.Cancel ); }); }); } }

Kind Regards


Post Reply