Skip to content

Add stacked flag for MultiLineProgress, so that the bars stack instead of overwriting - #40

Open
Archer6621 wants to merge 1 commit into
Exahilosys:mainfrom
Archer6621:stacked-multilineprogress
Open

Add stacked flag for MultiLineProgress, so that the bars stack instead of overwriting#40
Archer6621 wants to merge 1 commit into
Exahilosys:mainfrom
Archer6621:stacked-multilineprogress

Conversation

@Archer6621

@Archer6621 Archer6621 commented May 18, 2026

Copy link
Copy Markdown

My use case for the MultiLineProgress bar is one where I keep track of different results for the same process, e.g. succeeded versus failed, or perhaps even more. In this case, I always expect the same total amount of items, but each item might get a different label depending on the result. Currently, the progress lines all get written to index 0 on the main bar (useful for e.g. pipeline steps where each bar represents a step that all items have to go through), causing them to overwrite one another for this particular use case.

I'm proposing a flag stacked=True/False where when it is True, the control progress lines get stacked; each one writes where the previous line had ended. This way, when all items are processed and have received a label, the lines will fill the bar fully in the correct proportions.

Decided to go ahead and implement/PR it, since it is a very minor modification.

@Exahilosys

Copy link
Copy Markdown
Owner

To stack lines, simply nest the context managers!

import survey
import time

total = 1600

controls = [
    survey.graphics.MultiLineProgressControl(1600, color = survey.colors.basic('blue' ), epilogue = 'done!'),
    survey.graphics.MultiLineProgressControl(1600, color = survey.colors.basic('red'  )),
    survey.graphics.MultiLineProgressControl(1600, color = survey.colors.basic('green'), epilogue = lambda context: 'dynamic done!')
]

with survey.graphics.MultiLineProgress(controls) as l1:
    with survey.graphics.LineProgress(total = total) as l2:
        with survey.graphics.LineProgress(total = total, color = survey.colors.basic('magenta')) as l3:
            for _ in range(total):
                for index, control in enumerate(controls, start = 1):
                    if control.value >= total:
                        continue
                    for _ in range(index):
                        control.move(1)
                        time.sleep(0.01)
                if l2.controls[0].value >= total:
                    continue
                l2.move(1)
                l3.move(3)
                time.sleep(0.05)
image

I suppose the MultiLine part of the progress graphic's name might incline some to think these are indeed multiple lines, but they are actually one line with multiple controls - there is nothing to "stack" here alone🙂, you need multiple lines to have multiple... lines stacked on top of each other.

If this solves your issue feel free to close!

@Archer6621

Archer6621 commented May 23, 2026

Copy link
Copy Markdown
Author

Ah, I meant stacking in the sense that each progress instance represents a portion of the total! So that they do not overlap, much like a bar in a stacked bar chart. But this approach that you showed also works for communicating the same thing.

I have switched to a slightly more elaborate way of showing progress using a different library, so this can be closed if nobody will use it.

@Exahilosys

Copy link
Copy Markdown
Owner

Oooh gocha, I'll consider adding it but yes for now this can be closed then :)

@Exahilosys Exahilosys closed this May 23, 2026
@Exahilosys

Copy link
Copy Markdown
Owner

Reopening because I didn't realize code was submitted to actually fix this issue (woops). I'll review and possibly merge!

@Exahilosys Exahilosys reopened this May 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants