예제 #1
0
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)