Conditional Cell Formatiing

Hello Everybody,

I am trying to do conditional formatting for cells in a table but I don’t want it to be fixed as mentioned in the following tutorial:
https://dash.plot.ly/datatable/style

I want a variable color change wherein if I make changes to the data for a particular cell, the color for that specific cell should change, so on and so forth. is that possible?

Any responses would be appreciated.

I think you can, through the style_data_conditional parameter of DataTable.

I just tried it with the following simple code (adapted from the style page you reference). I made the table editable, and added a condition to change the color of the cell if it is in column a and its value is greater than 3. It worked.

Alternatively, you might have a callback function that modifies the cell values through the data property, and once you have the conditional formatting in place colors, fonts, etc. should change dynamically.

import dash
import dash_html_components as html
import pandas as pd
from dash_table import DataTable

df = pd.DataFrame({
    'a': [1, 2, 3, 4],
    'b': [5, 6, 7, 8],
    'c': [10, 20, 30, 40]
})

app = dash.Dash(__name__)

app.layout = html.Div([
    DataTable(id='table',
              editable=True,
              data=df.to_dict('records'),
              columns=[{'id': c, 'name': c} for c in df.columns],
              style_data_conditional=[
                  {
                      'if': {
                          'column_id': 'a',
                          'filter_query': '{a} gt 3'
                      },
                      'backgroundColor': '#3D9970',
                      'color': 'white',
                  },
              ])
])

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

Hope this works for you.

1 Like

Hello Elias,

Thank you for your response and the sample code. I could get through that, however in this case we are just talking about one condition for a column with a specific color.

What I am looking out for is,
for example:
One of the cell in my datatable is 25 and I change it to 35 or 50. When I press ‘tab’ or go to the next cell; the ‘change’ should be recognized by the cell and the color should immediately reflect.

I know this is really confusing but I hope I am making sense :slight_smile:

What you are describing is exactly what is happening with me with this code :slight_smile:
Unless I’m missing something? As I change values of column a to numbers greater than 3, the change is happening immediately (hitting TAB or moving to another cell), otherwise the cell stays the same.
You can add as many conditions (and types of conditions) as you want, affecting different aspects of the data (color, background, font size, etc.).

@eliasdabbas: what @swap700 is attempting to do is perform this conditional cell formatting on a per-cell basis - compared to the original value of the cell - vice comparing an entire column of values to determine which is > 3. I haven’t tried this before to offer a solution.

Thank you for the clarification @flyingcujo, it couldn’t have been portrayed better. That is actually what I am looking out for; just not sure how I would apply that logic in a datatable.

It would actually be a perfect visual experience like I have on the graph now.
Eg: When I change the data in the table, it reflects on the graph, I just want the same experience in the table by changing the cell color.

Please let me know if you try this and are successful.

Still looking for anyone who can help me with it.

If it’s only the case of cell vs. column, you can simply add a new condition, so the table tracks the value of a certain cell, without having to check the whole column. I just tried the same code with an additional line, that adds a condition for row_index. It worked for me :slight_smile:

                  {
                      'if': {
                          'column_id': 'a',
                          'row_index': 2,   # the only additional line
                          'filter_query': '{a} gt 3'
                      },
                      'backgroundColor': '#3D9970',
                      'color': 'white',
                  },

Please check and let me know if this is what you wanted.

@swap700 - looks like you can iterate over the rows/columns of your table to create a conditional for each cell based on the example provided by @eliasdabbas!

1 Like

Hello Elias,

Thank you for the input. However, it is still a specific cell.

My concern is not the cell, its the ‘filter query’ in this case which is ‘greater than 3’ whereas I am looking out for a ‘filter query’ which can detect ‘any’ change in the code.

Number change, operator functions, etc.

Hello @flyingcujo,

Could you help me out as to how would I be doing that?

This is a little crude and I wasn’t able to test it out but I think this will generate an appropriate style_cell_conditional. You could probably implement this a little better.

# Assume df_orig contains the original value of teh table, possibly stored via a dcc.Store component
df_orig = pd.DataFrame({
    'a': [1, 2, 3, 4],
    'b': [5, 6, 7, 8],
    'c': [10, 20, 30, 40]
})

# Generate the cell-wise conditional
style_cell_conditional = []

for col_id, value in df.iteritems(): 
    for row_id in range(len(value)):
        style_cell_conditional += [
            {
                'if': {
                    'column_id': col_id,
                    'row_index': row_id, 
                    'filter_query': '{' + col_id +'} ne {' + str(df_orig[col_id][row_id]) + '}'
                    },
                    'backgroundColor': '#3D9970',
                    'color': 'white',
            }
        ]
        
print(style_cell_conditional)

Thanks @flyingcujo,

I’ll check this and get back to you :crossed_fingers:t2: