CompositeFormatter for DataTable objects

The objective is to create a DataTable with numeric and text columns and be able to set a consistent (larger) font size in all columns. This previous PR describes a CompositeFormatter object that would enable a list of formatters, eg a HTMLTemplateFormatter and a NumberFormatter, however I’m not finding the CompositeFormatter object anywhere currently (bokeh 3.4.0). A minimal example and app screenshot are below, you can see the issue is the different column font sizes. As a related issue, is my code in the minimal example to set the column title font size the cleanest way to do that? Thanks again for the excellent support here!

from bokeh.io import curdoc
from bokeh.models import DataTable, TableColumn, HTMLTemplateFormatter, NumberFormatter, ColumnDataSource

c1 = TableColumn(width=100, field='text',
    formatter=HTMLTemplateFormatter(template=f"""<div style="font-size:18px;"><%=value%></div>"""),
    title=f"""<div style="font-size:18px;">text</div>""")

c2 = TableColumn(width=100, field='num',
    formatter=NumberFormatter(format=f'0,0.0'),
    title=f"""<div style="font-size:18px;">num</div>""")

cds = ColumnDataSource({
    'text': ['a','b','c','d'],
    'num': [1,2,3,4]})

table = DataTable(width=200, height=200, index_position=None, columns=[c1, c2], sortable=True, source=cds)

curdoc().add_root(table)

app screenshot
2024-04-03_9-39-41

The referenced PR was declined and never merged due to the author disappearing while a review was ongoing. Since the PR was submitted without a corresponding issue, I’d actually suggest opening as GitHub Issue to actually record a request for the feature, as otherwise it’s not likely to be revisited. Please include full details (links to this discussion and the earlier PR) as well as examples of the code you would like to be able to write.

FWIW, my setup is to make a function that I call to retrieve the “standard” formatting I want, with the option of adding additional styling content:

def get_html_formatter(style_string):
    template = '<div '+style_string+'''>
            
            <%=(function fm(v){
                if (typeof v == 'number'){
                        if (v % 1 == 0){
                                return v.toFixed(0)}
                        else {return v.toFixed(2)}}
                else {return value}
            }(value))%>
            </div>
            '''
    return HTMLTemplateFormatter(template=template)


cols = [TableColumn(field=k,title=k,formatter=get_html_formatter(style_string='')) for k in src.data.keys()]

The one above will round numbers to 2 decimals. I’ll add additional styling like conditional formatting etc. using the style_string arg. This makes it a little less clunky/repetitive at least.

Hi @gmerritt123 and thanks for the comment. My application uses the sortable feature of the DataTable object. The issue I found with string formatting of numbers is the sorted order can be wrong, eg if 72.3, 7.1, 23.7 are three numbers in a column. Would your approach sort those numbers (descending) as 72.3, 23.7, 7.1 or as the order in the prev list?

See GitHub Issue 13796

1 Like