Streamlit component - Card with "progress" bar showing min and max values

Hello, everyone!
Any tips on how to implement a card with the following structure?

image

Basically I need to show a card with a progress bar, But I’d like to display the min and max values (100 and 15000 based on the example above) of this variable (it changes depending on the filters applied to the app), but also i need to show where the actual result stands (the 70% number) compared to this range of values.

I’ve tried to use st.metric or st.progress but couldn’t achieve the result i would like to. I would really apprecite any help. Thanks in advance!

Hi @Gabriel21,

Thanks for posting!

You can use custom CSS to achieve this functionality. Here’s a sample code for it:

# Your min and max values
min_val = 0
max_val = 100  # 100 iterations for simplicity

# Create a placeholder for the progress bar and text
progress_bar = st.empty()
progress_text = st.empty()

# Call the simulated data processing function
process_data()  
    
# Calculate the percentage for the progress bar
percentage = current_val / max_val
  
# Update the progress bar with the current percentage
progress_bar.progress(percentage)
  
# Update the text under the progress bar to show min, current, and max values
progress_style = f"""
<div style="
    display: flex;
    justify-content: space-between;
    align-items: center;">
    <span>0</span>
    <span style="position: absolute; left: {percentage * 100}%; transform: translateX(-50%);">{current_val}%</span>
    <span>100</span>
</div>
"""
progress_text.markdown(progress_style, unsafe_allow_html=True)

The progress bar will look like this:

ezgif.com-video-to-gif (1)

Hello @tonykip, thank you for your reply!
I have tried this way, but got the following results:

The position of the “blue tick” on the bar seems to be ok (representing 80% of the totals), but the labels didn’t get the min and max values (0 and 10000). Also, the % label = 8000%. Is there any way to solve that too?

Thank you once again

The min_val and max_val should be on at the start and end of the bar and not be affected by the percentage calculations. You can modify it as such to have both the current value and percentage show up on the progress bar:

progress_style = f"""
<div style="
    display: flex;
    justify-content: space-between;
    width: 100%;">
    <span>{min_val}</span>
    <span style="position: absolute; left: {percentage * 100}%; transform: translateX(-50%);">
        {current_val} ({percentage * 100:.1f}%)
    </span>
    <span>{max_val}</span>
</div>
"""

Thats great, exactly what i needed!
Thank you very much, @tonykip

1 Like

Awesome! Glad it worked.

Happy Streamlit-ing!:balloon: