def test_patch_from_partial_dataframe(): data = pd.DataFrame({"x": [1, 2, 3, 4], "y": ["a", "b", "c", "d"]}) data1 = data.loc[0:1, ] data2 = data.loc[2:4] # When tabulator = Tabulator(value=data1) tabulator.value = data2.reset_index(drop=True) patch_value = tabulator.value["x"] + 2 tabulator.patch(patch_value) # Then expected = pd.DataFrame({"x": [5, 6], "y": ["c", "d"]}) pd.testing.assert_frame_equal(tabulator.value, expected)
def test_patch_and_reset(): """I experienced some strange behaviour which I test below. The code actually worked as it should. The problem was that I patched the original data so I could never "reset" back to the original data """ # Given data = pd.DataFrame({"x": [1, 2, 3, 4], "y": ["a", "b", "c", "d"]}) data_copy = data.copy(deep=True) tabulator = Tabulator(value=data_copy) patch = tabulator.value["x"] + 2 # When patch Then tabulator.patch(patch_value=patch) assert set(tabulator._source.data["x"]) == {3, 4, 5, 6} # When reset Then tabulator.value = data assert set(tabulator._source.data["x"]) == {1, 2, 3, 4}
class TabulatorDataCDSApp(pn.Column): """Extension Implementation""" tabulator = param.Parameter() reset = param.Action(label="RESET") replace = param.Action(label="REPLACE") stream = param.Action(label="STREAM") patch = param.Action(label="PATCH") # The _rename dict is used to keep track of Panel parameters to sync to Bokeh properties. # As dope is not a property on the Bokeh model we should set it to None _rename = { **pn.Column._rename, "tabulator": None, "reset": None, "replace": None, "stream": None, "patch": None, } def __init__(self, configuration: Dict, data: pd.DataFrame, **params): super().__init__(**params) self.data = data self.data_reset = ColumnDataSource(self.data.iloc[0:10, ]) self.tabulator = Tabulator( configuration=configuration, value=self.data_reset, sizing_mode="stretch_both", background="salmon", ) self.sizing_mode = "stretch_width" self.height = 950 self.rows_count = len(self.data) self.stream_count = 15 self.reset = self._reset_action self.replace = self._replace_action self.stream = self._stream_action self.patch = self._patch_action stylesheet = TabulatorStylesheet(theme="site") actions_pane = pn.Param( self, parameters=["reset", "replace", "stream", "patch"], name="Actions") tabulator_pane = pn.Param(self.tabulator, parameters=["selection"]) self[:] = [ stylesheet, self.tabulator, pn.WidgetBox(stylesheet.param.theme, actions_pane, tabulator_pane, sizing_mode="fixed", width=400), ] def _reset_action(self, *events): value = self.data.iloc[0:10, ] self.tabulator.value.data = value def _replace_action(self, *events): data = self.data.iloc[10:15, ] self.tabulator.value.data = data def _stream_action(self, *events): if self.stream_count == len(self.data): self.stream_count = 15 self._reset_action() else: stream_data = self.data.iloc[self.stream_count:self.stream_count + 1, ] self.tabulator.stream(stream_data) self.stream_count += 1 def _patch_action(self, *events): def _patch(value): value += 10 if value >= 100: return 0 return value data = self.tabulator.value.data progress = data["progress"] new_progress = [_patch(value) for value in progress] patches = { "progress": [(slice(len(progress)), new_progress)], } self.tabulator.patch(patches) def __repr__(self): return f"Tabulator({self.name})" def __str__(self): return f"Tabulator({self.name})"