popo
April 24, 2023, 10:11pm
1
Hi,
AgGrid looks like a great alternative to dash-tabulator (better dash support).
I have some data : over 900.000 rows and 21 columns.
What is the best way to have a seamless experience?
In ‘pagination’ mode (user defined page size) as well as in ‘unlimited scroll’ mode.
hi @popo
Did you get a chance to review the section of the docs on pagination ?
Hello @popo ,
I think it is possible to use pagination along with rowModelType="infinite", this way you are only querying a single page from the server at a time.
Here, check this out:
import dash_ag_grid as dag
import dash
from dash import Input, Output, html, dcc, no_update
import pandas as pd
app = dash.Dash(__name__)
df = pd.read_csv(
"https://raw.githubusercontent.com/plotly/datasets/master/liquor_iowa_2021.csv"
)
app.layout = html.Div(
[
dcc.RadioItems(
id="columnSizing",
options=[
{"label": i, "value": j}
for i, j in [
("Auto size", "autoSize"),
("Size to fit", "sizeToFit"),
]
],
value="autoSize",
),
dag.AgGrid(
id="grid",
columnDefs=[{"field": i} for i in df.columns],
rowModelType="infinite",
columnSize="autoSize",
defaultColDef=dict(
resizable=True,
sortable=True,
filter=True,
minWidth=100
),
dashGridOptions={"pagination":True}
),
]
)
@app.callback(Output("grid", "columnSize"), Input("columnSizing", "value"))
def column_sizing(size_type):
return size_type
@app.callback(
Output("grid", "getRowsResponse"),
Input("grid", "getRowsRequest"),
)
def infinite_scroll(request):
if request is None:
return no_update
partial = df.iloc[request["startRow"] : request["endRow"]]
return {"rowData": partial.to_dict("records"), "rowCount": len(df.index)}
if __name__ == "__main__":
app.run_server(debug=True)
If you use infinite model, you need to also use server side filtering and sorting.
opened 06:50PM - 03 Mar 23 UTC
docs
When `rowModelType="infinite"`, the table doesnt respond to sorting and filterin… g the same way, as denoted here:
https://www.ag-grid.com/react-data-grid/infinite-scrolling/#sorting--filtering
Here is an example of how to work with sorting and filtering inside the requests in an infinite model:
```
"""
Working with infinite scroll against a backend database in AG-Grid.
"""
import traceback
import dash_ag_grid as dag
from dash import Dash, Input, Output, html, no_update, State, ctx
import pandas as pd
import requests
app = Dash(__name__)
raw_data = requests.get(
r"https://www.ag-grid.com/example-assets/olympic-winners.json"
).json()
df = pd.DataFrame(data=raw_data)
pd.to_datetime(df['date'], dayfirst=True)
columnDefs = [
{"field": "athlete", "filter": False},
{"field": "country", "filter": False},
{
"headerName": "Date",
'field': 'date',
"filter": "agDateColumnFilter",
"valueGetter": {"function": "d3.timeParse('%d/%m/%Y')(params.data.date)"},
"valueFormatter": {"function": "params.data.date"},
"filterParams": {
"browserDatePicker": True,
"minValidYear": 2000,
"maxValidYear": 2021,
},
},
]
app.layout = html.Div(
[
dag.AgGrid(
id="grid1",
rowModelType="infinite",
rowSelection="multiple",
columnSize="sizeToFit",
columnDefs=columnDefs,
defaultColDef={"sortable": True, 'filter': True},
# The number of rows rendered outside the viewable area the grid renders.
rowBuffer=0,
# How many blocks to keep in the store. Default is no limit, so every requested block is kept.
maxBlocksInCache=1,
multiSortKey=True
),
]
)
operators = {
'greaterThanOrEqual': 'ge',
'lessThanOrEqual':'le',
'lessThan': 'lt',
'greaterThan': 'gt',
'notEqual': 'ne',
'equals': 'eq'
}
def filterDf(df, data, col):
##To-Do fix date filtering
if data['filterType'] == 'date':
crit1 = data['dateFrom']
if 'dateTo' in data:
crit2 = data['dateTo']
else:
crit1 = data['filter']
if 'filterTo' in data:
crit2 = data['filterTo']
if data['type'] == 'contains':
df = df.loc[df[col].str.contains(crit1)]
elif data['type'] == 'notContains':
df = df.loc[~df[col].str.contains(crit1)]
elif data['type'] == 'startsWith':
df = df.loc[df[col].str.startswith(crit1)]
elif data['type'] == 'notStartsWith':
df = df.loc[~df[col].str.startswith(crit1)]
elif data['type'] == 'endsWith':
df = df.loc[df[col].str.endswith(crit1)]
elif data['type'] == 'notEndsWith':
df = df.loc[~df[col].str.endswith(crit1)]
elif data['type'] == 'inRange':
if data['filterType'] == 'date':
df = df.loc[df[col].astype('datetime64[ns]').between_time(crit1, crit2)]
else:
df = df.loc[df[col].between(crit1, crit2)]
elif data['type'] == 'blank':
df = df.loc[df[col].isnull()]
elif data['type'] == 'notBlank':
df = df.loc[~df[col].isnull()]
else:
df = df.loc[getattr(df[col], operators[data['type']])(crit1)]
return df
@app.callback(
Output("grid1", "getRowsResponse"),
Input("grid1", "getRowsRequest")
)
def infinite_scroll(request):
dff = df.copy()
orig_dff = dff.copy()
if request['filterModel']:
fils = request['filterModel']
for k in fils:
try:
if 'operator' in fils[k]:
if fils[k]['operator'] == 'AND':
dff = filterDf(dff, fils[k]['condition1'], k)
dff = filterDf(dff, fils[k]['condition2'], k)
else:
dff1 = filterDf(dff, fils[k]['condition1'], k)
dff2 = filterDf(dff, fils[k]['condition2'], k)
dff = pd.concat([dff1, dff2])
else:
dff = filterDf(dff, fils[k], k)
except:
print(traceback.format_exc())
pass
dff = dff
if request['sortModel']:
sorting = []
asc = []
for sort in request['sortModel']:
sorting.append(sort['colId'])
if sort['sort'] == 'asc':
asc.append(True)
else:
asc.append(False)
dff = dff.sort_values(by=sorting, ascending=asc)
partial = dff.iloc[request["startRow"]: request["endRow"]]
return {"rowData": partial.to_dict("records"), "rowCount": len(orig_dff.index)}
if __name__ == "__main__":
app.run_server(debug=True, port=12345)
```
4 Likes
popo
April 27, 2023, 12:01am
5
Great @jinnyzor !
just Great !!
But…
I had to upgrade to dash-ag-grid==2.0.0rc2 to run the above code.
(as stipulated at the time of this post on dashaggrid.pythonanywhere.com in the Getting Started section)
I run into a problem running the ’ Filtering and Sorting’ code.
Several arguments are unknown (commented below).
dag.AgGrid(
id="grid1",
rowModelType="infinite",
#rowSelection="multiple",
columnSize="sizeToFit",
columnDefs=columnDefs,
defaultColDef={"sortable": True, 'filter': True},
## The number of rows rendered outside the viewable area the grid renders.
# rowBuffer=0,
## How many blocks to keep in the store. Default is no limit, so every requested block is kept.
# maxBlocksInCache=1,
# multiSortKey=True
),
rowSelection, rowBuffer, maxBlocksInCache, multiSortKey
when i run the ’ Filtering and Sorting’ code :
Am I doing something wrong?
1 Like
As far as the commented out areas, you’ll need to toss those into dashGridOptions.
What is the full code of the things that you are running? Also, as far as the code to use, use the second post on that issue. In the first I was sorting some things out.