{
    "componentChunkName": "component---src-templates-doc-page-jsx",
    "path": "/react-data-grid/aggregation-custom-functions/",
    "result": {"data":{"markdownRemark":{"htmlAst":{"type":"element","tagName":"div","properties":{},"children":[{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This section covers how custom aggregation functions can be supplied and used in the grid."}]},{"type":"element","tagName":"h2","properties":{"id":"directly-supplied-functions","style":"position:relative;"},"children":[{"type":"element","tagName":"a","properties":{"href":"#directly-supplied-functions","ariaLabel":"directly supplied functions permalink","className":["anchor","before"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","dataPrefix":"fas","dataIcon":"link","className":["svg-inline--fa","fa-link"],"role":"img","xmlns":"http://www.w3.org/2000/svg","viewBox":"0 0 512 512"},"children":[{"type":"element","tagName":"path","properties":{"fill":"currentColor","d":"M326.612 185.391c59.747 59.809 58.927 155.698.36 214.59-.11.12-.24.25-.36.37l-67.2 67.2c-59.27 59.27-155.699 59.262-214.96 0-59.27-59.26-59.27-155.7 0-214.96l37.106-37.106c9.84-9.84 26.786-3.3 27.294 10.606.648 17.722 3.826 35.527 9.69 52.721 1.986 5.822.567 12.262-3.783 16.612l-13.087 13.087c-28.026 28.026-28.905 73.66-1.155 101.96 28.024 28.579 74.086 28.749 102.325.51l67.2-67.19c28.191-28.191 28.073-73.757 0-101.83-3.701-3.694-7.429-6.564-10.341-8.569a16.037 16.037 0 0 1-6.947-12.606c-.396-10.567 3.348-21.456 11.698-29.806l21.054-21.055c5.521-5.521 14.182-6.199 20.584-1.731a152.482 152.482 0 0 1 20.522 17.197zM467.547 44.449c-59.261-59.262-155.69-59.27-214.96 0l-67.2 67.2c-.12.12-.25.25-.36.37-58.566 58.892-59.387 154.781.36 214.59a152.454 152.454 0 0 0 20.521 17.196c6.402 4.468 15.064 3.789 20.584-1.731l21.054-21.055c8.35-8.35 12.094-19.239 11.698-29.806a16.037 16.037 0 0 0-6.947-12.606c-2.912-2.005-6.64-4.875-10.341-8.569-28.073-28.073-28.191-73.639 0-101.83l67.2-67.19c28.239-28.239 74.3-28.069 102.325.51 27.75 28.3 26.872 73.934-1.155 101.96l-13.087 13.087c-4.35 4.35-5.769 10.79-3.783 16.612 5.864 17.194 9.042 34.999 9.69 52.721.509 13.906 17.454 20.446 27.294 10.606l37.106-37.106c59.271-59.259 59.271-155.699.001-214.959z"},"children":[]}]}]},{"type":"text","value":"Directly Supplied Functions"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Custom aggregation functions can be supplied directly to "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"colDef.aggFunc"}]},{"type":"text","value":" as shown below: "}]},{"type":"element","tagName":"snippet","properties":{},"children":[{"type":"text","value":"\nconst gridOptions = {\n    columnDefs: [\n        {\n            field: 'total',\n            aggFunc: params => {\n                let total = 0;\n                params.values.forEach(value => total += value);\n                return total;\n            }\n        }\n    ]\n}\n"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"As shown above, a custom agg function is supplied directly to the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"aggFunc"}]},{"type":"text","value":" property. The custom function uses the\nprovided "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"values"}]},{"type":"text","value":" to perform the custom aggregation. See "},{"type":"element","tagName":"a","properties":{"href":"/archive/28.0.0/aggregation/#api-reference"},"children":[{"type":"text","value":"Aggregation API Reference"}]},{"type":"text","value":" to\nlearn more about the supplied "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"params"}]},{"type":"text","value":"."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This is the simplest way to supply custom functions, however it has limitations compared with\n"},{"type":"element","tagName":"a","properties":{"href":"/archive/28.0.0/aggregation-custom-functions/#registering-custom-functions"},"children":[{"type":"text","value":"Registering Custom Functions"}]},{"type":"text","value":"."}]},{"type":"element","tagName":"div","properties":{"className":["custom-block","note"]},"children":[{"type":"element","tagName":"div","properties":{"className":["custom-block-body"]},"children":[{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Direct Functions will not appear in the "},{"type":"element","tagName":"a","properties":{"href":"/archive/28.0.0/tool-panel-columns/"},"children":[{"type":"text","value":"Columns Tool Panel"}]},{"type":"text","value":" or work when "},{"type":"element","tagName":"a","properties":{"href":"/archive/28.0.0/column-state/#save-and-apply"},"children":[{"type":"text","value":"Saving and Applying Column State"}]},{"type":"text","value":"."}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The example below uses the direct "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"aggFunc"}]},{"type":"text","value":" approach shown in the above snippet. Note the following:"}]},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Rows are grouped by the "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Country"}]},{"type":"text","value":" and "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Year"}]},{"type":"text","value":" columns by enabling the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"rowGroup"}]},{"type":"text","value":" column definition property."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"The "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Gold"}]},{"type":"text","value":", "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Silver"}]},{"type":"text","value":" and "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Bronze"}]},{"type":"text","value":" value columns have different agg functions applied via "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"colDef.aggFunc"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"func(Total)"}]},{"type":"text","value":" is displayed in the column header by default as it's a direct function."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"agg(Total)"}]},{"type":"text","value":" appears in the Columns Tool Panel, but it's omitted from the drop-down list as it's not registered with the grid.   "}]},{"type":"text","value":"\n"}]},{"type":"element","tagName":"div","properties":{},"children":[{"type":"element","tagName":"grid-example","properties":{"title":"Directly Supplied Aggregation Functions","name":"direct-functions","type":"generated","options":"{ \"enterprise\": true, \"exampleHeight\": 540, \"modules\": [\"clientside\", \"rowgrouping\", \"menu\", \"columnpanel\", \"filterpanel\", \"setfilter\"] }"},"children":[]}]},{"type":"element","tagName":"h2","properties":{"id":"registering-custom-functions","style":"position:relative;"},"children":[{"type":"element","tagName":"a","properties":{"href":"#registering-custom-functions","ariaLabel":"registering custom functions permalink","className":["anchor","before"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","dataPrefix":"fas","dataIcon":"link","className":["svg-inline--fa","fa-link"],"role":"img","xmlns":"http://www.w3.org/2000/svg","viewBox":"0 0 512 512"},"children":[{"type":"element","tagName":"path","properties":{"fill":"currentColor","d":"M326.612 185.391c59.747 59.809 58.927 155.698.36 214.59-.11.12-.24.25-.36.37l-67.2 67.2c-59.27 59.27-155.699 59.262-214.96 0-59.27-59.26-59.27-155.7 0-214.96l37.106-37.106c9.84-9.84 26.786-3.3 27.294 10.606.648 17.722 3.826 35.527 9.69 52.721 1.986 5.822.567 12.262-3.783 16.612l-13.087 13.087c-28.026 28.026-28.905 73.66-1.155 101.96 28.024 28.579 74.086 28.749 102.325.51l67.2-67.19c28.191-28.191 28.073-73.757 0-101.83-3.701-3.694-7.429-6.564-10.341-8.569a16.037 16.037 0 0 1-6.947-12.606c-.396-10.567 3.348-21.456 11.698-29.806l21.054-21.055c5.521-5.521 14.182-6.199 20.584-1.731a152.482 152.482 0 0 1 20.522 17.197zM467.547 44.449c-59.261-59.262-155.69-59.27-214.96 0l-67.2 67.2c-.12.12-.25.25-.36.37-58.566 58.892-59.387 154.781.36 214.59a152.454 152.454 0 0 0 20.521 17.196c6.402 4.468 15.064 3.789 20.584-1.731l21.054-21.055c8.35-8.35 12.094-19.239 11.698-29.806a16.037 16.037 0 0 0-6.947-12.606c-2.912-2.005-6.64-4.875-10.341-8.569-28.073-28.073-28.191-73.639 0-101.83l67.2-67.19c28.239-28.239 74.3-28.069 102.325.51 27.75 28.3 26.872 73.934-1.155 101.96l-13.087 13.087c-4.35 4.35-5.769 10.79-3.783 16.612 5.864 17.194 9.042 34.999 9.69 52.721.509 13.906 17.454 20.446 27.294 10.606l37.106-37.106c59.271-59.259 59.271-155.699.001-214.959z"},"children":[]}]}]},{"type":"text","value":"Registering Custom Functions"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Custom functions that are registered with the grid can be referenced by name in column definitions and will\nappear in the "},{"type":"element","tagName":"a","properties":{"href":"/archive/28.0.0/tool-panel-columns/"},"children":[{"type":"text","value":"Columns Tool Panel"}]},{"type":"text","value":" just like any "},{"type":"element","tagName":"a","properties":{"href":"/archive/28.0.0/aggregation/#enabling-aggregation"},"children":[{"type":"text","value":"Built-In Function"}]},{"type":"text","value":",\nand is done using the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"aggFuncs"}]},{"type":"text","value":" grid option:"}]},{"type":"element","tagName":"div","properties":{},"children":[{"type":"element","tagName":"api-documentation","properties":{"source":"grid-options/properties.json","section":"rowPivoting","names":"[\"aggFuncs\"]"},"children":[]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The following snippet shows how to register custom functions using the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"aggFuncs"}]},{"type":"text","value":" grid option:"}]},{"type":"element","tagName":"snippet","properties":{},"children":[{"type":"text","value":"\nconst gridOptions = {\n    columnDefs: [\n        { field: 'sales', aggFunc: 'mySum' },\n    ],\n    aggFuncs: {\n        'mySum': params => {\n            let sum = 0;\n            params.values.forEach(value => sum += value);\n            return sum;\n        }\n    },\n}\n"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"As shown above, a custom function is registered with in the grid with the name 'mySum' and is referenced by name in\nthe column definition using the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"aggFunc"}]},{"type":"text","value":" property."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Note that custom aggregation functions can also be registered using "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"gridApi.addAggFunc('mySum', mySumFunc)"}]},{"type":"text","value":"."}]},{"type":"element","tagName":"div","properties":{},"children":[{"type":"element","tagName":"api-documentation","properties":{"source":"grid-api/api.json","section":"rowPivoting","names":"[\"addAggFunc\"]"},"children":[]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The example below uses the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"aggFuncs"}]},{"type":"text","value":" approach shown in the snippet above. Note the following:"}]},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Rows are grouped by the "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Country"}]},{"type":"text","value":" and "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Year"}]},{"type":"text","value":" columns by enabling the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"rowGroup"}]},{"type":"text","value":" column definition property."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"The "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Gold"}]},{"type":"text","value":", "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Silver"}]},{"type":"text","value":" and "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Bronze"}]},{"type":"text","value":" value columns have different agg functions applied via "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"colDef.aggFunc"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"mySum(Total)"}]},{"type":"text","value":" is displayed in the column header by default as it uses the registered function name."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"mySum(Total)"}]},{"type":"text","value":" appears in the Columns Tool Panel and appears in the drop-down list just like a built-in function."}]},{"type":"text","value":"\n"}]},{"type":"element","tagName":"div","properties":{},"children":[{"type":"element","tagName":"grid-example","properties":{"title":"Registering Custom Aggregation Functions","name":"registered-function","type":"generated","options":"{ \"enterprise\": true, \"exampleHeight\": 540, \"modules\": [\"clientside\", \"rowgrouping\", \"menu\", \"columnpanel\", \"filterpanel\", \"setfilter\"] }"},"children":[]}]},{"type":"element","tagName":"h2","properties":{"id":"custom-aggregation-functions","style":"position:relative;"},"children":[{"type":"element","tagName":"a","properties":{"href":"#custom-aggregation-functions","ariaLabel":"custom aggregation functions permalink","className":["anchor","before"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","dataPrefix":"fas","dataIcon":"link","className":["svg-inline--fa","fa-link"],"role":"img","xmlns":"http://www.w3.org/2000/svg","viewBox":"0 0 512 512"},"children":[{"type":"element","tagName":"path","properties":{"fill":"currentColor","d":"M326.612 185.391c59.747 59.809 58.927 155.698.36 214.59-.11.12-.24.25-.36.37l-67.2 67.2c-59.27 59.27-155.699 59.262-214.96 0-59.27-59.26-59.27-155.7 0-214.96l37.106-37.106c9.84-9.84 26.786-3.3 27.294 10.606.648 17.722 3.826 35.527 9.69 52.721 1.986 5.822.567 12.262-3.783 16.612l-13.087 13.087c-28.026 28.026-28.905 73.66-1.155 101.96 28.024 28.579 74.086 28.749 102.325.51l67.2-67.19c28.191-28.191 28.073-73.757 0-101.83-3.701-3.694-7.429-6.564-10.341-8.569a16.037 16.037 0 0 1-6.947-12.606c-.396-10.567 3.348-21.456 11.698-29.806l21.054-21.055c5.521-5.521 14.182-6.199 20.584-1.731a152.482 152.482 0 0 1 20.522 17.197zM467.547 44.449c-59.261-59.262-155.69-59.27-214.96 0l-67.2 67.2c-.12.12-.25.25-.36.37-58.566 58.892-59.387 154.781.36 214.59a152.454 152.454 0 0 0 20.521 17.196c6.402 4.468 15.064 3.789 20.584-1.731l21.054-21.055c8.35-8.35 12.094-19.239 11.698-29.806a16.037 16.037 0 0 0-6.947-12.606c-2.912-2.005-6.64-4.875-10.341-8.569-28.073-28.073-28.191-73.639 0-101.83l67.2-67.19c28.239-28.239 74.3-28.069 102.325.51 27.75 28.3 26.872 73.934-1.155 101.96l-13.087 13.087c-4.35 4.35-5.769 10.79-3.783 16.612 5.864 17.194 9.042 34.999 9.69 52.721.509 13.906 17.454 20.446 27.294 10.606l37.106-37.106c59.271-59.259 59.271-155.699.001-214.959z"},"children":[]}]}]},{"type":"text","value":"Custom Aggregation Functions"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"It is possible to add your own custom aggregation to the grid. Custom aggregation functions can be applied directly to\nthe column or registered to the grid and reference by name (similar to grid provided functions)."}]},{"type":"element","tagName":"div","properties":{},"children":[{"type":"element","tagName":"api-documentation","properties":{"source":"grid-options/properties.json","section":"rowPivoting","names":"[\"aggFuncs\"]"},"children":[]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"A custom aggregation function takes values to aggregate and aggregates them."}]},{"type":"element","tagName":"div","properties":{"className":["custom-block","note"]},"children":[{"type":"element","tagName":"div","properties":{"className":["custom-block-body"]},"children":[{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Javascript doesn't always represent decimal numbers correctly (e.g "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"0.2 + 0.1 = 0.30000000000000004"}]},{"type":"text","value":"). For this\nreason, if your aggregations rely on decimal values, it's better to add logic to enforce the amount of decimal\nnumbers that will be displayed in the cell (see the Rounded Average on Age Column in the example below)."}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The next example shows many custom aggregation functions configured in a variety of ways and demonstrating different things aggregation functions can do."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The following can be noted from the example:"}]},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Min/Max on Age Column"}]},{"type":"text","value":": The function creates an aggregation over age giving a min and a max age. The function knows whether it is working with leaf nodes (original row data items) or aggregated nodes (ie groups) by checking the type of the value. If the value is a number, it's a row data item, otherwise it's a group. This is because the result of the aggregation has two values based on one input value. "},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":" The min/max function is then set by placing the function directly as the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"colDef.aggFunc"}]},{"type":"text","value":".\n"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"element","tagName":"br","properties":{},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Average on Age Column"}]},{"type":"text","value":": The age columns is aggregated a second time with a custom average function. The average function also needs to know if it is working with leaf nodes or group nodes, as if it's group nodes then the average is weighted. The grid also provides an average function that works in the same way, so there is no value in providing your own average function like this, it is done in this example for demonstration purposes. "},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":" The average function is also set by placing the function directly as the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"colDef.aggFunc"}]},{"type":"text","value":".\n"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"element","tagName":"br","properties":{},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Rounded Average on Age Column"}]},{"type":"text","value":": This is the same as "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"Average on Age Column"}]},{"type":"text","value":" but forcing the values to display a maximum of\ntwo decimal numbers.\n"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"element","tagName":"br","properties":{},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Sum on Gold"}]},{"type":"text","value":": The gold column gets a custom "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"sum"}]},{"type":"text","value":" aggregated function. The new sum function doesn't do anything different to the built in sum function, however it serves as a demonstration on how you can override. Maybe you want to provide a sum function that uses for example the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"math.js"}]},{"type":"text","value":" library."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":" The sum function is set using a "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"gridOptions"}]},{"type":"text","value":" property.\n"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"element","tagName":"br","properties":{},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"'123' on Silver"}]},{"type":"text","value":": The '123' function ignores the inputs and always returns the value 123. Because it is registered as an aggregation function, it can be reference by name in the column definitions. Having a function return the same thing isn't very useful, however for the example it demonstrates easily where in the grid the function was used. "},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":" The '123' function, like 'sum', is set using a "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"gridOptions"}]},{"type":"text","value":" property.\n"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"element","tagName":"br","properties":{},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"'xyz' on Bronze"}]},{"type":"text","value":": The 'xyz' function is another function with much use, however it demonstrates you can return anythin from an aggregation function - as long as your aggregation function can handle the result (if you have groups inside groups) and as long as your cell renderer can render the result (if using "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"cellRenderer"}]},{"type":"text","value":"). "},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":" The 'xyz' function is set using the API. Note that we also set 'xyz' in the grid options as otherwise\nthe grid would complain 'Function not found' as it tries to use the function before it is set via the API."}]},{"type":"text","value":"\n"}]},{"type":"element","tagName":"div","properties":{},"children":[{"type":"element","tagName":"grid-example","properties":{"title":"Custom Aggregation Functions","name":"custom-agg-functions","type":"generated","options":"{ \"enterprise\": true, \"modules\": [\"clientside\", \"rowgrouping\", \"menu\", \"columnpanel\", \"filterpanel\", \"setfilter\"] }"},"children":[]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Note that custom aggregations will get called for the top level rows to calculate a 'Grand Total', not just for row groups. For example if you have 10 rows in the grid, the grid will still call the aggregation with 10 values to get a grand total aggregation."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The grand total aggregation is normally not seen, unless the grid is configured with "},{"type":"element","tagName":"a","properties":{"href":"/archive/28.0.0/grouping/#grouping-footers"},"children":[{"type":"text","value":"Grouping Total Footers"}]},{"type":"text","value":". Total footers display the result of the aggregation for top level, for example displaying a grand total even if no row grouping is active."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"When the grid is empty, the aggregations are still called once with an empty set. This is to calculate the grand total aggregation for the top level."}]},{"type":"element","tagName":"h2","properties":{"id":"multi-column-aggregation","style":"position:relative;"},"children":[{"type":"element","tagName":"a","properties":{"href":"#multi-column-aggregation","ariaLabel":"multi column aggregation permalink","className":["anchor","before"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","dataPrefix":"fas","dataIcon":"link","className":["svg-inline--fa","fa-link"],"role":"img","xmlns":"http://www.w3.org/2000/svg","viewBox":"0 0 512 512"},"children":[{"type":"element","tagName":"path","properties":{"fill":"currentColor","d":"M326.612 185.391c59.747 59.809 58.927 155.698.36 214.59-.11.12-.24.25-.36.37l-67.2 67.2c-59.27 59.27-155.699 59.262-214.96 0-59.27-59.26-59.27-155.7 0-214.96l37.106-37.106c9.84-9.84 26.786-3.3 27.294 10.606.648 17.722 3.826 35.527 9.69 52.721 1.986 5.822.567 12.262-3.783 16.612l-13.087 13.087c-28.026 28.026-28.905 73.66-1.155 101.96 28.024 28.579 74.086 28.749 102.325.51l67.2-67.19c28.191-28.191 28.073-73.757 0-101.83-3.701-3.694-7.429-6.564-10.341-8.569a16.037 16.037 0 0 1-6.947-12.606c-.396-10.567 3.348-21.456 11.698-29.806l21.054-21.055c5.521-5.521 14.182-6.199 20.584-1.731a152.482 152.482 0 0 1 20.522 17.197zM467.547 44.449c-59.261-59.262-155.69-59.27-214.96 0l-67.2 67.2c-.12.12-.25.25-.36.37-58.566 58.892-59.387 154.781.36 214.59a152.454 152.454 0 0 0 20.521 17.196c6.402 4.468 15.064 3.789 20.584-1.731l21.054-21.055c8.35-8.35 12.094-19.239 11.698-29.806a16.037 16.037 0 0 0-6.947-12.606c-2.912-2.005-6.64-4.875-10.341-8.569-28.073-28.073-28.191-73.639 0-101.83l67.2-67.19c28.239-28.239 74.3-28.069 102.325.51 27.75 28.3 26.872 73.934-1.155 101.96l-13.087 13.087c-4.35 4.35-5.769 10.79-3.783 16.612 5.864 17.194 9.042 34.999 9.69 52.721.509 13.906 17.454 20.446 27.294 10.606l37.106-37.106c59.271-59.259 59.271-155.699.001-214.959z"},"children":[]}]}]},{"type":"text","value":"Multi-Column Aggregation"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This section provides an example of how to calculate a ratio using values from multiple columns."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"When values from multiple columns are required, a value object containing all the required values across multiple columns\nshould be passed around instead of a simple value. This value object should also contain a "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"toString()"}]},{"type":"text","value":" method, so it can\nalso be resolved by the grid to a single value. This is shown in the code snippet below:"}]},{"type":"element","tagName":"snippet","properties":{"spacebetweenproperties":"true"},"children":[{"type":"text","value":"\n|const gridOptions = {\n|    columnDefs: [\n|        { field: 'gold', aggFunc: 'sum' },\n|        { field: 'silver', aggFunc: 'sum' },\n|        {\n|            headerName: 'Ratio',\n|            colId: 'ratio',\n|            valueGetter: params => {\n|                if (!params.node.group) {\n|                    // no need to handle group levels - calculated in the 'ratioAggFunc'\n|                    return {\n|                        gold: params.data.gold,\n|                        silver: params.data.silver,\n|                        toString: () => (gold && silver) ? gold / silver : 0,\n|                    }\n|                }\n|            },\n|            aggFunc: (params) => {\n|                var goldSum = 0;\n|                var silverSum = 0;\n|                params.values.forEach(value => {\n|                    if (value && value.gold) {\n|                        goldSum += value.gold;\n|                    }\n|                    if (value && value.silver) {\n|                        silverSum += value.silver;\n|                    }\n|                });\n|                return {\n|                    gold: goldSum,\n|                    silver: silverSum,\n|                    toString: () => {\n|                        return goldSum && silverSum ? goldSum / silverSum : 0;\n|                    },\n|                }\n|            }\n|        }\n|    ]\n|}\n"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The following example demonstrates this approach in action:"}]},{"type":"element","tagName":"div","properties":{},"children":[{"type":"element","tagName":"grid-example","properties":{"title":"Multi-Column Aggregation","name":"multi-column-aggregation","type":"generated","options":"{ \"enterprise\": true, \"modules\": [\"clientside\", \"rowgrouping\", \"menu\", \"columnpanel\", \"filterpanel\", \"setfilter\"] }"},"children":[]}]},{"type":"element","tagName":"h2","properties":{"id":"custom-full-row-aggregation","style":"position:relative;"},"children":[{"type":"element","tagName":"a","properties":{"href":"#custom-full-row-aggregation","ariaLabel":"custom full row aggregation permalink","className":["anchor","before"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","dataPrefix":"fas","dataIcon":"link","className":["svg-inline--fa","fa-link"],"role":"img","xmlns":"http://www.w3.org/2000/svg","viewBox":"0 0 512 512"},"children":[{"type":"element","tagName":"path","properties":{"fill":"currentColor","d":"M326.612 185.391c59.747 59.809 58.927 155.698.36 214.59-.11.12-.24.25-.36.37l-67.2 67.2c-59.27 59.27-155.699 59.262-214.96 0-59.27-59.26-59.27-155.7 0-214.96l37.106-37.106c9.84-9.84 26.786-3.3 27.294 10.606.648 17.722 3.826 35.527 9.69 52.721 1.986 5.822.567 12.262-3.783 16.612l-13.087 13.087c-28.026 28.026-28.905 73.66-1.155 101.96 28.024 28.579 74.086 28.749 102.325.51l67.2-67.19c28.191-28.191 28.073-73.757 0-101.83-3.701-3.694-7.429-6.564-10.341-8.569a16.037 16.037 0 0 1-6.947-12.606c-.396-10.567 3.348-21.456 11.698-29.806l21.054-21.055c5.521-5.521 14.182-6.199 20.584-1.731a152.482 152.482 0 0 1 20.522 17.197zM467.547 44.449c-59.261-59.262-155.69-59.27-214.96 0l-67.2 67.2c-.12.12-.25.25-.36.37-58.566 58.892-59.387 154.781.36 214.59a152.454 152.454 0 0 0 20.521 17.196c6.402 4.468 15.064 3.789 20.584-1.731l21.054-21.055c8.35-8.35 12.094-19.239 11.698-29.806a16.037 16.037 0 0 0-6.947-12.606c-2.912-2.005-6.64-4.875-10.341-8.569-28.073-28.073-28.191-73.639 0-101.83l67.2-67.19c28.239-28.239 74.3-28.069 102.325.51 27.75 28.3 26.872 73.934-1.155 101.96l-13.087 13.087c-4.35 4.35-5.769 10.79-3.783 16.612 5.864 17.194 9.042 34.999 9.69 52.721.509 13.906 17.454 20.446 27.294 10.606l37.106-37.106c59.271-59.259 59.271-155.699.001-214.959z"},"children":[]}]}]},{"type":"text","value":"Custom Full Row Aggregation"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Using "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"colDef.aggFunc"}]},{"type":"text","value":" is the preferred way of doing aggregations. However you may find scenarios where you cannot define your aggregations with respect to individual column values. Maybe you are aggregating sales records in different currencies and you need to read the value from one column and the currency code from another column and then convert the record to a common currency for aggregation - the point being you need data from more than just one column, or you want to put the results into different columns to the inputs for the calculation. For that reason, you can take control of the row aggregation by providing a "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"getGroupRowAgg"}]},{"type":"text","value":" function as a grid callback."}]},{"type":"element","tagName":"div","properties":{"className":["custom-block","note"]},"children":[{"type":"element","tagName":"div","properties":{"className":["custom-block-body"]},"children":[{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Using "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"colDef.aggFunc"}]},{"type":"text","value":" is the preferred way of doing aggregations, only use "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"getGroupRowAgg"}]},{"type":"text","value":"\nif you cannot achieve what you want as it will make your code more complex. Also note that "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"getGroupRowAgg"}]},{"type":"text","value":"\nwill not work when pivoting."}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"For groups, when aggregating, the grid stores the results in the colId of the column. For example, if you have a group defined as follows:"}]},{"type":"element","tagName":"snippet","properties":{},"children":[{"type":"text","value":"\nconst gridOptions = {\n    columnDefs: [\n        {\n            field: 'abby',\n            valueGetter: 'data.a + data.b',\n            colId: 'aaa'\n        }\n    ]\n}\n"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Then the result of the aggregation will be stored in "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"data.aaa"}]},{"type":"text","value":" and not in 'abby'. Most of the time this will not matter for you as the colId, if not provided, will default to the field. In order for the grid to display the aggregation result, it must be stored in the correct field name."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Below shows an  example using "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"getGroupRowAgg"}]},{"type":"text","value":". The example doesn't represent a real world scenario, it's contrived for demonstration. It takes the number of medals as inputs and creates two outputs, one as a normal sum and another by multiplying the result by "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"Math.PI"}]},{"type":"text","value":"."}]},{"type":"element","tagName":"div","properties":{},"children":[{"type":"element","tagName":"grid-example","properties":{"title":"Custom Full Row Aggregation","name":"custom-full-row-aggregation","type":"generated","options":"{ \"enterprise\": true, \"modules\": [\"clientside\", \"rowgrouping\", \"menu\", \"columnpanel\", \"filterpanel\", \"setfilter\"], \"exampleHeight\": 620 }"},"children":[]}]},{"type":"element","tagName":"h2","properties":{"id":"next-up","style":"position:relative;"},"children":[{"type":"element","tagName":"a","properties":{"href":"#next-up","ariaLabel":"next up permalink","className":["anchor","before"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","dataPrefix":"fas","dataIcon":"link","className":["svg-inline--fa","fa-link"],"role":"img","xmlns":"http://www.w3.org/2000/svg","viewBox":"0 0 512 512"},"children":[{"type":"element","tagName":"path","properties":{"fill":"currentColor","d":"M326.612 185.391c59.747 59.809 58.927 155.698.36 214.59-.11.12-.24.25-.36.37l-67.2 67.2c-59.27 59.27-155.699 59.262-214.96 0-59.27-59.26-59.27-155.7 0-214.96l37.106-37.106c9.84-9.84 26.786-3.3 27.294 10.606.648 17.722 3.826 35.527 9.69 52.721 1.986 5.822.567 12.262-3.783 16.612l-13.087 13.087c-28.026 28.026-28.905 73.66-1.155 101.96 28.024 28.579 74.086 28.749 102.325.51l67.2-67.19c28.191-28.191 28.073-73.757 0-101.83-3.701-3.694-7.429-6.564-10.341-8.569a16.037 16.037 0 0 1-6.947-12.606c-.396-10.567 3.348-21.456 11.698-29.806l21.054-21.055c5.521-5.521 14.182-6.199 20.584-1.731a152.482 152.482 0 0 1 20.522 17.197zM467.547 44.449c-59.261-59.262-155.69-59.27-214.96 0l-67.2 67.2c-.12.12-.25.25-.36.37-58.566 58.892-59.387 154.781.36 214.59a152.454 152.454 0 0 0 20.521 17.196c6.402 4.468 15.064 3.789 20.584-1.731l21.054-21.055c8.35-8.35 12.094-19.239 11.698-29.806a16.037 16.037 0 0 0-6.947-12.606c-2.912-2.005-6.64-4.875-10.341-8.569-28.073-28.073-28.191-73.639 0-101.83l67.2-67.19c28.239-28.239 74.3-28.069 102.325.51 27.75 28.3 26.872 73.934-1.155 101.96l-13.087 13.087c-4.35 4.35-5.769 10.79-3.783 16.612 5.864 17.194 9.042 34.999 9.69 52.721.509 13.906 17.454 20.446 27.294 10.606l37.106-37.106c59.271-59.259 59.271-155.699.001-214.959z"},"children":[]}]}]},{"type":"text","value":"Next Up"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Continue to the next section to learn about "},{"type":"element","tagName":"a","properties":{"href":"/archive/28.0.0/aggregation-filtering/"},"children":[{"type":"text","value":"Aggregation Filtering"}]},{"type":"text","value":"."}]}]},"frontmatter":{"title":"Aggregation - Custom Functions","version":null,"enterprise":true,"description":null},"headings":[{"id":"directly-supplied-functions","depth":2,"value":"Directly Supplied Functions"},{"id":"registering-custom-functions","depth":2,"value":"Registering Custom Functions"},{"id":"custom-aggregation-functions","depth":2,"value":"Custom Aggregation Functions"},{"id":"multi-column-aggregation","depth":2,"value":"Multi-Column Aggregation"},{"id":"custom-full-row-aggregation","depth":2,"value":"Custom Full Row Aggregation"},{"id":"next-up","depth":2,"value":"Next Up"}]}},"pageContext":{"frameworks":["javascript","angular","react","vue"],"framework":"react","srcPath":"/aggregation-custom-functions","pageName":"aggregation-custom-functions"}},
    "staticQueryHashes": ["1766026005","3577950178","699667431"]}