-
Notifications
You must be signed in to change notification settings - Fork 116
Description
[I'd like to have access to the selected rows]
Good news...
With a combination of
py-shiny/shiny/render/_data_frame.py
Lines 405 to 412 in 3b742a2
| @reactive.calc | |
| def self__input_data_view_indices() -> list[int]: | |
| data_view_indices = self._get_session().input[ | |
| f"{self.output_id}_data_view_indices" | |
| ]() | |
| return data_view_indices | |
| self._input_data_view_indices = self__input_data_view_indices |
py-shiny/shiny/render/_data_frame.py
Lines 492 to 502 in 3b742a2
| cell_selection = self.input_cell_selection() | |
| if cell_selection is not None and cell_selection["type"] == "row": | |
| # Use a `set` for faster lookups | |
| selected_row_indices_set = set(cell_selection["rows"]) | |
| # Subset the data view indices to only include the selected rows | |
| data_view_indices = [ | |
| index | |
| for index in data_view_indices | |
| if index in selected_row_indices_set | |
| ] |
.data_view_indices(*, selected: bool = False)? (Similar to .data_view(*, selected: bool = False))
It could return a {rows: list[int], cols: list[int]} object containing all rows/cols being used (given selected value). We could add a type to describe how the values were selected, similar to the CellSelection type
py-shiny/shiny/render/_data_frame_utils/_selection.py
Lines 162 to 185 in 3b742a2
| class CellSelectionRow(TypedDict): | |
| type: Literal["row"] | |
| rows: ListOrTuple[int] | |
| class CellSelectionCol(TypedDict): | |
| type: Literal["col"] | |
| cols: ListOrTuple[int] | |
| class CellSelectionRect(TypedDict): | |
| type: Literal["rect"] | |
| # Attempt to type the list of size 2, but it is not type enforced | |
| rows: tuple[int, int] | Annotated[list[int], 2] | |
| cols: tuple[int, int] | Annotated[list[int], 2] | |
| # For receiving selection info from JS: | |
| CellSelection = Union[ | |
| CellSelectionRow, | |
| CellSelectionCol, | |
| CellSelectionRect, | |
| CellSelectionNone, | |
| ] |
For the return value, I still don't know if rows and cols should always exist (containing all values). If they always exist, it is easier to code as a user. If they do not exist, it is much clearer as to what is being subsetted but more annoying to integrate with as a user. I'm currently leaning towards always including rows and cols containing all values being used. Ex: multi row selection would return {type: "row", rows: [1,3,5], cols: [0,1,2,3,4,5]} assuming we selected rows 1, 3, and 5 and there were 6 columns.
class DataViewIndices(TypedDict):
type: Literal["row", "col", "rect", "none"]
rows: ListOrTuple[int]
cols: ListOrTuple[int]
# class data_frame...
def data_view_indices(self, *, selected: bool = False) -> DataViewIndices:
...@pstorozenko Glad you like .data_view()!
It's not a problem for now, but if one day we shiny switches to some dataframe representation without creature like
pd.Indexit may be.
Can I get a copy of your crystal ball? 😆
I'd love to move to something like https://github.com/data-apis/dataframe-api-compat , however to get typing support, their typing specification is defined deep within another repo: https://github.com/data-apis/dataframe-api/tree/main/spec/API_specification/dataframe_api .
I do not understand why the types being used within dataframe-api-compat are not shipped with the package. /rant
Originally posted by @schloerke in #1345 (comment)