Example #1
0
def test_stream_dataframe_dictionary_value_single():
    # Given
    value = pd.DataFrame({"x": [1, 2], "y": ["a", "b"]})
    tabulator = Tabulator(value=value)
    stream_value = {"x": 4, "y": "d"}

    # Used to test that value event is triggered
    global VALUE_CHANGED_COUNT
    VALUE_CHANGED_COUNT = 0

    @param.depends(tabulator.param.value, watch=True)
    def _inc(*events):
        global VALUE_CHANGED_COUNT
        VALUE_CHANGED_COUNT += 1

    # When PROVIDING A DICTIONARY ROW
    tabulator.stream(stream_value)
    # Then
    tabulator_source_df = tabulator._source.to_df().drop(columns=["index"])
    expected = pd.DataFrame({"x": [1, 2, 4], "y": ["a", "b", "d"]})
    pd.testing.assert_frame_equal(tabulator.value, expected)
    pd.testing.assert_frame_equal(tabulator_source_df,
                                  expected,
                                  check_column_type=False,
                                  check_dtype=False)
    assert VALUE_CHANGED_COUNT == 1
Example #2
0
def test_replace_stream_and_reset():
    # Given
    data = pd.DataFrame({"x": [1, 2, 3, 4, 5], "y": ["a", "b", "c", "d", "e"]})
    data1 = data.copy(deep=True).loc[0:1, ].reset_index(drop=True)
    data2 = data.copy(deep=True).loc[2:3, ].reset_index(drop=True)
    data3 = data.copy(deep=True).loc[4:4, ]
    tabulator = Tabulator(value=data1)
    # When replace, stream and reset
    tabulator.value = data2
    tabulator.stream(stream_value=data3)
    tabulator.value = data.copy(deep=True).loc[0:1, ]
    # Then
    assert set(tabulator._source.data["x"]) == {1, 2}
Example #3
0
def test_stream_dataframe_dataframe_value():
    # Given
    value = pd.DataFrame({"x": [1, 2], "y": ["a", "b"]})
    tabulator = Tabulator(value=value)
    stream_value = pd.DataFrame({"x": [3, 4], "y": ["c", "d"]})

    # Used to test that value event is triggered
    global VALUE_CHANGED_COUNT
    VALUE_CHANGED_COUNT = 0

    @param.depends(tabulator.param.value, watch=True)
    def _inc(*events):
        global VALUE_CHANGED_COUNT
        VALUE_CHANGED_COUNT += 1

    # When
    tabulator.stream(stream_value)
    # Then
    tabulator_source_df = tabulator._source.to_df().drop(columns=["index"])
    expected = pd.DataFrame({"x": [1, 2, 3, 4], "y": ["a", "b", "c", "d"]})
    pd.testing.assert_frame_equal(tabulator.value, expected)
    pd.testing.assert_frame_equal(tabulator_source_df, expected)
    assert VALUE_CHANGED_COUNT == 1
Example #4
0
def test_stream_cds_dictionary_value():
    # Given
    value = ColumnDataSource({"x": [1, 2], "y": ["a", "b"]})
    tabulator = Tabulator(value=value)
    stream_value = {"x": [3, 4], "y": ["c", "d"]}

    # Used to test that value event is triggered
    global VALUE_CHANGED_COUNT
    VALUE_CHANGED_COUNT = 0

    @param.depends(tabulator.param.value, watch=True)
    def _inc(*events):
        global VALUE_CHANGED_COUNT
        VALUE_CHANGED_COUNT += 1

    # When
    tabulator.stream(stream_value)
    # Then
    tabulator_source_json = tabulator._source.to_json(
        include_defaults=False)["data"]
    expected = {"x": [1, 2, 3, 4], "y": ["a", "b", "c", "d"]}
    assert tabulator.value is value
    assert tabulator_source_json == expected
    assert VALUE_CHANGED_COUNT == 1
Example #5
0
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})"