✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
⚡️ Concerned about the grid? Kyle Baranko teaches how to predicting peak loads using XGBoost. Register for the August webinar!

Dash Data Table working with Icons in new row

I am building an app that shows some tables with Icons. Actually i am fetching csv files with values:

Task Name,Main Concept,Solutions,Duration,Difficulty,Priority
Ueb01,Variables,2,20,5,4

For the Difficulty value i have choosen the fire icon. This works for initial rendering:

df_tasks['Difficulty'] = df_tasks['Difficulty'].apply(lambda x:
        '🔥🔥🔥🔥🔥' if x == 5 else (
        '🔥🔥🔥🔥' if x == 4 else (
        '🔥🔥🔥' if x == 3 else (
        '🔥🔥' if x == 2 else (
        '🔥' if x == 1 else ''
    )))))

I can also add new rows with the variable:

emptyTaskRow = {'Task Name': '','Main Concept': '','Solutions': 0,'Duration': 0, 'Difficulty': '🔥','Priority': 1}

@app.callback(
    Output('table-tasks', 'data'),
    [Input('editing-taskrows-button', 'n_clicks')],
    [State('table-tasks', 'data'),
     State('table-tasks', 'columns')])
def add_row(n_clicks, rows, columns):
    if n_clicks > 0:
        rows.append(emptyTaskRow)
    return rows

My problem actually is, i need to manipulate the table e.g. typing a 3 into a cell -> and three Fire Icons appears.

style_data_conditional works well for background color, if you want to have a heatmap-like table.
But how to solve this with Icons?

Hi @wollewolf42 and welcome to the Dash Plotly forum!

As an example to help you get started, here is the editable table from the Dash tutorial with flames added: https://dash.plotly.com/datatable/editable

# -*- coding: utf-8 -*-

import dash
from dash.dependencies import Input, Output, State
import dash_table
import dash_html_components as html

app = dash.Dash(__name__)

app.layout = html.Div([
    dash_table.DataTable(
        id='computed-table',
        columns=[
            {'name': 'Input Data', 'id': 'input-data'},
            {'name': 'Input Squared', 'id': 'output-data'},
            {'name': 'Difficulty', 'id': 'Difficulty'}
        ],
        data=[{'input-data': i} for i in range(11)],
        editable=True,
    ),
])


@app.callback(
    Output('computed-table', 'data'),
    [Input('computed-table', 'data_timestamp')],
    [State('computed-table', 'data')])
def update_columns(timestamp, rows):
    for row in rows:
        try:
            row['output-data'] = float(row['input-data']) ** 2
            row['Difficulty'] = '🔥' * int(row['input-data'])
        except:
            row['output-data'] = 'NA'
     
    return rows


if __name__ == '__main__':
    app.run_server(debug=True)

1 Like

Hi @AnnMarieW thank you!

Thanks a lot, this solution looks quite nice. I tried to use dropdown instead,
but i will try yours.

For some reason, if i use dropdown options, the other cells are not editable anymore :smiley:

Hi @wollewolf42

Actually having the flames as a dropdown in the table is an even better idea, since it will keep the ratings within a valid range. Here is a version where the table is still editable and the Difficulty column is a dropdown:

import dash
from dash.dependencies import Input, Output, State
import dash_table
import dash_html_components as html

app = dash.Dash(__name__)

app.layout = html.Div([
    dash_table.DataTable(
        id='computed-table',
        columns=[
            {'name': 'Input Data', 'id': 'input-data', },
            {'name': 'Input Squared', 'id': 'output-data'},
            {'name': 'Difficulty', 'id': 'Difficulty', 'presentation': 'dropdown'}
        ],
        data=[{'input-data': i} for i in range(11)],
        editable=True,
        dropdown={
            'Difficulty': {
                'options': [
                    {'label': '🔥' * i, 'value': i}
                    for i in range( 6)
                ]
            },
        }
    ),
])


@app.callback(
    Output('computed-table', 'data'),
    [Input('computed-table', 'data_timestamp')],
    [State('computed-table', 'data')])
def update_columns(timestamp, rows):
    for row in rows:
        try:
            row['output-data'] = float(row['input-data']) ** 2           
        except:
            row['output-data'] = 'NA'
     
    return rows


if __name__ == '__main__':
    app.run_server(debug=True)
1 Like

Hi, thanks a lot. The dropdown version works very well, i will use this solution for all my tables :slight_smile:

1 Like