Alright, got the server side to work, this utilizing the server route, enjoy:
app.py
import dash_ag_grid as dag
from dash import Dash, Input, Output, html, dcc, State
import requests, json
import flask
app = Dash(__name__)
server = app.server
rowData = requests.get('https://www.ag-grid.com/example-assets/small-tree-data.json').json()
def extractRowsFromData(groupKeys, data):
response = []
if len(groupKeys) == 0:
for row in data:
response.append({
'group': not row.get('children') is None,
'employeeId': row['employeeId'],
'employeeName': row['employeeName'],
'employmentType': row['employmentType'],
'jobTitle': row['jobTitle']
})
return response
key = groupKeys[0]
for row in data:
if row['employeeId'] == key:
response += extractRowsFromData(
groupKeys[1:],
row['children']
)
return response
@server.route('/api/serverData', methods=['POST'])
def serverData():
response = extractRowsFromData(flask.request.json['groupKeys'], rowData)
return json.dumps(response)
grid = html.Div(
[
dag.AgGrid(
id="grid",
columnDefs= [
{"field": 'employeeId', "hide": True},
{"field": 'employeeName', "hide": True},
{"field": 'jobTitle'},
{"field": 'employmentType'},
],
defaultColDef={
"flex": 1,
},
dashGridOptions={
"autoGroupColumnDef": {
"field": "employeeName",
"cellRendererParams": {
"function": "groupRenderer"
},
},
"treeData": True,
"isServerSideGroupOpenByDefault": {'function': 'params ? params.rowNode.level < 2 : null'},
"isServerSideGroup": {'function': 'params ? params.group : null'},
"getServerSideGroupKey": {"function": 'params ? params.employeeId : null'}
},
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 allRows = await getServerData(params.request)
var request = params.request;
var doingInfinite = request.startRow != null && request.endRow != null;
var result = doingInfinite
? {
rowData: allRows.slice(request.startRow, request.endRow),
rowCount: allRows.length,
}
: { rowData: allRows };
console.log('getRows: result = ', result);
setTimeout(function () {
params.success(result);
}, 200);
},
};
return dataSource;
}
dagfuncs.groupRenderer = function (){
return {
innerRenderer: (params) => {
console.log(params)
// display employeeName rather than group key (employeeId)
return params.data.employeeName;
}
}
}