예제 #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)
예제 #2
0
def test_format_escape_html(escape, exp):
    chars = '<>&"%$#_{}~^\\~ ^ \\ '
    df = DataFrame([[chars]])

    s = Styler(df, uuid_len=0).format("&{0}&", escape=None)
    expected = f'<td id="T__row0_col0" class="data row0 col0" >&{chars}&</td>'
    assert expected in s.to_html()

    # only the value should be escaped before passing to the formatter
    s = Styler(df, uuid_len=0).format("&{0}&", escape=escape)
    expected = f'<td id="T__row0_col0" class="data row0 col0" >&{exp}&</td>'
    assert expected in s.to_html()

    # also test format_index()
    styler = Styler(DataFrame(columns=[chars]), uuid_len=0)
    styler.format_index("&{0}&", escape=None, axis=1)
    assert styler._translate(True, True)["head"][0][1]["display_value"] == f"&{chars}&"
    styler.format_index("&{0}&", escape=escape, axis=1)
    assert styler._translate(True, True)["head"][0][1]["display_value"] == f"&{exp}&"
예제 #3
0
def test_format_with_precision(precision, expected):
    # Issue #13257
    df = DataFrame([[1.0, 2.0090, 3.2121, 4.566]], columns=[1.0, 2.0090, 3.2121, 4.566])
    styler = Styler(df)
    styler.format(precision=precision)
    styler.format_index(precision=precision, axis=1)

    ctx = styler._translate(True, True)
    for col, exp in enumerate(expected):
        assert ctx["body"][0][col + 1]["display_value"] == exp  # format test
        assert ctx["head"][0][col + 1]["display_value"] == exp  # format_index test
예제 #4
0
def test_format_escape_na_rep():
    # tests the na_rep is not escaped
    df = DataFrame([['<>&"', None]])
    s = Styler(df, uuid_len=0).format("X&{0}>X", escape="html", na_rep="&")
    ex = '<td id="T__row0_col0" class="data row0 col0" >X&&lt;&gt;&amp;&#34;>X</td>'
    expected2 = '<td id="T__row0_col1" class="data row0 col1" >&</td>'
    assert ex in s.to_html()
    assert expected2 in s.to_html()

    # also test for format_index()
    df = DataFrame(columns=['<>&"', None])
    styler = Styler(df, uuid_len=0)
    styler.format_index("X&{0}>X", escape="html", na_rep="&", axis=1)
    ctx = styler._translate(True, True)
    assert ctx["head"][0][1]["display_value"] == "X&&lt;&gt;&amp;&#34;>X"
    assert ctx["head"][0][2]["display_value"] == "&"
예제 #5
0
def test_precision_zero(df):
    styler = Styler(df, precision=0)
    ctx = styler._translate(True, True)
    assert ctx["body"][0][2]["display_value"] == "-1"
    assert ctx["body"][1][2]["display_value"] == "-1"
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)