panel icon indicating copy to clipboard operation
panel copied to clipboard

Tabulator columns width ("fit_data_fill") not refreshing when editing cells

Open xavArtley opened this issue 3 years ago • 1 comments

panel 0.14.0

MRE (extract from a larger code)

import param
import panel as pn
import pandas as pd
from bokeh.models.widgets.tables import SelectEditor
pn.extension("tabulator")


class AnnotationCard(pn.viewable.Viewer, pn.viewable.Layoutable):

    title = param.String(default="Annotations")
    df_annotations = param.DataFrame() 
    editors = param.Dict()
    initialdir = param.String(default=".")
    new_row = param.Dict()
    table_widths = param.Dict(default={})
    table_show_index = param.Boolean(default=False)
    table_height = param.Integer(default=207)
    table_layout = param.Selector(
        default="fit_data_fill",
        objects=["fit_columns", "fit_data", "fit_data_stretch", "fit_data_fill", "fit_data_table"],
    )
    table_pagination = param.Selector(default="local", objects=[None, "local", "remote"])
    table_page_size = param.Integer(default=5)
    add = param.Event()
    delete = param.Event()

    def __init__(self, editors, **params):
        df_annotations = pd.DataFrame([], columns=list(editors.keys()))
        new_row = params.get(
            "new_row",
            {
                k: 0
                if isinstance(v, dict) and v["type"] == "number"
                else v.options[0]  # type: ignore
                if isinstance(v, SelectEditor)
                else ""
                for k, v in editors.items()
            },
        )
        super().__init__(editors=editors, df_annotations=df_annotations, new_row=new_row, **params)
        self._annotations_table = pn.Param(
            self,
            parameters=["df_annotations"],
            widgets={
                "df_annotations": {
                    "type": pn.widgets.Tabulator,
                    "editors": self.editors,
                    "widths": self.table_widths,
                    "show_index": self.table_show_index,
                    "height": self.table_height,
                    "layout": self.table_layout,
                    "pagination": self.table_pagination,
                    "page_size": self.table_page_size,
                    "selectable": "checkbox",
                    "sizing_mode": "stretch_width",
                    "margin": 2,
                }
            },
            show_name=False,
        )[0]
        self._add_button = pn.widgets.Button(name="add", width=30, height=30,button_type = "primary")
        self._add_button.param.watch(lambda evt: self.param.trigger("add"), ["clicks"])
        self._remove_button = pn.widgets.Button(name="detete", width=30, height=30, button_type = "primary")
        self._remove_button.param.watch(lambda evt: self.param.trigger("delete"), ["clicks"])

    @param.depends("add", watch=True)
    def _add_row(self):
        assert isinstance(self._annotations_table.value, pd.DataFrame)
        self._annotations_table.value = self._annotations_table.value.append(
            self.new_row, ignore_index=True
        )

    @param.depends("delete", watch=True)
    def _delete_row(self):
        assert isinstance(self._annotations_table.value, pd.DataFrame)
        self._annotations_table.value = self._annotations_table.value.drop(
            self._annotations_table.selection
        ).reset_index(drop=True)

    def __panel__(self):
        return pn.Card(
            pn.Row(self._add_button, self._remove_button),
            self._annotations_table,
            title=self.title,
            collapsed=False,
            **{
                k: self.param.inspect_value(k)
                for k in pn.viewable.Layoutable.param.params().keys()  # type: ignore
                if k not in ["css_classes", "name"]
            }
        )

editors = {
    "start": {"type": "number"},
    "end": {"type": "number"},
    "type": SelectEditor(options=["Standard", "Outlier"]),
    "use": SelectEditor(options=["Train", "Test", "Train&Test", "No Use"]),
}
ac = AnnotationCard(editors, sizing_mode="stretch_width")
template = pn.template.FastListTemplate()
ac = AnnotationCard(editors, sizing_mode="stretch_width", table_height=207, margin=(0,-7,0,5))
template.sidebar.append(ac)
template.show()

col_refresh

xavArtley avatar Oct 24 '22 09:10 xavArtley

Doing so would unfortunately be very expensive.

philippjfr avatar Aug 02 '24 11:08 philippjfr