How do I use Status Bar in Dash AG Grid(ServerSide RowModel)

JavaScript Data Grid: Status Bar (ag-grid.com)

I want to display row count information in the Status Bar of dash ag grid, as shown in the link Above.

If you see my code, Grid-Provided Status Bar Components work fine when using the Server-Side Row Model. However, they do not work when using the server-side Row Model.

I would like to know if there is way to make it work on the server-side as well.

thankyou.

===app.py=====================

import dash_ag_grid as dag
from dash import Dash, html, dcc, Input, Output, State
import pandas as pd
import json
import flask
import pandas as pd

app = Dash(__name__)

server = app.server


df = pd.read_csv("datasets/olympic-winners.csv")
# df = pd.read_csv(
    # "https://raw.githubusercontent.com/plotly/datasets/master/ag-grid/olympic-winners.csv"
# )

columnDefs = [
    {"field": "country", "enableRowGroup": True, "rowGroup": True, "hide": True},
    {"field": "year", "enableRowGroup": True, "rowGroup": True, "hide": True},
    {"field": "sport", "enableRowGroup": True},
    {"field": "gold"},
    {"field": "silver"},
    {"field": "bronze"},
]

app.layout = html.Div(
    [
        dag.AgGrid(
            columnDefs=columnDefs,
            rowData=df.to_dict("records"),
            columnSize="sizeToFit",
            defaultColDef={"resizable": True, "sortable": True, "filter": True},
            enableEnterpriseModules=True,
            rowModelType="clientSide",
            # rowModelType="serverSide",
            dashGridOptions={
                "rowGroupPanelShow": "always",
                "statusBar": {
                    "statusPanels": [
                        {"statusPanel": "agTotalRowCountComponent"},
                    ]
                },
            },
            id="grid",
        ),
    ],
)


def extractRowsFromData(request, df):
    response = []
    print(request)
    dff = df.copy()

    groupBy = []
    if request["rowGroupCols"]:
        groupBy = [i["id"] for i in request["rowGroupCols"]]
    agg = {}
    if request["valueCols"]:
        agg = {i["id"]: i["aggFunc"] for i in request["valueCols"]}
    if not request["groupKeys"]:
        if groupBy:
            if agg:
                dff = dff.groupby(groupBy[0]).agg(agg).reset_index()
            else:
                dff = dff.groupby(groupBy[0]).agg("count").reset_index()
    else:
        for i in range(len(request["groupKeys"])):
            dff = dff[dff[request["rowGroupCols"][i]["id"]] == request["groupKeys"][i]]
        if len(request["groupKeys"]) != len(groupBy):
            if agg:
                dff = (
                    dff.groupby(groupBy[: len(request["groupKeys"]) + 1])
                    .agg(agg)
                    .reset_index()
                )
            else:
                dff = (
                    dff.groupby(groupBy[: len(request["groupKeys"]) + 1])
                    .agg("count")
                    .reset_index()
                )
    dff = dff.sort_values(
        by=[i["colId"] for i in request["sortModel"]],
        ascending=[i["sort"] == "asc" for i in request["sortModel"]],
    )

    return {
        "rowData": dff.to_dict("records")[request["startRow"] : request["endRow"]],
        "rowCount": len(dff),
    }


@server.route("/api/serverData", methods=["POST"])
def serverData():
    response = extractRowsFromData(flask.request.json, df)
    return json.dumps(response)


app.clientside_callback(
    """async function (id) {
        const updateData = (grid) => {
          var datasource = createServerSideDatasource();
          grid.setServerSideDatasource(datasource);
        };
        var grid;
        grid = await window.dash_ag_grid.getApiAsync(id)
        if (grid) {
            updateData(grid)
        }
        return window.dash_clientside.no_update
    }""",
    Output("grid", "id"),
    Input("grid", "id"),
)

if __name__ == "__main__":
    app.run(debug=True)

=== dag.js ========================

async function getServerData(request) {
  response = await fetch('./api/serverData', {'method': 'POST', 'body': JSON.stringify(request),
    'headers': {'content-type': 'application/json'}})
  return response.json()
}


function createServerSideDatasource() {
  const dataSource = {
    getRows: async (params) => {
      console.log('ServerSideDatasource.getRows: params = ', params);
      var result = await getServerData(params.request);
      console.log('getRows: result = ', result);
      params.success(result);
    },
  };
  return dataSource;
}



var dagfuncs = window.dashAgGridFunctions = window.dashAgGridFunctions || {};

dagfuncs.getChildCount =  function(data) {
  // here child count is stored in the 'childCount' property
  // console.log('data = ', data);
  return data.childCount;
}

Hello @wowwwn,

What isnt working about the status bar?

The server side model seems to be working fine…

Thanks for the quick response!
If you run my code, when I use rowModelType=“clientSide”, the rowCount appears as it does on your image.
However, when I use RerverSideRowModel by changing to rowModelType=“serverSide”, it doesn’t work.

Actually, I’ve managed to solve this issue by creating seperate component and display it at the bottom of ag-grid table.

But, since this features are already present in dash-ag-grid.js, I just want to know how to use the it.

Actually, what I really want to know is how to use the SSRM Advanced Filter in dash_ag_grid.

It’s really difficult to replicate this with a separate dash component. I want to know if its possible to implement the advanced features of all the ag-grid, which seems written in JavaScript, to in dash_ag_grid. I would really appreciate any tips or help.

As far as the status bar, it seems to be disabled (at least counts):

import dash_ag_grid as dag
from dash import Dash, html, dcc, Input, Output, State
import pandas as pd
import json
import flask
import pandas as pd

app = Dash(__name__)

server = app.server


# df = pd.read_csv("datasets/olympic-winners.csv")
df = pd.read_csv(
    "https://raw.githubusercontent.com/plotly/datasets/master/ag-grid/olympic-winners.csv"
)

columnDefs = [
    {"field": "country", "enableRowGroup": True, "rowGroup": True, "hide": True},
    {"field": "year", "enableRowGroup": True, "rowGroup": True, "hide": True},
    {"field": "sport", "enableRowGroup": True},
    {"field": "gold"},
    {"field": "silver"},
    {"field": "bronze"},
]

app.layout = html.Div(
    [
        dag.AgGrid(
            columnDefs=columnDefs,
            rowData=df.to_dict("records"),
            columnSize="sizeToFit",
            defaultColDef={"resizable": True, "sortable": True, "filter": True},
            enableEnterpriseModules=True,
            # rowModelType="clientSide",
            rowModelType="serverSide",
            dashGridOptions={
                "enableRangeSelection": True,
                "rowGroupPanelShow": "always",
                "statusBar": {
                    "statusPanels": [
                        {"statusPanel": "agAggregationComponent",
                         "statusPanelParams": {
                            "aggFuncs": ['min', 'max', 'avg']
                        }
                        },
                    ]
                },
            },
            id="grid",
        ),
    ],
)


def extractRowsFromData(request, df):
    response = []
    print(request)
    dff = df.copy()

    groupBy = []
    if request["rowGroupCols"]:
        groupBy = [i["id"] for i in request["rowGroupCols"]]
    agg = {}
    if request["valueCols"]:
        agg = {i["id"]: i["aggFunc"] for i in request["valueCols"]}
    if not request["groupKeys"]:
        if groupBy:
            if agg:
                dff = dff.groupby(groupBy[0]).agg(agg).reset_index()
            else:
                dff = dff.groupby(groupBy[0]).agg("count").reset_index()
    else:
        for i in range(len(request["groupKeys"])):
            dff = dff[dff[request["rowGroupCols"][i]["id"]] == request["groupKeys"][i]]
        if len(request["groupKeys"]) != len(groupBy):
            if agg:
                dff = (
                    dff.groupby(groupBy[: len(request["groupKeys"]) + 1])
                    .agg(agg)
                    .reset_index()
                )
            else:
                dff = (
                    dff.groupby(groupBy[: len(request["groupKeys"]) + 1])
                    .agg("count")
                    .reset_index()
                )
    dff = dff.sort_values(
        by=[i["colId"] for i in request["sortModel"]],
        ascending=[i["sort"] == "asc" for i in request["sortModel"]],
    )

    return {
        "rowData": dff.to_dict("records")[request["startRow"] : request["endRow"]],
        "rowCount": len(dff),
    }


@server.route("/api/serverData", methods=["POST"])
def serverData():
    response = extractRowsFromData(flask.request.json, df)
    return json.dumps(response)


app.clientside_callback(
    """async function (id) {
        const updateData = (grid) => {
          var datasource = createServerSideDatasource();
          grid.setServerSideDatasource(datasource);
        };
        var grid;
        grid = await window.dash_ag_grid.getApiAsync(id)
        if (grid) {
            updateData(grid)
        }
        return window.dash_clientside.no_update
    }""",
    Output("grid", "id"),
    Input("grid", "id"),
)

if __name__ == "__main__":
    app.run(debug=True)
1 Like

Thanks for letting me know, I didn’t realize the agAggregationComponent would work.

For now, I think I just have to handle the counts with a separate component and a callback on the server side.

1 Like