Ben Northrop

Decisions and software development

Weighted Average with Ag-grid

August 8th 2018

One of the nice features of ag-grid (which is a kick-ass HTML 5 grid) is the ability to define an aggregate function for a given column - i.e. when grouping data, what calculation should you use for a given numeric column. Out of the box, there's support for a bunch of basic functions (sum, average, etc.), but one that's missing is a weighted average, which is extremely important in some domains (like finance).

A weighted average is defined as:

```  weighted average (colA weighted by colB) = SUM(colA * colB) / SUM(colB)
```

After a little poking around, I figured out the following solution within ag-grid:

``````
var gridOptions = {
...
groupRowAggNodes: groupRowAggNodes,
};

...

function groupRowAggNodes(nodes) {

let result = {
colA: 0,
colB: 0
};

let sumColB = 0;
let sumProduct = 0;
nodes.forEach(node => {
var data = node.group ? node.aggData : node.data;
sumColB += data.colB;
sumProduct += (data.colA * data.colB);
});

result.colB = sumColB;
result.colA = sumProduct / sumColB;

return result;
}
```
```

If your aggregation function is in terms of just that column, then `colDef.aggFunc` is fine, but if you need to "reach" into other columns in order to calculate, then the groupRowAggNodes() is what you want to use. You can find the entire solution on Plunker here. I believe that software development is fundamentally about making decisions, and so this is what I write about (mostly). I'm the owner of Highline Solutions and also the Principal Technical Consultant. I have two degrees from Carnegie Mellon University, most recently one in philosophy (thesis here). I live in Pittsburgh, PA with my wife and 3 energetic boys. Subscribe here or write me at ben dot northrop at gmail dot com.

Got a Comment? August 10, 2018
Yes you can do it that way. Another way to do it is use valueGetter to provide both values to the aggFunc.

colDef.valueGetter = function(params) {
return {
a: params.data.colA,
b: params.data.colB,
toString: function() {
return this.a;
}
}

the toString is so that the grid will render A in the cells.

the standard aggFunc will then get all the objects with both a and b.
Ben
January 12, 2019
Cool. Thanks for sharing that.