Dashtable integer to hh:mm format

Hello,
i`m having a problem where i can’t format my output of my dash datatable so that an integer such as 90 can be displayed as ‘01:30’ in my dashtable. i am also using the databars function of the dashtable conditional formating documentation, so i can’t convert my data before inserting it into the layout data.
i have tried converting columns inside the databars function and reverting it afterwards and i have tried working with the datetime datatype, aswell as creating seperate tables so that my function is independent of my table but it doesn’t seem to work.

Can someone explain to me why the formatting of the databars function doesnt apply to my string-datatype table or describe how i could format the output.

    app = Dash(__name__)

    def data_bars(dfs, columns):
    styles = []
    columns = columns.tolist()
    

    for column in columns:
        n_bins = 100
        bounds = [i * (1.0 / n_bins) for i in range(n_bins + 1)]
        ranges = [
            ((dfs[column].max() - dfs[column].min()) * i) + dfs[column].min()
            for i in bounds
        ]
        for i in range(1, len(bounds)):
            min_bound = ranges[i - 1]
            max_bound = ranges[i]
            max_bound_percentage = bounds[i] * 100
            styles.append({
                'if': {
                    'filter_query': (
                        '{{{column}}} >= {min_bound}' +
                        (' && {{{column}}} < {max_bound}' if (i < len(bounds) - 1) else '')
                    ).format(column=column, min_bound=min_bound, max_bound=max_bound),
                    'column_id': column
                },
                'background': (
                    """
                        linear-gradient(90deg,
                        #d90f19 0%,
                        #d90f19 {max_bound_percentage}%,
                        white {max_bound_percentage}%,
                        white 100%)
                    """.format(max_bound_percentage=max_bound_percentage)
                ),

                'paddingBottom': 2,
                'paddingTop': 2
            })

    return styles

    app.layout = html.Div([
    html.H4('Simple interactive table'),
    html.P(id='table_out'),
    dash_table.DataTable(
      id='table',
      columns=[{"name": i, "id": i, "type": "numeric"}
               for i in table_rdy.columns],
      data=table_rdy.to_dict('records'),
      style_cell=dict(textAlign='left', fontWeight= 'bold'),
      style_header=dict(backgroundColor="paleturquoise"),
      style_data=dict(backgroundColor="lavender"),

  
      style_data_conditional=(data_bars(table_rdy, table_rdy.columns) + [{'if': {'column_type':'numeric'},'text_align': 'right',}])

    ),
    ])

    @app.callback(
    Output('table_out', 'children'),
    Input('table', 'active_cell'))
    def update_graphs(active_cell):
    if active_cell:
      cell_data = table_rdy.iloc[active_cell['row']][active_cell['column_id']]
      cell_data2 = 'l'
      return f"Data: \"{cell_data}\",\"{cell_data2}\" from table cell: {active_cell}"
    return "Click the table"

    app.run_server( port = 8090, dev_tools_ui=True, #debug=True,
            dev_tools_hot_reload =True, threaded=True)

    def table_to_time (tab):
        copy_tab = tab[:]
        for column in copy_tab.columns:
     
                x = copy_tab[column].div(60).astype(int).apply(str).str.zfill(2)
                y = copy_tab[column].mod(60).astype(int).apply(str).str.zfill(2)
                copy_tab[column]= (x + ':' + y)


         return copy_tab



    def table_to_int (tab):
        copy_tab = tab[:]
        for column in copy_tab.columns:
        
                z= copy_tab[column].str.partition(':')
                x= pd.to_numeric(z[0])
                y= pd.to_numeric(z[2])

                copy_tab[column]= x*60 +y


        return copy_tab

Hello @eliastraesser,

Is there a reason you cant use the data_bars function before you are creating the table? ie. Store the styling as a dictionary, and then pass that during the table creation.

That way, you can format the data however you need to in order to get the data to be more along the lines of how you want to display it.

Hello jinnzyor,

thanks for the answer.
How would storing the databars styling as a dictionary work in your idea?
I understand what you mean to do, but i still have the problem that as soon as i convert my original table i no longer output the background styling ( so the databars themselves) in my new table .

Sure… Do you have any data that I can use for “table_rdy”?

Hello Jinnzyor, this is a new minimal reproductive problem: you should be able to copy this as a whole and have the table with bars without hh:mm format.

from jupyter_dash import JupyterDash
from collections import OrderedDict
from dash import Dash, dash_table
import pandas as pd
data = OrderedDict(
    [
        ("Temperature", [1, 20, 34, 4, 10423, 441]),
        ("Humidity", [10, 20, 30, 40, 50, 60]),
        ("Pressure", [2, 1094, 392, 10, 391, 15]),
    ]
)
df= pd.DataFrame(data)

app = JupyterDash(__name__)
def data_bars(df, column):
    n_bins = 100
    bounds = [i * (1.0 / n_bins) for i in range(n_bins + 1)]
    ranges = [
        ((df[column].max() - df[column].min()) * i) + df[column].min()
        for i in bounds
    ]
    styles = []
    for i in range(1, len(bounds)):
        min_bound = ranges[i - 1]
        max_bound = ranges[i]
        max_bound_percentage = bounds[i] * 100
        styles.append({
            'if': {
                'filter_query': (
                    '{{{column}}} >= {min_bound}' +
                    (' && {{{column}}} < {max_bound}' if (i < len(bounds) - 1) else '')
                ).format(column=column, min_bound=min_bound, max_bound=max_bound),
                'column_id': column
            },
            'background': (
                """
                    linear-gradient(90deg,
                    #0074D9 0%,
                    #0074D9 {max_bound_percentage}%,
                    white {max_bound_percentage}%,
                    white 100%)
                """.format(max_bound_percentage=max_bound_percentage)
            ),
            'paddingBottom': 2,
            'paddingTop': 2
        })

    return styles

app.layout = dash_table.DataTable(
        id='table',
        columns=[{'name': i, 'id': i} for i in df.columns],
        data= df.to_dict('records'),
        style_data_conditional=(data_bars(df,'Temperature')+
                                data_bars(df,'Humidity')+
                                data_bars(df,'Pressure'))
    )
if __name__ == '__main__':
    app.run_server()

Hey @eliastraesser,

Is this what you are supposed to be seeing?

I run your code, and that’s what I see.

If it’s what you are supposed to see, then consider updating your versions? XD

yes that’s what my output looks like aswell and there i want to have 00:01 instead of 1 and 00:10 instead of 10 , 07:21 instead of 441 etc.

1 Like