Ag-Grid component with input support

Hi @usmansiddiqui98! Good question, yes! Hopefully the code attached here should be a full working example. Let me know if it doesn’t work.

import streamlit as st
import pandas as pd
from st_aggrid import AgGrid, GridOptionsBuilder, GridUpdateMode, DataReturnMode, JsCode

js_sumFunction = JsCode("""

    function sumFunction(params) {
        let result = 0;
        params.values.forEach((value) => {
            if (typeof value === 'number') {
                result += value;
            }
        });
      return result;
    }

""")

js_stdev_sample = JsCode("""

    function stdevSample(params) {
    
        /* Double slash comments appear not to work here 
        
        Quick example adapted from https://www.geeksforgeeks.org/how-to-get-the-standard-deviation-of-an-array-of-numbers-using-javascript/
        
        */
    
        /* Define array and add each entry from AG Grid into the array - there is probably a better way of doing this...?*/
        let arr = [];
        params.values.forEach((value) => {
            if (typeof value === 'number') {
                arr.push(value);
            }
        });
        
        /* Calculate mean */
        let mean = arr.reduce((acc, curr)=>{
            return acc + curr
        }, 0) / arr.length;
        
        /* Calculating sum of (x-mean_x)^2 */
        arr = arr.map((k)=>{
            return (k - mean) ** 2
        });
        
        /* Apply (x-mean_x)^2 calculation for all x in the array */
        let sum = arr.reduce((acc, curr)=> acc + curr, 0);
        
        /* Variance definition of a sample (including -1 normalisation) */
        let variance = sum / (arr.length - 1);
        
        /* Sample standard deviation is square root of sample variance */
        return Math.sqrt(variance);

    }

""")

columnDefs = [
                { "field": 'Name'},
                { "field": 'Fruit'},
                { "field": 'Count', "type":["numericColumn", "numberColumnFilter"]}
            ]
gridOptions = {
    "defaultColDef":{
        "minWidth":5,
        "editable":False,
        # allow every column to be aggregated
        "enableValue": True,
        # allow every column to be grouped
        "enableRowGroup": True,
        # allow every column to be pivoted
        "enablePivot": True,
        "filter":True,
        "resizable":True,
        # "rowGroup":False,
        # "hide":False,
        # if it's not clear already, any other AG Grid gridOptions can go here - look on the website!
        },
    "columnDefs": columnDefs,
    "aggFuncs": {"sumFunction": js_sumFunction, # example sum function from AG Grid docs (https://www.ag-grid.com/react-data-grid/aggregation-custom-functions/) to show how this works - has same result as inbuilt sum but appears separately in Column Tools Panel 
                "stdevSample": js_stdev_sample
                },
    "sideBar": True,
    "animateRows": True,

}
# A fun fruit-based sample dataset
df = pd.DataFrame({'Name':['James', 'James', 'Frank', 'Catherine', 'Catherine', 'Catherine', 'Mira'], 
                   'Fruit':['Apple', 'Mango', 'Banana', 'Banana', 'Grape', 'Tomato', 'Banana'],
                   'Count':[1,3, 2,3,7, 1, 4]})
grid_response = AgGrid(
                    df,
                    gridOptions=gridOptions,
                    height=500,
                    allow_unsafe_jscode=True,
                    enable_enterprise_modules=True,
                    reload_data=False,
                    update_mode=GridUpdateMode.MODEL_CHANGED,
                    theme="light"
                )


(Only issue is the divide by zero error when number of data points=1 and the denominator of the variance is 1-1=0, but apart from that this works for me.)

1 Like