Here is if you have data as a df:
app.py
import dash_ag_grid as dag
from dash import Dash, Input, Output, html, dcc, State
import requests, json
import flask
import pandas as pd
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 and by year is enabled.
{"field": "country", "sortable": True, "filter": True, "rowGroup": True, "hide": True},
{"field": "year", "sortable": True, "filter": True, "rowGroup": True, "hide": True},
{"field": "athlete", "sortable": True, "filter": True},
{"field": "age", "sortable": True, "filter": True},
{"field": "date", "sortable": True, "filter": True},
{"field": "sport", "sortable": True, "filter": True},
{"field": "total", "sortable": True, "filter": True, "aggFunc": "sum"},
]
def extractRowsFromData(request, df):
response = []
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={"rowSelection": "multiple"},
defaultColDef=dict(
resizable=True,
),
enableEnterpriseModules=True,
rowModelType="serverSide",
),
]
)
app.layout = html.Div(
[
dcc.Markdown("Example: Organisational Hierarchy using Tree Data "),
grid,
]
)
app.clientside_callback(
"""async function (id) {
const delay = ms => new Promise(res => setTimeout(res, ms));
const updateData = (grid) => {
var datasource = createServerSideDatasource();
grid.setServerSideDatasource(datasource);
};
var grid;
try {
grid = dash_ag_grid.getApi(id)
} catch {}
count = 0
while (!grid) {
await delay(200)
try {
grid = dash_ag_grid.getApi(id)
} catch {}
count++
if (count > 20) {
break;
}
}
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:
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;
}
with support for sorting the columns:
import dash_ag_grid as dag
from dash import Dash, Input, Output, html, dcc, State
import requests, json
import flask
import pandas as pd
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 and by year is enabled.
{"field": "country", "sortable": True, "filter": True, "rowGroup": True, "hide": True},
{"field": "year", "sortable": True, "filter": True, "rowGroup": True, "hide": True},
{"field": "athlete", "sortable": True, "filter": True},
{"field": "age", "sortable": True, "filter": True},
{"field": "date", "sortable": True, "filter": True},
{"field": "sport", "sortable": True, "filter": True},
{"field": "total", "sortable": True, "filter": True, "aggFunc": "sum"},
]
def extractRowsFromData(request, df):
response = []
print(request)
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()
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)
grid = html.Div(
[
dag.AgGrid(
id="grid",
columnDefs=columnDefs,
dashGridOptions={"rowSelection": "multiple"},
defaultColDef=dict(
resizable=True,
),
enableEnterpriseModules=True,
rowModelType="serverSide",
),
]
)
app.layout = html.Div(
[
dcc.Markdown("Example: Organisational Hierarchy using Tree Data "),
grid,
]
)
app.clientside_callback(
"""async function (id) {
const delay = ms => new Promise(res => setTimeout(res, ms));
const updateData = (grid) => {
var datasource = createServerSideDatasource();
grid.setServerSideDatasource(datasource);
};
var grid;
try {
grid = dash_ag_grid.getApi(id)
} catch {}
count = 0
while (!grid) {
await delay(200)
try {
grid = dash_ag_grid.getApi(id)
} catch {}
count++
if (count > 20) {
break;
}
}
if (grid) {
updateData(grid)
}
return window.dash_clientside.no_update
}""",
Output('grid', 'id'), Input('grid', 'id')
)
if __name__ == "__main__":
app.run(debug=True)