Here is a basic example:
from dash import *
import dash_ag_grid as dag
import pandas as pd
import dash_mantine_components as dmc
operators = {
"greaterThanOrEqual": "ge",
"lessThanOrEqual": "le",
"lessThan": "lt",
"greaterThan": "gt",
"notEqual": "ne",
"equals": "eq",
}
def filter_df(dff, filter_model, col):
if "filter" in filter_model:
if filter_model["filterType"] == "date":
crit1 = filter_model["dateFrom"]
crit1 = pd.Series(crit1).astype(dff[col].dtype)[0]
if "dateTo" in filter_model:
crit2 = filter_model["dateTo"]
crit2 = pd.Series(crit2).astype(dff[col].dtype)[0]
else:
crit1 = filter_model["filter"]
crit1 = pd.Series(crit1).astype(dff[col].dtype)[0]
if "filterTo" in filter_model:
crit2 = filter_model["filterTo"]
crit2 = pd.Series(crit2).astype(dff[col].dtype)[0]
if "type" in filter_model:
if filter_model["type"] == "contains":
dff = dff.loc[dff[col].str.contains(crit1)]
elif filter_model["type"] == "notContains":
dff = dff.loc[~dff[col].str.contains(crit1)]
elif filter_model["type"] == "startsWith":
dff = dff.loc[dff[col].str.startswith(crit1)]
elif filter_model["type"] == "notStartsWith":
dff = dff.loc[~dff[col].str.startswith(crit1)]
elif filter_model["type"] == "endsWith":
dff = dff.loc[dff[col].str.endswith(crit1)]
elif filter_model["type"] == "notEndsWith":
dff = dff.loc[~dff[col].str.endswith(crit1)]
elif filter_model["type"] == "inRange":
if filter_model["filterType"] == "date":
dff = dff.loc[
dff[col].astype("datetime64[ns]").between_time(crit1, crit2)
]
else:
dff = dff.loc[dff[col].between(crit1, crit2)]
elif filter_model["type"] == "blank":
dff = dff.loc[dff[col].isnull()]
elif filter_model["type"] == "notBlank":
dff = dff.loc[~dff[col].isnull()]
else:
dff = dff.loc[getattr(dff[col], operators[filter_model["type"]])(crit1)]
elif filter_model["filterType"] == "set":
dff = dff.loc[dff[col].astype("string").isin(filter_model["values"])]
return dff
numbers = [
'1111111111111111111',
'2222222222222222222',
'3333333333333333333',
]
test_df = pd.DataFrame()
test_df["test"] = numbers
app = Dash(__name__)
app.layout = html.Div([
dag.AgGrid(
id="grid",
rowData=test_df.to_dict("records"),
defaultColDef={
"sortable": True,
"resizable": True,
"editable": False,
"filter": "agNumberColumnFilter",
},
columnDefs=[{"field": i} for i in test_df.columns],
style={"height": "600px", "width": "100%", "border": "none"},
),
dmc.Button("Callback", id="button")
])
@callback(
Output("grid", "getRowsResponse"),
Input("grid", "getRowsRequest"),
)
def infinite_scroll(request):
if request:
dff = test_df.copy()
### format dff to be numbers
dff['test'] = pd.to_numeric(dff['test'])
if request["filterModel"]:
filters = request["filterModel"]
for f in filters:
try:
if "operator" in filters[f]:
if filters[f]["operator"] == "AND":
dff = filter_df(dff, filters[f]["condition1"], f)
dff = filter_df(dff, filters[f]["condition2"], f)
else:
dff1 = filter_df(dff, filters[f]["condition1"], f)
dff2 = filter_df(dff, filters[f]["condition2"], f)
dff = pd.concat([dff1, dff2])
else:
dff = filter_df(dff, filters[f], f)
except:
pass
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)
lines = len(dff.index)
if lines == 0:
lines = 1
partial = dff.iloc[request["startRow"]: request["endRow"]]
return {"rowData": partial.to_dict("records"), "rowCount": lines}
return no_update
app.run(debug=True)
Obviously, if you want to add more data, you’ll have to get creative in how to do that.