트리 - 하위노드 계산
트리 자식노드의 연산된 값을 상위부모노드에 출력되도록 적용할 수 있습니다.
조회, 값 변경 시점에 재연산 된 값이 부모 노드에 반영될 수 있도록 시점마다 setValue() 로 값을 변경합니다.
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));
// 다시 연결해서 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));
}