Angular UI Grid - How to customize aggregate rows behavior
Asked Answered
G

2

8

When grouping, ng-grid creates group row(s) that look and behave differently to regular rows. In particular, group rows don't display regular columns, but display a single merged row as defined by the aggregateTemplate. What I'm attempting to do is to customize group rows to include aggregated column data. For example:

Columns:
NAME | VALUE

Data:
name1 | 5
name1 | 5
name2 | 1

Grid displayed when grouped by NAME:
- name1 | 10 (this is the first group row expanded)
-- name1 | 5 (these are the actual data rows)
-- name1 | 5 (these are the actual data rows)
- name2 | 1 (this is the second group row collapsed)

Notice that the group rows display both columns and their VALUE is equal to the sum of their children.
If you are familiar with ms excel pivot tables, that's exactly the grouping type functionality I'm trying to emulate.

A similar question here on stack overflow (How to set aggregation with grouping in ng-grid) shows an example of how to do the child aggregation calculations, but I'm stuck on how to get ng-grid to display the output like regular rows with separate columns. Looking at the ng-grid code it's not looking like an easy task. Anyone have some experience with this?
Thanks!

Guelders answered 26/5, 2013 at 19:57 Comment(0)
K
3

It is an old questiotn but i had the exactly same problem, so i give my solution here:

I have copied the cell template in aggregateTemplate, then adapted it to display the arrow, and called a function to compute aggregate value (i am just copying the value of the first row for instance, summing, min or max on values could be parameterized in column definition)

    groupTemplate=
        '<div ng-style="{\'top\':row.offsetTop+\'px\'}" class="{{row.aggClass()}}"></div>'
        +'<div ng-click="row.toggleExpand()" ng-style="{ \'cursor\': row.cursor ,\'top\':row.offsetTop+\'px\'}" ng-repeat="col in renderedColumns" ng-class="col.colIndex()" class="ngCell ngCellGroup {{col.cellClass}}">'
                +'<div class="ngVerticalBar" ng-style="{height: rowHeight}" ng-class="{ ngVerticalBarVisible: !$last }">&nbsp;</div>'
                +'<div >{{aggFc(row,col) }}</div>'

        +'</div>';

    $scope.aggFc=function(rowAgg,col){
        var row=rowAgg.children[0];
        if(row.entity[col.field] && col.cellFilter){
            console.log("'"+row.entity[col.field]+"'  |" +col.cellFilter);
            return $scope.$eval("'"+row.entity[col.field]+"'  |" +col.cellFilter);
        }
        return row.entity[col.field]
    };

     $scope.yourGrid =
            {
                data: '...',
                enableCellSelection: false,
                enableRowSelection: true,
                aggregateTemplate:groupTemplate,
                ...

I think this solution can be used by adapting the "$scope.aggFc" function inspired by the link you gave (How to set aggregation with grouping in ng-grid)

Katzen answered 21/11, 2013 at 11:17 Comment(0)
C
0

to get sums, you can just change the aggFC to something like:

$scope.get_total= (col,row) ->
    # used by the footer template to access column totals.
    return $scope.totals[col.field] if _.isUndefined(row)
    _.reduce(row.children, ((sum, child) -> sum + child.entity[col.field]), 0)

(coffee script and underscore assumed) Note that I use the same function for both footer (total for the whole table) and aggrows. In the footer case, no row is passed in, so the pre-computed totals are returned. if a row is passed, it's assumed to be an aggregate, and its children are summed for the column.

Conductor answered 22/11, 2013 at 0:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.