Our state of the art Gantt chart


Post by Nualis »

Hi,

Just started the Gantt Advanced Vue demo project. I trying to add a custom 'costs' column that extends the regular column. How do I add the behaviour that the column will do a summary on the child nodes like the duration column? Is there any example code for this for this rendering?

Post by sergey.maltsev »

Hi!

We are going to make a demo which shows how to create column which calculates sum for child values.
This the ticket for this.
https://app.assembla.com/spaces/bryntum/tickets/9211-add-new-demo-showing-how-add-a-custom-new-column-summing-values/details#

Post by Nualis »

Hi Sergey,

The ticket is now set to resolved. Can you tell me where can I find the example?

Post by sergey.maltsev »

Hi!
It will be in next release and already available in nighlty build.

You could check this code.
import { Gantt, ProjectModel, TaskModel, RandomGenerator } from '../../build/gantt.module.js';
import shared from '../_shared/shared.module.js';

class MyTaskModel extends TaskModel {
    static get fields() {
        return [
            { name : 'cost', type : 'number' }
        ];
    }
}

const
    project = new ProjectModel({
        taskModelClass : MyTaskModel,
        transport      : {
            load : {
                url : '../_datasets/launch-saas.json'
            }
        }
    }),

    gantt = new Gantt({
        appendTo : 'container',
        project  : project,
        columns  : [
            { type : 'name', field : 'name', width : 250 },
            { type : 'startdate' },
            { type : 'duration' },
            {
                type       : 'number',
                text       : 'Cost<br><span style="font-size:0.8em">(aggregated)</span>',
                align      : 'right',
                field      : 'cost',
                width      : 100,
                htmlEncode : false,
                renderer   : ({ record, value }) => record.isLeaf ? `$${value}` : `<b>$${value}</b>`
            }
        ],
        features : {
            taskEdit : {
                editorConfig : {
                    height     : '37em',
                    extraItems : {
                        generaltab : [
                            {
                                html    : '',
                                ref     : 'costGroup',
                                dataset : {
                                    text : 'Cost'
                                },
                                cls  : 'b-divider',
                                flex : '1 0 100%'
                            },
                            {
                                type  : 'number',
                                ref   : 'costField',
                                name  : 'cost',
                                label : 'Cost',
                                flex  : '.5 0',
                                cls   : 'b-inline'
                            }
                        ]
                    }
                }
            }
        },
        listeners : {
            // Disable Cost editing for parent tasks
            beforeCellEditStart : ({ editorContext }) => editorContext && (editorContext.column.field !== 'cost' || editorContext.record.isLeaf),
            beforeTaskEdit      : ({ taskRecord }) => {
                gantt.taskEdit.editor.widgetMap.costField.disabled = !taskRecord.isLeaf;
            }
        }
    });

project.load().then(() => {
    const rndGen = new RandomGenerator();
    // Set random cost for each child task
    gantt.taskStore.traverse(task => {
        task.cost = task.isLeaf ? rndGen.nextRandom(100) : 0;
    });
});

// Listen to update events on taskStore to calculate sum for customField
project.taskStore.on('update', ({ record, changes }) => {
    const parent = record.parent;

    // Sum parent's children values when record's field is changed and record has parent node
    if (changes.cost && parent) {
        // Children for parent node or empty array for record without children
        const children = parent && parent.children || [];
        parent.cost    = children.reduce((a, v) => {
            // If record has no field then we use 0 value
            return a + parseInt(v.cost || 0);
        },
        // Initial value is 0
        0);
    }
});
 

Post by Nualis »

Thank you!! We've added the column based on your example.

Post by Nualis »

Can you also give an example on how to refesh the costs field when a user deletes a row or multiple rows from the Gantt?

Post by sergey.maltsev »

Hi!

You could subscribe to store change event and run recalculation.
More info can be found here.
https://www.bryntum.com/docs/grid/#Common/data/Store#event-change

Post Reply