Weighted Average with Ag-grid


(4 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'm an "old" programmer who has been blogging for almost 20 years now. In 2017, I started Highline Solutions, a consulting company that helps with software architecture and full-stack development. I have two degrees from Carnegie Mellon University, one practical (Information and Decision Systems) and one not so much (Philosophy - thesis here). Pittsburgh, PA is my home where I live with my wife and 3 energetic boys.
We're hiring! Looking for a full-stack developer (React, NodeJS or Java, AWS) open to contract work. Fully remote. The model at Highline is a little different - we're more of a co-op than a traditional consultancy. Our goal is to reward the person doing the work, and keep everything else streamlined. If you're interested, hit me up at ben@highlinesolutions.io to find out more. Send along a resume, or better yet a TechRez!
I recently released a web app called TechRez, a "better resume for tech". The idea is that instead of sending out the same-old static PDF resume that's jam packed with buzz words and spans multiple pages, you can create a TechRez, which is modern, visual, and interactive. Try it out for free!
Got a Comment?
Comments (4)
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.
Charbs
September 25, 2019
Found this while searching for a way to access data in different rows in the total column. Tried the Comment version and it worked, until I tried to use the export and it broke the CsvCreator.
September 17, 2022
The two indispensable MMPs are Gelatinase A MMP- 2 and Gelatinase B MMP- 9, which could degrade the entire active forms of the extracellular matrix ECM collagen 8. chlamydia treatment doxycycline