Please provide a way to draw if/elseif/else structure vertically in activity diagrams

0 votes
asked Oct 23, 2015 in Wanted features by MAV (460 points)

I'm working on some code with switch case structures on big enumerate type or if/elsif/else structures with big conditions.

For now, I use the if/elseif/else plantUML structure to draw them but the different cases are placed horizontally.

It is a problem when the associated conditions or actions are big, the diagram becomes very large.

Example :

title lot_of_elsif

activity diagram

Please provide a way to draw if/elseif/else structure vertically in activity diagrams.

1 Answer

+1 vote
answered Nov 1, 2015 by plantuml (295,000 points)

This is still under work, but you can try an alpha version here:

With this version you must add a line to enable the feature:
!pragma useVerticalIf on


!pragma useVerticalIf on
if (condition A) then (yes)
  :Text 1;
elseif (condition B) then (yes)
  :Text 2;
elseif (condition C) then (yes)
  :Text 3;
elseif (condition D) then (yes)
  :Text 4;
else (nothing)
  :Text else;

In the final version, this pragma stuff will not be needed.
It's not clear yet if PlantUML will decide on its own to select horizontal/vertical strategy, or if the user will have to use a special command to change the layout (maybe a new keyword instead of "if" )

There are still issue about label layout, but the general idea is here.
Tell us what do you think about it!

commented Feb 20, 2019 by Nathan
thanks, this is very helpful
commented May 1, 2021 by Bert Merchie

I really love this feature and use it quite frequently. Recently I bumped onto a case whereby it doesn't seem to do the job :-(. Could you please help me out how I can make it work for this case too?

Many thanks!

!pragma useVerticalIf on
scale 1020x4000

:**prioCheck_Ondemand_PI**: \n__input parameters__:\n* item = VIDEO_CONTENT\n* highestPrio\n* highestPrioItem\n* selectedProduct\n__output parameters__\n* highestPrio\n* highestPrioItem\n* selectedProduct;
If (item.EntitlementState?) then ("Entitled")
   group entitled on-demand
   If (item.IsTstv?) then (false)
   'ingested entitled on demand                    
      If (highestPrio = 1?) then (no)                      
         :* highestPrio = 1\n* highestPrioItem = item;
      'ElseIf (highestPrioItem.IsViewableOnCpe = false And item.IsViewableOnCpe = true) then (yes)
         ':highestPrioItem = item;
         'note right: prioritize viewable content
      else (yes)
      :product = item.products(0);
      while (more products?)
         if (products(i).Type < product.Type) then (yes)
            :selectedProduct = products(i);
         else (no)
   Else (true)
      'automatically recorded, entitled                           
      If (highestPrio >= 4?) then (yes)           
         If (highestPrio = 4?) then (yes)          
            'If (highestPrioItem.IsViewableOnCpe = false And item.IsViewableOnCpe = true) then (yes)
               ':highestPrioItem = item;
               '(-> prioritize viewable content)
            'ElseIf (item.FirstAvailability\n> highestPrioItem.FirstAvailability And highestPrioItem.IsViewableOnCpe\n= item.IsViewableOnCpe) then (yes)
            If (item.FirstAvailability\n> highestPrioItem.\nFirstAvailability) then (yes)
               :highestPrioItem = item;                      
               '(-> this autorecorded entitled catchup, recorded more recently than the one selected so far)
            Else (no)                 
         else (no)          
            :* highestPrio = 4\n* highestPrioItem = item;
            '(-> this automatically recorded entitled catchup)
      else (no)
      'If (item.EntitlementEnd > Now()                                 '** entitled TVoDs
      '            highestPrioLinkedItem = item                                  '(-> this rented TVoD)
      '            highestPrio = 1                        
      '        Else '(non entitled on-demand)   
   end group
else ("NotEntitled")
   group non-entitled on-demand
   If (highestPrio >= 6?) then (yes)                     
      If (IsTstv?) then (False)                          
           'non-entitled TVoD "Transaction" has higher priority over non-entitled SVoD "Subscription" (FVoD not possible for the non-entitled case)
            If (item.Products(i).Type?) then ("Transactional")
              'ElseIf (highestPrioItem.IsViewableOnCpe = false And item.IsViewableOnCpe = true) Or (item.Products(0).ListPrice < ctaLowestRentalPrice) then  
               If (item.Products(i).ListPrice < ctaLowestRentalPrice?) then (yes)
                  '** non-entitled TVoDs (for ease of implementation, start implementation for lowest ListPrice, not OfferPrice)
                  :highestPrio = 6\n* highestPrioItem = item\n* selectedProduct = item.Products(i)\n* ctaLowestRentalPrice = ListPrice;
                  '(-> this TVoD content option at lower price OR prioritize viewable content)
            else ("Subscription")
               'If (highestPrio = 7 And (highestPrioItem.IsViewableOnCpe = false And item.IsViewableOnCpe = true) then  
               if (highestPrio > 7) then (yes)
                  'note right: € SVoD
                  :selectedProduct = item.Products(i) ;
                  :highestPrio = 7;
                  :highestPrioItem = item;
               else (no)
         repeat while (more products) is (yes)
      else (true)
      '(automatically recorded, non entitled)                    '** non entitled autorecorded catchup
         if (highestPrio > 7) then (yes)
            if (highestPrio = 8) then (yes)
               'If highestPrioItem.IsViewableOnCpe = false And item.IsViewableOnCpe = true
               'highestPrioItem = linkedItem                  '(-> prioritize viewable content)
               'ElseIf item.FirstAvailability > highestPrioItem.FirstAvailability And highestPrioItem.IsViewableOnCpe = item.IsViewableOnCpe
                If (item.FirstAvailability?) then (> highestPrioItem.FirstAvailability)
                   :* highestPrioItem = item\n*  selectedProduct = item.Products(0);
                  '(-> this SVoD content option)
            else (no)
               :* highestPrioItem = item\n* highestPrio = 8\n* selectedProduct = item.Products(0) ;
               '(-> this SVoD content option)
         else (no)
   end group

   :return\n* highestPrio\n* highestPrioItem\n* selectedProduct;