panel icon indicating copy to clipboard operation
panel copied to clipboard

Tabulator does not resize to fit content

Open MarcSkovMadsen opened this issue 3 years ago • 1 comments

panel==0.13.1

I am trying to help a user of Panel here https://discourse.holoviz.org/t/switching-between-tabulators-trims-the-table-when-it-contains-images/4257. He wants to show images in Tabulator.

The issue is that Tabulator does not show these nicely on a first render. But if I change a widget value it does.

https://user-images.githubusercontent.com/42288570/190558980-39aa570f-7c61-4b19-ac70-2e39bcaceca3.mp4

import pathlib

import pandas as pd
import panel as pn
from PIL import Image, ImageDraw

pn.extension("tabulator")

ROOT = pathlib.Path(__file__).parent
N = 5

def image_path(stage, i)->pathlib.Path:
    return ROOT/f"assets/demo_images/Image{stage}_{i + 1}.png"

def create_images():
    for stage in ["A","B"]:
        for i in range(N):
            path = image_path(stage, i)
            if not path.exists():

                img = Image.new('RGB', (200, 200), color = (73, 109, 137))
            
                d = ImageDraw.Draw(img)
                d.text((20,20), "Hello World", fill=(255,255,0))
                path.parent.mkdir(exist_ok=True, parents=True)
                img.save(path)

create_images()

def create_report(stage):
    demo_df = pd.DataFrame(
        data={
            'Steps': [f'Step {stage}{i + 1}' for i in range(N)],
            'Actions': [f'Perform step {stage}{i + 1}' for i in range(N)],
            'Images': [f'assets/demo_images/Image{stage}_{i + 1}.png' for i in range(N)],
        },
        index=[i + 1 for i in range(N)]
    )

    tabulator_formatters = {
        'Images': {'type': 'image'}
    }

    df_table = pn.widgets.Tabulator(
        demo_df,
        header_align='center',
        text_align='center',
        selectable=False,
        theme='simple',
        formatters=tabulator_formatters,
        show_index=False,
    )

    stage_report = pn.Column(
        f'## Report stage {stage}',
        df_table
    )

    return stage_report


select = pn.widgets.Select(name='Select stage', options=['A', 'B'])
report = pn.bind(create_report, stage=select)

template = pn.template.FastListTemplate(
    site="Staging reports",
    title="",
    theme_toggle=False,
    header_background="rgb(95,158,209)",
    sidebar=[select],
    main=[report]
)

template.servable()

panel serve 'script.py' --auto --static-dirs assets=assets

Additional Context

I've posted a workaround on the discourse site.

MarcSkovMadsen avatar Sep 16 '22 04:09 MarcSkovMadsen

The problem is that images load after the sizing calculation happens. Will assign to 1.0 with the hope that the new layout engine handles this better.

philippjfr avatar Sep 16 '22 11:09 philippjfr

Indeed fixed in 1.0

philippjfr avatar Mar 08 '23 20:03 philippjfr