Here’s the problem. I set up a bunch of tooltips for specific cells. They display perfectly. But when I go to the next page, the tooltips are still displaying on the same cells, they should be display the tooltip appropriate for the ID of the row, but instead they are displaying the tooltip for the index of the row of the table. If I had to guess, I’d say that there’s some offset that should be automatically applied when the new data is loaded, and it’s not being used to index the tooltips.
Let’s say I create a DataTable and use the following attributes.
page_current=0,
data = df.to_dict('records'),
page_size=50,
page_action='custom',
tooltip_data=[
{'src_series_title': {'duration': None, 'type': 'markdown', 'value': '**TEST**: foo1'}},
{'src_series_title': {'duration': None, 'type': 'markdown', 'value': '**TEST**: foo2'}},
{'src_series_title': {'duration': None, 'type': 'markdown', 'value': '**TEST**: foo3'}},
{'src_series_title': {'duration': None, 'type': 'markdown', 'value': '**TEST**: foo4'}},
{'src_series_title': {'duration': None, 'type': 'markdown', 'value': '**TEST**: foo5'}},
],
And here’s my update callback (please ignore the temporary use of a global variable, I’ll be stashing it properly later).
@app.callback(
[
Output('datatable-paging', 'data'),
Output('datatable-paging', 'page_count'),
],
[Input('datatable-paging', "page_current"),
Input('datatable-paging', "page_size"),
Input('datatable-paging', "filter_query"),
Input('datatable-paging', "sort_by"),
Input('errorlevel', 'value')],
)
def update_table(page_current, page_size, filter, sort_by, errorlevel):
dff = app.df
print("update_table", type(filter), filter)
print("update_table", type(errorlevel), errorlevel)
if errorlevel is not None:
if filter is None:
filter = errorlevel
else:
filter = filter + ' && ' + errorlevel
if filter is not None and len(filter) > 0:
filtering_expressions = filter.split(' && ')
for filter_part in filtering_expressions:
col_name, operator, filter_value = split_filter_part(filter_part)
if operator in ('eq', 'ne', 'lt', 'le', 'gt', 'ge'):
# these operators match pandas series operator method names
dff = dff.loc[getattr(dff[col_name], operator)(filter_value)]
elif operator == 'contains':
dff = dff.loc[dff[col_name].str.contains(filter_value)]
elif operator == 'datestartswith':
# this is a simplification of the front-end filtering logic,
# only works with complete fields in standard format
dff = dff.loc[dff[col_name].str.startswith(filter_value)]
if sort_by is not None and len(sort_by) > 0:
dff = dff.sort_values(
sort_by[0]['column_id'],
ascending=sort_by[0]['direction'] == 'asc',
inplace=False
)
size = dff.size / len(dff.columns)
dff = dff.iloc[page_current*page_size:(page_current+1)*page_size]
print(dff.head())
return dff.to_dict('records'), int(size / page_size)+1
Let me know if you want a small standalone example. But in my code, if I do the following, the first few rows of the table always display the same tooltips.
I’d greatly appreciate a suggestion for a patch or workaround.
Thanks!
P.S. For what it’s worth, I played around with setting trying to set the derived_viewport_indices or row_ids in the Output. (Oddly, they always return the first page data if I ask for them via State, which seems wrong.) But that didn’t change anything.