plantuml / plantuml

Generate diagrams from textual description
https://plantuml.com
Other
10.57k stars 969 forks source link

BUG: multiple activation of lifelines does not render properly in sequence diagrams #344

Closed nnako closed 3 months ago

nnako commented 4 years ago

the following text sequence creates a sequence diagram which shows an odd effect:

@startuml

'
' 1 - some activation lines separated by messages
'
activate "actor 1" #Olive
"actor 1" -> "actor 1": actor1 activity1
activate "actor 1" #OliveDrab
"actor 1" -> "actor 1": actor1 sub-activity1
deactivate "actor 1"
"actor 1" -> "actor 1": actor1 activity2\nactor1 summary1
activate "actor 1" #OliveDrab
"actor 1" -> "actor 1": actor1 sub-activity2\nactor1 sub-activity3
"actor 1" -> "actor 5" : 
deactivate "actor 1"
deactivate "actor 1"
activate "actor 5" #Olive
"actor 5" -> "actor 5": general func activity1\ngeneral func activity2
activate "actor 5" #OliveDrab
"actor 5" -> "actor 5": general func sub-activity1
"actor 5" -> "actor 1" : 
deactivate "actor 5"
deactivate "actor 5"

'
' 2 - some activation lines in sequence
'
activate "actor 1" #Olive
activate "actor 1" #OliveDrab
"actor 1" -> "actor 1": actor1 sub-summary1
"actor 1" -> "actor1_func1()" : 
deactivate "actor 1"
deactivate "actor 1"
activate "actor1_func1()" #Olive
"actor1_func1()" -> "actor1_func1()": actor1 func1 activity1\nactor1 func1 activity2
"actor1_func1()" -> "actor2_func1()" : 
deactivate "actor1_func1()"
activate "actor2_func1()" #Olive
"actor2_func1()" -> "actor2_func1()": actor2 func1 activity1
"actor2_func1()" -> "actor 1" : 
deactivate "actor2_func1()"

'
' 3 - some further activation lines in sequence
'
activate "actor 1" #Olive
activate "actor 1" #OliveDrab
activate "actor 1" #MediumSeaGreen
"actor 1" -> "actor 1": actor1 sub-sub-activity1
deactivate "actor 1"
"actor 1" -> "actor 1": actor1 sub-activity4
deactivate "actor 1"
"actor 1" -> "actor 1": actor1 activity3
@enduml

The above PlantUML sequence creates the following diagram as PNG:

resulting diagram

Looking at the diagram above, you see three red marke ovals. The 1st marker (1) shows how it was intended to look like: the first lifeline is created below action1 and then overlayed by another, short lifeline, which is then deactivated and re-activated again. Then the sequence walks over to actor5... The 2nd marker (2) shows that when returning from actor5 back to actor1 the double "activate actor1" from the text sequence results in only one visible lifeline, placed right of the middle line. The 3rd marker (3) now shows the same as seen before, just with three subsequent "activate actor1" text rows. It can be seen, that all lifelines are displayed even more on the right of the middle line and all directly above each other. The arrow heads end as expected, but as the lifelines are misplaced, they seem to end within the lifelines, not at them.

When deactivating lifelines, multi-deactivations work just fine (see deactivations of the first actor1 lifelines and the deactivation of the actor5 lifelines). But the other way round, multi-activation does not. I guess, this must be a bug? Or is it an intended feature?

arnaudroques commented 4 years ago

Thanks for the feedback. However your example is quite complex. Could you post here a simple and short example that shows the issue ? It would help ! Thanks!

nnako commented 4 years ago

Of course, my friend, here it is (see editor as well). The sequence history seems to have an influence on the effect, though:

@startuml
activate "actor 1" #Olive
activate "actor 1" #OliveDrab
activate "actor 1" #MediumSeaGreen
"actor 1" -> "actor 1": actor1 sub-sub-activity1
deactivate "actor 1"
"actor 1" -> "actor 1": actor1 sub-activity2
deactivate "actor 1"
"actor 1" -> "actor 1": actor1 activity2
@enduml

diagram

This diagram shows even another effect: all created lifelines have the same color even though they were defined differently. This "missing-color-effect" is not visible in the diagram of the first post of this thread. So, when issuing multiple activation statements firectly in a sequence, the lifelines of the respective actor are not built sequentially but show the following issues:

Deactivation shows a respective behavior.

nnako commented 4 years ago

here a kind of workaround. within the statement sequence, I inserted "dummy" statements in order to separate the three subsequent activate statements. this is done by inserting "actor 1" -[#ffffff00]> "actor 1" which create an invisible reflexive line with no text content:

@startuml
activate "actor 1" #Olive
"actor 1" -[#ffffff00]> "actor 1" :
activate "actor 1" #OliveDrab
"actor 1" -[#ffffff00]> "actor 1" :
activate "actor 1" #MediumSeaGreen
"actor 1" -[#ffffff00]> "actor 1": actor1 sub-sub-activity
deactivate "actor 1"
"actor 1" -[#ffffff00]> "actor 1": actor1 sub-activity
deactivate "actor 1"
"actor 1" -[#ffffff00]> "actor 1": actor1 activity
@enduml

diagram_reduced_02

The three lifelines get created properly (with their correct colors). Unfortunately, these additional "dummy" statements take up some vertical space, which I don't want to see.

So, I guess, we see still a BUG, here, which appears when multiple directly issued subsequent activate statements are placed within any PlantUML sequence diagram text.

jhoehle commented 2 years ago

Even hidden, the U-turn self-referential arrow costs vertical space. You can avoid that by using "actor 1" -[hidden]>? (short arrows) instead. This will reduce the effect a bit. You case save one more millimeter by using & on the second arrow.

Note that you waste vertical space between the 3 activity texts, because there are invisible U-turns between them. Your alpha-channel trick is excellent to display text! Just combine it with short arrows. This is the smallest that I could achieve:

@startuml
!pragma teoz true
activate "actor 1" #Olive
"actor 1" -[hidden]>?
activate "actor 1" #OliveDrab
& "actor 1" -[hidden]>?
activate "actor 1" #MediumSeaGreen
"actor 1" -[#ffffff00]>? : actor1 sub-sub-activity
deactivate "actor 1"
"actor 1" -[#ffffff00]>? : actor1 sub-activity
deactivate "actor 1"
"actor 1" -[#ffffff00]>? : actor1 activity
deactivate "actor 1"
@enduml

online image

You can use "actor 1" <[hidden]-?, even add ++ #OliveDrab but then quickly run into weird lifeline/activation bugs.

nnako commented 2 years ago

Thanks @jhoehle . This looks much better than what this thread had to offer, so far. I think, the hidden "colors" don't do any optimization of size, though.

The statement !pragma teoz true somehow causes multiple direct deactivations to render invalid. The lowest activity bar stays alife even though it was deactivated:

@startuml
!pragma teoz true
activate "actor 1" #Olive
"actor 1" -[#ffffff00]>? : actor1 activity1
activate "actor 1" #OliveDrab
"actor 1" -[#ffffff00]>? : actor1 sub-activity1
deactivate "actor 1"
"actor 1" -[#ffffff00]>? : actor1 activity2\nactor1 summary1
activate "actor 1" #OliveDrab
"actor 1" -[#ffffff00]>? : actor1 sub-activity2\nactor1 sub-activity3
"actor 1" -> "actor 5" : 
deactivate "actor 1"
deactivate "actor 1"
activate "actor 5" #Olive
"actor 5" -[#ffffff00]>? : general func activity1\ngeneral func activity2
activate "actor 5" #OliveDrab
"actor 5" -[#ffffff00]>? : general func sub-activity1
"actor 5" -> "actor 1" : 
deactivate "actor 5"
deactivate "actor 5"
activate "actor 1" #Olive
"actor 1" -[#ffffff00]>? :
activate "actor 1" #OliveDrab
"actor 1" -[#ffffff00]>? : actor1 sub-summary1
"actor 1" -> "actor1_func1()" : 
@enduml

image

jhoehle commented 2 years ago

You are right. Teoz looks like it cannot count! :-( Another bug!

I used hidden (where applicable) rathern than #ffffff00 to convey what I want rather than to rely on the alpha channel. I agree that alternating both is cumbersome, so just stick to the invisible arrow.

jimnelson372 commented 5 months ago

I'm looking through the open issues related to sequence diagrams and specifically "teoz" problems. This one still seems to be a problem.

Right now, in teoz, multple activates in a row do seem to push out where the arrow draws, but the drawing of the active levels on the timeline is still not working. Similarly, multiple deactivate statements moves in where the arrow draws, but the activity levels are also not correctly adjusting.

I'm going to look in the code where it draws the activity levels and picks the colors to see if I can find exactly where the problem is and a solution to it.

Jim N. @jimnelson372

jimnelson372 commented 5 months ago

I am testing some fixes in teoz addressing this issue. It would not allow multiple activates and multiple deactivates on the same Participant on the same event, drawing the appropriate activity levels with the specified colors.

A necessary restriction though, which I believe is logical, is that if an activate occurs on an event where a deactivate has already occurred (for the same Participant), that activate will cause further activate/deactivates on that Participant to be evaluated after a brief pause. Likewise for a deactivate after an activate has occurred on the same Participant on the same event. [I haven't removed the current error messages for such activation immediately following deactivation, but these conditions can still occur when parallel messages are used, where the activates and deactivates aren't immediately next to each other, but they still might occur at the same point on the timeline, if not for the testing I added.] Still, it supports any number of activates (to increase the activation level) and and any number of deactivates (until the level is 0) to occur on a participant life line on a single event.

Here is the diagram generated for the original script that @nnako provided, adding only the !pragma teoz true and no other changes:

testteozdemomult

Now, teoz is not only able to match Puma on the deactivates, but all the multiple activates on "actor 1" when the messages return are drawn correctly. This was also the part @nnako highlighted in his second script. Here is that diagram, with the script updated only to activate teoz:

testteozdemomult_001

You would no longer need the hidden arrows to control the number of activation levels. With the hidden arrows, it will still draw as it currently does, since those hidden arrows are still considered separate events for the activation/deactivation instructions to apply to. So that 3rd script, using teoz, still draws:

testteozdemomult_002

Interestingly, since @jhoehle used a parallel short message in his first script above, with the & working better now, it actually hides the impact of the hidden short arrow all together. The parallel short arrow was only used between the 2nd and 3rd activates, so you can see the difference between them and between the 1st and 2nd.

testteozdemomult_003

On @nnako's final script above, it produces the following in my test environment:

testteozdemomult_004

The final two activates would occur at the same level if the hidden short arrow was made parallel (i.e. putting & in front of it), or if it were removed all together.

I wanted to share each of the above images in case anyone believes it still isn't working as expected. As I said, the scripts I used are identical to those above, except adding !pragma teoz true on the scripts that didn't use this.

I have been testing to verify that my changes do not unexpectedly cause new problems, and I've already discovered a few cases I wasn't properly handling, but I believe I have a reliable solution now. Still, I'll test it a little longer.

My fixes are only to teoz. I have not yet looked at the multiple activation problem that shows up in the puma layout, so I'm not sure how difficult fixing that might be.

Regards,

Jim N @jimnelson372

jimnelson372 commented 5 months ago

As for the original Puma issues, I've tracked down the problem with it not drawing multiple activates that occur at the same time. So, the original script above, so with teoz not activated, now looks like this in my test environment:

testteozdemomult

I believe this is what you would expect.

As for the 2nd script, where the activitates all occur at the beginning of the diagram, before any messages, this fix does make it draw the bars themselves. Unfortunately, the color problem that was reported, where they are all the same color despite different colors being specified for each bar. So, at the moment, it looks like this, with teoz not activated:

testteozdemomult_001

My testing of the Teoz fix that I wrote about yesterday is looking good. I hope to have a chance to track down this final Puma color problem later today.

Jim

jimnelson372 commented 5 months ago

Okay, I took a quick look and found the problem in Puma for these start of lifeline activation colors. And fortunately the solution was simple enough. Here's what the diagram that 2nd script (original puma version) generates now in my test environment:

testteozdemomult_001

I'm glad that I was able to find solutions for both layout systems. I will test these Puma fixes a little further to make sure noting else was impacted.

Regards,

Jim N. @jimnelson372

The-Lum commented 3 months ago

Hi all,

[This is an Issue Review] 👀 This is now fixed on V1.2024.6.

Regards.