ipydatagrid
ipydatagrid copied to clipboard
Come with an automatic way of setting the minimum grid size
Seems we generate extra space at the bottom of short grids:
FWIW I just checked on the binder link provided by the repo and I get the same effect, so at least you should be able to reproduce it easily...
We do have a workaround for it:
The issue you are seeing with the blank space is the default canvas size. We don't have an intelligent way (yet) of determining a good default size for a given grid, so they all have the same one, and I agree it does look a bit odd for smaller grids. The good news is that this is a layout property and as such you pass it as a parameter to the grid constructor:
from ipydatagrid import DataGrid
import pandas as pd
df = pd.DataFrame({"A":[1,2,3], "B":[4,5,6]})
grid = DataGrid(df, layout={"height":"120px", "width":"200px", "align-content":"center"})
grid
This issue is to track in finding an automated way of setting the grid size to a just-right size.
I have a solution to this.
from copy import deepcopy
from ipydatagrid import DataGrid
class DataGrid2(DataGrid):
_max_width = 576
_max_height = 600
_adjustment = 25
def __init__(self, dataframe, **kwargs):
if "index_name" in kwargs:
self._index_name = kwargs["index_name"]
else:
self._index_name = None
self._first_call = True
self._layout_init = kwargs.get('layout', {})
self.data = dataframe
df = self.data
kwargs = self.auto_resize_grid(df, **kwargs)
super().__init__(dataframe, **kwargs)
def auto_resize_grid(self, data, **kwargs):
df = data
max_width = kwargs.pop('max_width', self._max_width)
max_height = kwargs.pop('max_height', self._max_height)
adjustment = kwargs.pop('adjustment', self._adjustment)
column_widths = kwargs.get('column_widths', {})
base_row_size = kwargs.get('base_row_size', 20)
base_column_size = kwargs.get('base_column_size', 64)
base_row_header_size = kwargs.get('base_row_header_size', 64)
base_column_header_size = kwargs.get('base_column_header_size', 20)
index_names = [*df.index.names]
index_size = np.sum([column_widths.get(v, base_row_header_size) for v in index_names])
columns_size = np.sum([column_widths.get(v, base_column_size) for v in df.columns])
print(column_widths)
print([column_widths.get(v, base_column_size) for v in df.columns])
width = index_size + columns_size + adjustment
height = len(df) * base_row_size + df.columns.nlevels * base_column_header_size + adjustment
layout = kwargs.pop('layout', {})
lo_width = layout.get('width', f"{width if width < max_width else ''}px")
lo_height = layout.get('height', f"{height if height < max_height else ''}px")
if lo_width != 'px':
layout['width'] = lo_width
if lo_height != 'px':
layout['height'] = lo_height
layout["align-content"] = "center"
kwargs['layout'] = layout
return kwargs
@DataGrid.data.setter
def data(self, dataframe):
# Reference for the original frame column and index names
# This is used to when returning the view data model
self.__dataframe_reference_index_names = dataframe.index.names
self.__dataframe_reference_columns = dataframe.columns
dataframe = dataframe.copy()
# Primary key used
index_key = self.get_dataframe_index(dataframe)
self._data = self.generate_data_object(
dataframe, "ipydguuid", index_key
)
if not self._first_call:
kwargs = self.auto_resize_grid(
self.data,
column_widths=self.column_widths,
base_row_size=self.base_row_size,
base_column_size=self.base_column_size,
base_row_header_size=self.base_row_header_size,
base_column_header_size=self.base_column_header_size,
layout=deepcopy(self._layout_init)
)
self.layout = kwargs['layout']
else:
self._first_call = False