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.