Skip to content

Commit c1428de

Browse files
committed
decouple data model from DataGrid for selections
Signed-off-by: Itay Dafna <[email protected]>
1 parent 0b181cc commit c1428de

File tree

1 file changed

+40
-31
lines changed

1 file changed

+40
-31
lines changed

ipydatagrid/datagrid.py

Lines changed: 40 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -79,16 +79,18 @@ class SelectionHelper:
7979
to traverse selected cells.
8080
"""
8181

82-
def __init__(self, grid, **kwargs):
82+
def __init__(self, data, selections, selection_mode, **kwargs):
8383
super().__init__(**kwargs)
84-
self._grid = grid
84+
self._data = data
85+
self._selections = selections
86+
self._selection_mode = selection_mode
8587
self._num_columns = -1
8688
self._num_rows = -1
8789

8890
def __iter__(self):
8991
selections = [
9092
self._transform_rect_for_selection_mode(rect)
91-
for rect in self._grid.selections
93+
for rect in self._selections
9294
]
9395
return SelectionIterator(selections)
9496

@@ -108,12 +110,12 @@ def all_values(self):
108110
Returns values for all selected cells as a list.
109111
"""
110112
return [
111-
self._grid._get_cell_value_by_numerical_index(cell["c"], cell["r"])
113+
DataGrid._get_cell_value_by_numerical_index(self._data, cell["c"], cell["r"])
112114
for cell in self
113115
]
114116

115117
def _transform_rect_for_selection_mode(self, rect):
116-
selection_mode = self._grid.selection_mode
118+
selection_mode = self._selection_mode
117119
if selection_mode == "row":
118120
return {
119121
"r1": rect["r1"],
@@ -135,7 +137,7 @@ def _get_num_columns(self):
135137
if self._num_columns != -1:
136138
return self._num_columns
137139

138-
data = self._grid._data
140+
data = self._data
139141
primary_keys = (
140142
[]
141143
if "primaryKey" not in data["schema"]
@@ -153,7 +155,7 @@ def _get_num_rows(self):
153155
if self._num_rows != -1:
154156
return self._num_rows
155157

156-
data = self._grid._data
158+
data = self._data
157159
self._num_rows = 0 if "data" not in data else len(data["data"])
158160
return self._num_rows
159161

@@ -288,7 +290,7 @@ def __init__(self, dataframe, **kwargs):
288290
def __handle_custom_msg(self, _, content, buffers): # noqa: U101,U100
289291
if content["event_type"] == "cell-changed":
290292
row = content["row"]
291-
column = self._column_index_to_name(content["column_index"])
293+
column = DataGrid._column_index_to_name(self._data, content["column_index"])
292294
value = content["value"]
293295
# update data on kernel
294296
self._data["data"][row][column] = value
@@ -322,15 +324,8 @@ def data(self):
322324
final_df = final_df[final_df.columns[:-1]]
323325
return final_df
324326

325-
@data.setter
326-
def data(self, dataframe):
327-
guid_key = "ipydguuid"
328-
# Reference for the original frame column and index names
329-
# This is used to when returning the view data model
330-
self.__dataframe_reference_index_names = dataframe.index.names
331-
self.__dataframe_reference_columns = dataframe.columns
332-
333-
dataframe = dataframe.copy()
327+
@staticmethod
328+
def generate_data_object(dataframe, guid_key):
334329
dataframe[guid_key] = pd.RangeIndex(0, dataframe.shape[0])
335330
schema = pd.io.json.build_table_schema(dataframe)
336331
reset_index_dataframe = dataframe.reset_index()
@@ -364,12 +359,23 @@ def data(self, dataframe):
364359

365360
schema["primaryKeyUuid"] = guid_key
366361

367-
self._data = {
362+
363+
return {
368364
"data": data,
369365
"schema": schema,
370366
"fields": [{field["name"]: None} for field in schema["fields"]],
371367
}
372368

369+
@data.setter
370+
def data(self, dataframe):
371+
# Reference for the original frame column and index names
372+
# This is used to when returning the view data model
373+
self.__dataframe_reference_index_names = dataframe.index.names
374+
self.__dataframe_reference_columns = dataframe.columns
375+
dataframe = dataframe.copy()
376+
377+
self._data = DataGrid.generate_data_object(dataframe, "ipydguuid")
378+
373379
def get_cell_value(self, column_name, primary_key_value):
374380
"""Gets the value for a single or multiple cells by column name and index name.
375381
@@ -518,7 +524,7 @@ def selected_cells(self):
518524
List of selected cells. Each cell is represented as a dictionary
519525
with keys 'r': row and 'c': column
520526
"""
521-
return SelectionHelper(grid=self).all()
527+
return SelectionHelper(self._data, self.selections, self.selection_mode).all()
522528

523529
@property
524530
def selected_cell_values(self):
@@ -543,7 +549,7 @@ def selected_cell_iterator(self):
543549
"""
544550
An iterator to traverse selected cells one by one.
545551
"""
546-
return SelectionHelper(grid=self)
552+
return SelectionHelper(self._data, self.selections, self.selection_mode)
547553

548554
@validate("selections")
549555
def _validate_selections(self, proposal):
@@ -615,33 +621,35 @@ def on_cell_click(self, callback, remove=False):
615621
"""
616622
self._cell_click_handlers.register_callback(callback, remove=remove)
617623

618-
def _column_index_to_name(self, column_index):
619-
if "schema" not in self._data or "fields" not in self._data["schema"]:
624+
@staticmethod
625+
def _column_index_to_name(data, column_index):
626+
if "schema" not in data or "fields" not in data["schema"]:
620627
return None
621-
col_headers = self._get_col_headers()
628+
col_headers = DataGrid._get_col_headers(data)
622629
return (
623630
None
624631
if len(col_headers) <= column_index
625632
else col_headers[column_index]
626633
)
627634

628-
def _get_col_headers(self):
635+
@staticmethod
636+
def _get_col_headers(data):
629637
primary_keys = (
630638
[]
631-
if "primaryKey" not in self._data["schema"]
632-
else self._data["schema"]["primaryKey"]
639+
if "primaryKey" not in data["schema"]
640+
else data["schema"]["primaryKey"]
633641
)
634642
col_headers = [
635643
field["name"]
636-
for field in self._data["schema"]["fields"]
644+
for field in data["schema"]["fields"]
637645
if field["name"] not in primary_keys
638646
]
639647
return col_headers
640648

641649
def _column_name_to_index(self, column_name):
642650
if "schema" not in self._data or "fields" not in self._data["schema"]:
643651
return None
644-
col_headers = self._get_col_headers()
652+
col_headers = DataGrid._get_col_headers(self._data)
645653
try:
646654
return col_headers.index(column_name)
647655
except ValueError:
@@ -664,9 +672,10 @@ def _get_row_index_of_primary_key(self, value):
664672
]
665673
return row_indices
666674

667-
def _get_cell_value_by_numerical_index(self, column_index, row_index):
675+
@staticmethod
676+
def _get_cell_value_by_numerical_index(data, column_index, row_index):
668677
"""Gets the value for a single cell by column index and row index."""
669-
column = self._column_index_to_name(column_index)
678+
column = DataGrid._column_index_to_name(data, column_index)
670679
if column is None:
671680
return None
672-
return self._data["data"][row_index][column]
681+
return data["data"][row_index][column]

0 commit comments

Comments
 (0)