How to add increase or decrease arrow in div component based on value of html.Span in dash webapp?

Hi!
I am new to dash and python in general. I am trying to add a green up or red down arrow to indicate an increase or decrease based on a value that is in an html.Span component.

My div looks like this

1

and I want it to become like this for instant in case the popularity is +ve. and down red arrow in case it is -ve

2

Basically the popularity is a change rate that is already calculated in my dataframe. Depending on user selection of a value , the popularity value changes based on the selected filters.

Below is the code that generates this component

 html.Div(children=
           [html.Span('Popularity', style={'font-size':'19px','color':'#212121',
                                                     'display':'flex','justify-content':'center',
                                                     'padding':'15px 0px 0px 0px'}),

            html.Br(),
            html.Br(),
            html.Span(id='pop_chgrate',children=[f'{pop_chgrate} %'],style={'color':'black','font-size':'30px',
                                                                           'padding':'15px 5px 0px 10px'}),
            html.Br(),
            html.Span(' increase in Likes and Retweets vs last month.',style={'font-size':'18px', 
                                                                              'padding':'35px 10px 0px 10px'})
            
           ],
           style={'width':'230px','height':'268px','border':'1px solid lightgrey', 'borderRadius':'15px',
                  'borderWidth':'1px','box-shadow': '2px 2px 2px lightgrey','display':'inline-block',
                  'margin':'10px 0px 0px 42px'}
          )

Does anyone know how to add this increase or decrease indicator? or any equivalent thing?

Thanks.

1 Like

Hi @Moo

You coulde replace the line below with a plotly indicator chart

html.Span(id='pop_chgrate',children=[f'{pop_chgrate} %'],style={'color':'black','font-size':'30px',
                                                                           'padding':'15px 5px 0px 10px'}),

fig = go.Figure(
    go.Indicator(
        mode="delta",
        value=112,
        delta={"reference": 100, "relative": True},
    )
)
fig.update_layout(
    margin=dict(l=0, r=0, t=0, b=0),
)
dcc.Graph(figure=fig, style={"height": 50, "width": 100}),

image

You might also like to try dash-boostrap-components It makes styling an app easier. For example, here’s what the card could look like:

import dash
from dash import dcc, html
import plotly.graph_objects as go
import dash_bootstrap_components as dbc


fig = go.Figure(
    go.Indicator(
        mode="delta",
        value=90,
        delta={"reference": 100, "relative": True},
    )
)
fig.update_layout(
    margin=dict(l=0, r=0, t=0, b=0),
)


app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])

card = dbc.Card(
    [
        html.H4("Popularity"),
        dcc.Graph(figure=fig, style={"height": 50, "width": 100}),
        html.Div("increase in Likes and Retweets vs last month"),
    ],className="shadow m-4 p-4", style={"width": "18rem"}
)

app.layout=dbc.Container(card)

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


image

3 Likes

Hey @Moo

Here’s another cool option using the Dash Iconify library

You could change the color and rotate props of the arrow in a callback depending on the value.

image
image


from dash_iconify import DashIconify
from dash import Dash, html

app = Dash(__name__)

arrow= DashIconify(
    id="arrow",
    icon="el:arrow-up",
    width=30,
    color="green",
    height=30,
    rotate=0,
)

pop_chgrate = 112
stats = (
    html.Span(
        id="pop_chgrate",
        children=[f"{pop_chgrate} %", arrow],
        style={"color": "black", "font-size": "30px", "padding": "15px 5px 0px 10px"},
    )
)


app.layout = html.Div(stats)

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


Thanks a lot @AnnMarieW !
the iconify one printed a static up arrow that doesn’t change to the red one in case the value changed.
But the first solution worked perfectly ! :tada: