RealGrid2 Guide
Tree
Tree node move

Tree - Calculate subnodes

The calculated value of the tree child node can be applied to be output to the upper parent node.

Change the value with setValue() at each time so that the recalculated value can be reflected in the parent node at the time of inquiry or value change.

const sumFields = ["calc1", "calc2"];
const testNumFooterCallback = (tree, column, footerIndex, footer, value) => {
    const ds = tree.getDataSource();
    const rows = ds.getChildren(-1);
    let sum = 0;
    for (let row of rows) {
        sum += (ds.getValue(row, column.name) || 0)
    }
 
    return sum;
}
 
const calcLeaf = (dataProvider, rows) => {
    const innerCalc = (dataProvider, rows) => {
        const leafSum = {}
        for (let row of rows) {
            if (dataProvider.getChildCount(row) > 0) {
                const childSum = innerCalc(dataProvider, dataProvider.getChildren(row));
                for (let key of Object.keys(childSum)) {
                    if (childSum[key] > 0) {
                        dataProvider.setValue(row, key, childSum[key]);
                        leafSum[key] = (leafSum[key] || 0) + childSum[key]
                    }
                }
            } else {
                // softDeleting  hideDeletedRows값에 따라 조정 필요.
                if (!(dataProvider.getRowState(row) === "deleted" || dataProvider.getRowState(row) === "createdAndDeleted")) {
                    for (let key of sumFields) {
                        leafSum[key] = (leafSum[key] || 0) + (dataProvider.getValue(row, key) || 0)
                    }
                }
            }
        }
        return leafSum;
    }
    const checkStates = dataProvider.checkStates;
    dataProvider.checkStates = false;
    innerCalc(dataProvider, rows);
    dataProvider.checkStates = checkStates;
}
 
treeView.onDataLoadComplated = (tree) => {
    const ds = tree.getDataSource();
    calcLeaf(ds, ds.getChildren(-1));
    // Reconnect to refresh.
    for(var i = 0; i < sumFields.length; i++){
        tree.columnByName(sumFields[i]).footer.valueCallback = testNumFooterCallback;
 
        tree.columnByName(sumFields[i]).styleCallback = (tree, cell) => {
            const dataRowId = cell.index.dataRow;
            return {
                editable : (tree.getDataSource()).getChildCount(dataRowId) <= 0,
                styleName: "right-column"
            }
        }
    }
}
 
treeProvider.onRowUpdated =(ds, row) => {
    const ancestors = ds.getAncestors(row);
    calcLeaf(ds, [ancestors[ancestors.length-1]]);
}
 
// insert remove
treeProvider.onRowCountChanged = (ds) => {
    calcLeaf(ds, ds.getChildren(-1));
}