Patching values in Tabulator causes the vertical scrollbar to reset
ALL software version info
Python 3.8.8 panel 0.13.0a43
Description of expected behavior and the observed behavior
Expected behaviour: When patching data in Tabulator the vertical scrollbar should stay in the same position. Observed behaviour: When using patch function on Tabulator the vertical scrollbar jumps to the top
Complete, minimal, self-contained example code that reproduces the issue
import numpy as np
import pandas as pd
import panel as pn
df = pd.DataFrame(np.random.randn(10, 5), columns=list('ABCDE'))
styled = pn.widgets.Tabulator(df, height=200)
def highlight_max(s):
'''
highlight the maximum in a Series yellow.
'''
is_max = s == s.max()
return ['background-color: yellow' if v else '' for v in is_max]
styled.style.apply(highlight_max)
def start_updating(*args):
pn.state.add_periodic_callback(update, period=1000)
def update():
df = pd.DataFrame(np.random.randn(10, 5), columns=list('ABCDE'))
styled.patch(df)
button = pn.widgets.Button(name="Start")
button.on_click(start_updating)
pn.Column(button, styled).servable()
Stack traceback and/or browser JavaScript console output
Screenshots or screencasts of the bug in action
https://user-images.githubusercontent.com/2953645/159003446-e99ebde0-53c4-4bcf-a417-8a3c109c865c.mp4
Apparently this is still an issue. Will attempt reproduce tomorrow.
I believe there are two problems with the current fix.
- When calling scrollToRow we set ifVisible = false. In the example visible in the video if we scroll so that 5th row is the top visible one. Then we won't scroll to it because it's already visible when we reset the scroll bar on patch.
- The scrolling works correctly if we add more rows and scroll to something not visible on the initial load. The interesting problem that occurs then is that if we scroll to the 8th row, then a little bit of the 7th row is visible. On the next patch we will therefore scroll to the 7th row. Then a little bit of 6th row is visible and so we repeat until we are back in the case 1. I think this requires changing the second parameter of scrollToRow but haven't had a chance to experiment yet.
Following the advice I have found here https://stackoverflow.com/questions/66920201/react-tabulator-looses-scroll-selection-after-replacedata I tried implementing a similar solution here https://github.com/holoviz/panel/pull/3327 it seems to be working well except for the fact that when we patch the scrollbar gets deselected and this can be annoying when updating frequently. Judging by this discussion it seems there is no easy fix for that https://github.com/olifolkerd/tabulator/issues/3056
Thanks for looking into that @Kadek! The PR looks good and I'll be happy to merge.
I have just discovered that the issue reappeared. After some investigation I am not perfectly sure which change caused the problem but it appears there is additional rendering happening which restarts the scrollbar to 0. I played around this change https://github.com/holoviz/panel/pull/3463 and managed to fix the problem with this approach https://github.com/holoviz/panel/pull/3645. This fixes the problem present in this issue as well as still preserves the fix for https://github.com/holoviz/panel/issues/3450. Would it be possible to merge https://github.com/holoviz/panel/pull/3645 ?
Hey @maximlt what do you think of my change https://github.com/holoviz/panel/pull/3645 as a possible fix?
We've added UI tests for the Tabulator widget in https://github.com/holoviz/panel/pull/3633
Do you mind rebasing your PR https://github.com/holoviz/panel/pull/3645 on master to run these new tests?
Done! Some tests are failing but it looks like the same ones are failing on master. It shouldn't be related to https://github.com/holoviz/panel/pull/3645 then?
The problem still exists in panel 0.14.0a4 pyviz/label/dev.
Python 3.8.13 Panel 0.14.0a4
It appears to be the styling causing the vertical scroll bar to reset. The vertical scroll bar behaves properly when styling is removed. However, the horizontal scroll bar is reset, and when using pagination, the table returns to page 1.
import numpy as np
import pandas as pd
import panel as pn
df = pd.DataFrame(np.random.randn(10, 10), columns=list('ABCDEFGHIJ'))
styled = pn.widgets.Tabulator(df,
pagination='local',
page_size=5,
height=200,
width=400)
def highlight_max(s):
'''
highlight the maximum in a Series yellow.
'''
is_max = s == s.max()
return ['background-color: yellow' if v else '' for v in is_max]
# styled.style.apply(highlight_max)
def start_updating(*args):
pn.state.add_periodic_callback(update, period=1000)
def update():
df = pd.DataFrame(np.random.randn(10, 10), columns=list('ABCDEFGHIJ'))
styled.patch(df)
button = pn.widgets.Button(name="Start")
button.on_click(start_updating)
pn.Column(button, styled).servable()