def _marshall_styler(proto: ArrowProto, styler: Styler, default_uuid: str) -> None: """Marshall pandas.Styler into an Arrow proto. Parameters ---------- proto : proto.Arrow Output. The protobuf for Streamlit Arrow proto. styler : pandas.Styler Helps style a DataFrame or Series according to the data with HTML and CSS. default_uuid : str If pandas.Styler uuid is not provided, this value will be used. """ # pandas.Styler uuid should be set before _compute is called. _marshall_uuid(proto, styler, default_uuid) # We're using protected members of pandas.Styler to get styles, # which is not ideal and could break if the interface changes. styler._compute() # In Pandas 1.3.0, styler._translate() signature was changed. # 2 arguments were added: sparse_index and sparse_columns. # The functionality that they provide is not yet supported. if type_util.is_pandas_version_less_than("1.3.0"): pandas_styles = styler._translate() else: pandas_styles = styler._translate(False, False) _marshall_caption(proto, styler) _marshall_styles(proto, styler, pandas_styles) _marshall_display_values(proto, styler.data, pandas_styles)
def render_style(style: Styler, **kwargs): style._compute() d = style._translate() cell_styles = [ x for x in d.pop('cellstyle') if any(any(y) for y in x["props"]) ] for cs in cell_styles: cs['selector'] = '.' + cs['selector'].replace('_', '.') cell_style_map = parse_styles(cell_styles) table_styles = d.pop('table_styles') table_style_map = parse_styles(table_styles) uuid = d.pop('uuid') """ # will not be used (table component arguments could be used instead) table_attributes = d.pop('table_attributes') # will not be used (small text after table could be done with bootstrap components) caption = d.pop('caption') # not used in template renderer at all precision = d.pop('precision') """ def apply_styles(column): # style priority (high to low): # 0. original cell style # 1. styles from 'cellstyle' # 2. styles from 'table_styles' tag_name = column.get('type', '') classes_str = column.get('class', '') origin_style = column.get('style', {}) tag = f'<{tag_name} class="{classes_str}"></{tag_name}>' element_tag = etree.fromstring(tag) styles_from_cell_style = [ props for sel, props in cell_style_map.items() if sel(element_tag) ] styles_from_table_style = [ props for sel, props in table_style_map.items() if sel(element_tag) ] res_styles = {} for style in styles_from_table_style: res_styles.update(style) for style in styles_from_cell_style: res_styles.update(style) for style in origin_style: if type(style) is dict: res_styles.update(style) column['style'] = res_styles return column head = [] for row in d.pop('head'): row_content = [] for column in filter(lambda c: c.get('is_visible', True), row): column = apply_styles(column) el = parse_val(**column) row_content.append(el) head.append(html.Tr(row_content)) head = html.Thead(head) body = [] for row in d.pop('body'): row_content = [] for column in filter(lambda c: c.get('is_visible', False), row): column = apply_styles(column) el = parse_val(**column) row_content.append(el) body.append(html.Tr(row_content)) body = html.Tbody(body) return dbc.Table([head, body], id=kwargs.pop('id', uuid), bordered=kwargs.pop('bordered', True), striped=kwargs.pop('striped', False), **kwargs)