Hi Everyone,
I need to implement Dash AgGrid with ‘serverside’ rowmodel type having features with Row Groupings and Pivot. (code base - Python, Dash)
Below is my sample requirement which I can achieve in clientside model. However Pivoting with columns labels in serverside is not working as expected.
app.py
from dash import Dash, Input, Output, html, dcc
import json
import flask
import pandas as pd
import dash_ag_grid as dag
app = Dash(__name__)
server = app.server
df = pd.read_csv(
"https://raw.githubusercontent.com/plotly/datasets/master/ag-grid/olympic-winners.csv"
)
rowData = df.to_dict('records')
columnDefs = [
# Row group by country, by athelete, by year is enabled. Pivot with respect to sport
{"field": "country", "sortable": True, "filter": True, "rowGroup": True, "hide": True},
{"field": "athlete", "sortable": True, "filter": True, "rowGroup": True, "hide": True},
{"field": "year", "sortable": True, "filter": True, "rowGroup": True, "hide": True},
{"field": "age", "sortable": True, "filter": True},
{"field": "date", "sortable": True, "filter": True},
{"field": "sport", "sortable": True, "filter": True, "pivot": True, "enablePivot": True},
{"field": "total", "sortable": True, "filter": True, "aggFunc": "sum"},
]
def extractRowsFromData(request, df):
dff = df.copy()
groupBy = [i['id'] for i in request['rowGroupCols']]
agg = {i['id']: i['aggFunc'] for i in request['valueCols']}
if not request['groupKeys']:
dff = dff.groupby(groupBy[0]).agg(agg).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):
dff = dff.groupby(groupBy[:len(request['groupKeys'])+1]).agg(agg).reset_index()
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)
grid = html.Div(
[
dag.AgGrid(
id="grid",
columnDefs=columnDefs,
dashGridOptions={
"sideBar": True,
"pivotMode": True,
"suppressAggFuncInHeader": True
},
defaultColDef=dict(
resizable=True,
),
enableEnterpriseModules=True,
rowModelType="serverSide",
# rowData=rowData
),
]
)
app.layout = html.Div(
[
dcc.Markdown("Sample Grid with RowGroupings and Pivot "),
grid,
]
)
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)
.js file placed in assets
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);
setTimeout(function () {
params.success(result);
}, 200);
},
};
return dataSource;
}
I could see reference for my ask in below url which is in javascript which i am not familiar with. I use python, dash, dash_ag_grid to built applications.
Also I would like to allow users to freely apply row grouping and pivots in the columns of the sidebar.
Thanks in Advance.