Ben Northrop


Decisions and software development


Weighted Average with Ag-grid


(1 comments)
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've been building software for about 20 years now, as a developer, tech lead, and architect. I have two degrees from Carnegie Mellon University, most recently one in philosophy (thesis here). I live in Pittsburgh, PA with my wife, 3 energetic boys, and dog. Subscribe here or write me at ben dot northrop at gmail dot com.

Got a Comment?


Sign up to hear about the next post!

If you liked this article and want to hear about the next one, enter your email below. I don't spam - you'll only receive an email when there's a new post (which is about once a month, tops). It's all low-key, straight from me.

Comments (1)

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.