TransWikia.com

Error building Gantt Chart in LWC

Salesforce Asked on December 17, 2021

I was able to get a working test chart using ChartJS but I’m having trouble with the Frappe Gantt library.

Right now it’s throwing an error in the catch, but I think the error is null as I’m getting

Cannot read property ‘message’ of undefined

If I force it to call Initializechartjs(), I then get

Gantt is not defined

I can see all 4 resources loading –

resources

Here is my code

chart.html

<template>
    <lightning-card title="Gantt">
        <svg class="gantt" width="400" height="450" lwc:dom="manual"></svg>
    </lightning-card>
</template>

chart.js

import { LightningElement,api } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import { loadScript, loadStyle } from 'lightning/platformResourceLoader';
import momentJS from '@salesforce/resourceUrl/momentJS';
import snapSVG from '@salesforce/resourceUrl/snapSVG';
import frappeGanttMin from '@salesforce/resourceUrl/frappeGanttMin';
import frappeGanttStyle from '@salesforce/resourceUrl/frappeGanttStyle';


 export default class Chartcmp extends LightningElement {
  @api chartjsInitialized = false;
   @api recordId;
   renderedCallback() {
        if (this.chartjsInitialized) {
          return;
         }
        this.chartjsInitialized = true;
        console.log('chart loading');
        Promise.all([
              loadScript(this, momentJS),
              loadScript(this, snapSVG),
              loadScript(this, frappeGanttMin),
              loadStyle(this, frappeGanttStyle)
        ])
    .then(() => {
        this.Initializechartjs();
    })
    .catch(error => {
        this.dispatchEvent(
            new ShowToastEvent({
                title: 'Error loading chart',
                message: error.message,
                variant: 'error'
            })
        );
    });
   }

  Initializechartjs() {
    console.log("loaded");
    //Get the context of the canvas element we want to select
    var chartClass = this.template.querySelector(".gantt");
    var gantt = new Gantt(chartClass ,{
        tasks: [
            {
                id: 'Task 1',
                name: 'Redesign website',
                start: '2016-12-28',
                end: '2016-12-31',
            },
            {
                id: 'Task 2',
                name: 'Second Task',
                start: '2016-12-29',
                end: '2016-12-30',
            }
        ]
    });

    }

}

3 Answers

If anyone still needs Frappe Gantt to work with LWC's, I have a modified version that works, wasn't able to get SnapSVG to load, but all other imports do: https://github.com/damianoda96/Frappe-Gantt-LWC

Answered by ddamiano on December 17, 2021

The loadScript, loadStyle don`t propagate the error up (they manually print it out as warning on console) which means in this case you are getting an undefined error object on which are trying to access the message property => which leads to the "Cannot read property 'message' of undefined" failure

Seems to be thrown by the snapSVG lib which is not running in lockerservice. the gant lib (while not throwing an error) will most likely not work due to lockerservice without modification. It assigns its functionality to a global scoped variable - which is not accessible. So you would need to manually modify it and assign it to the window object. (Which of course does not automatically mean its working - 3rd party always are trial and error ....)

Edit: First Glance I guess if you dont want to (potentially) rewrite much in the lib you can forget about it. The constructor expects a dom selector or svg element. If you pass a dom selector it will query it via document.queryselector which will not work in LWC. If you pass the svg element itself it will try to create wrapper elements and access the parent element - but in order for appendChild to work it requires the lwc:dom=manual directive which requires a empty parent element.. which means you could not pass a svg element. Manually creating the svg too in your cmp could work but i don`t know what other traps will wait in the lib.. so i guess you maybe want to search for alternative librarys

Answered by Renji-xD on December 17, 2021

You shouldn't fetch elements by ID in lwc, as per the documentation:

Don’t use ID selectors with querySelector. The IDs that you define in HTML templates may be transformed into globally unique values when the template is rendered. If you use an ID selector in JavaScript, it won’t match the transformed ID.

Also, it is very likely that frappeGanttMin is not supported (Locker Service)

instead of using frappeGanttMin , why not use a d3 Gant chart?

You can find some supported libraries in the following posts:

Answered by glls on December 17, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP