LabVIEW APIs Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Project to Plant UML Diagram Script

I needed to visualize my object oriented design. The Class Hierarchy in LabVIEW only shows inheritance relationship. I wrote a simple VI scripting tool which would show also usage and composition. It produces Plant UML string representation which can be used in an online tool http://www.plantuml.com/plantuml/uml to convert to a diagram. The created Plant UML representation can be a starting point for your documentation, you can edit the string to provide more info or use as is.

 

It is using LV19 because I needed sets and maps for class relationship representation. Cannot save to previous version, sorry.

Project to Plant UML DIagram ScriptProject to Plant UML DIagram Script

 

Plant UML online tool with examplePlant UML online tool with example

 

Scripting through a project to extract all class relationships into a mapScripting through a project to extract all class relationships into a map

 

Capturing inheritance relationshipCapturing inheritance relationship

 

Capturing composition relationshipCapturing composition relationship

 

Capturing usage relationshipCapturing usage relationship

I hope this helps. Enjoy!

 

Piotr Kruczkowski
Certified TestStand Architect
Certified LabVIEW Architect
Message 1 of 9
(6,943 Views)

I did similar things for a few tools (GraphML and Modelio), but never really to my satisfaction. I have ~300 classes in ~90 hierarchies, and some of these tools don't really scale up very well. Often, ordering needs to be done manually, and each and every time.

 

Can you post a PlantUML file (of some significant projected preferably)? Just so I can test the PlanUML features, and get a feeling?

 

EDIT: I can of course try myself as you posted the source code...

EDIT2: Except it's in LV2019...

Message 2 of 9
(6,899 Views)

Sorry it has to be LV19 because I use sets and maps inside.

 

For big designs it is absolutely critical to only show the classes and relationships you are actually interested in. By default everything is shown but this results in the following...

 

Actor --* Message_Enqueuer
Actor --* Message_Priority_Queue
Actor --> Last_Ack
Actor --> Message_Enqueuer
Actor --> Message_Priority_Queue
Actor --> Message
Air_Cooler_Application --|> Actor
Air_Cooler_Application --* Message_Enqueuer
Air_Cooler_Application --> Actor
Air_Cooler_Application --> Cooler_Controller
Air_Cooler_Application --> Cooler
Air_Cooler_Application --> Live_User_Controller
Air_Cooler_Application --> Message_Enqueuer
Air_Cooler_Application --> Programmatic_Controller
Change_Desired_Temperature_Msg --|> Message
Change_Desired_Temperature_Msg --> Actor
Change_Desired_Temperature_Msg --> Cooler_Controller
Change_Desired_Temperature_Msg --> Message_Enqueuer
Cooler_Controller --|> Actor
Cooler_Controller --* Message_Enqueuer
Cooler_Controller --> Message_Enqueuer
Cooler_Update_Fan_Status_Msg --|> Update_Fan_Status_Msg
Cooler_Update_Fan_Status_Msg --> Actor
Cooler_Update_Fan_Status_Msg --> Evaporative_Cooler
Cooler_Update_Water_Level_Msg --|> Update_Water_Level_Msg
Cooler_Update_Water_Level_Msg --> Actor
Cooler_Update_Water_Level_Msg --> Evaporative_Cooler
Cooler --|> Level_Controller
Cooler --* Message_Enqueuer
Cooler --> Message_Enqueuer
Dual_Fan --|> Timed_Loop_Actor
Dual_Fan --* Update_Fan_Status_Msg
Dual_Fan --> Update_Fan_Status_Msg
Evaporative_Cooler_Controller --|> Cooler_Controller
Evaporative_Cooler --|> Cooler
Evaporative_Cooler --* Message_Enqueuer
Evaporative_Cooler --> Actor
Evaporative_Cooler --> Cooler_Update_Fan_Status_Msg
Evaporative_Cooler --> Cooler_Update_Water_Level_Msg
Evaporative_Cooler --> Dual_Fan
Evaporative_Cooler --> Message_Enqueuer
Evaporative_Cooler --> Run_Fan_Msg
Evaporative_Cooler --> Water_Level
HW_Dual_Fan --|> Dual_Fan
HW_Evaporative_Cooler --|> Evaporative_Cooler
HW_Evaporative_Cooler --> Dual_Fan
HW_Evaporative_Cooler --> HW_Dual_Fan
HW_Evaporative_Cooler --> HW_Water_Level
HW_Evaporative_Cooler --> Water_Level
HW_Water_Level --|> Water_Level
Halt_Fan_Msg --|> Message
Halt_Fan_Msg --> Actor
Halt_Fan_Msg --> Dual_Fan
Halt_Fan_Msg --> Message_Enqueuer
Last_Ack --|> Message
Last_Ack --* Actor
Last_Ack --* Message_Enqueuer
Last_Ack --> Actor
Last_Ack --> Message_Enqueuer
Launch_Nested_Actor_Msg --|> Message
Launch_Nested_Actor_Msg --* Actor
Launch_Nested_Actor_Msg --> Actor
Level_Controller --|> Timed_Loop_Actor
Live_User_Controller --|> Evaporative_Cooler_Controller
Live_User_Controller --> Actor
Load_Into_Sub_Panel_Msg --|> Message
Load_Into_Sub_Panel_Msg --> Actor
Load_Into_Sub_Panel_Msg --> Air_Cooler_Application
Load_Into_Sub_Panel_Msg --> Message_Enqueuer
Message_Dequeuer --* Message_Priority_Queue
Message_Dequeuer --> Message_Priority_Queue
Message_Dequeuer --> Message
Message_Enqueuer --* Message_Priority_Queue
Message_Enqueuer --> Message_Priority_Queue
Message_Enqueuer --> Message
Message_Priority_Queue --> Message
Message_Queue --* Message_Dequeuer
Message_Queue --* Message_Enqueuer
Message_Queue --* Message_Priority_Queue
Message_Queue --> Message_Dequeuer
Message_Queue --> Message_Enqueuer
Message_Queue --> Message
Message --> Actor
Ping_Msg --|> Message
Ping_Msg --> Actor
Ping_Msg --> Message_Enqueuer
Programmatic_Controller --|> Cooler_Controller
Programmatic_Controller --> Actor
Protected_Actor_Handle --* Message_Enqueuer
Protected_Actor_Handle --> Message_Enqueuer
Register_Actor_Msg --|> Message
Register_Actor_Msg --* Message_Enqueuer
Register_Actor_Msg --> Actor
Register_Actor_Msg --> Message_Enqueuer
Run_Fan_Msg --|> Message
Run_Fan_Msg --> Actor
Run_Fan_Msg --> Dual_Fan
Run_Fan_Msg --> Message_Enqueuer
Simulated_Dual_Fan --|> Dual_Fan
Simulated_Evaporative_Cooler --|> Evaporative_Cooler
Simulated_Evaporative_Cooler --> Actor
Simulated_Evaporative_Cooler --> Dual_Fan
Simulated_Evaporative_Cooler --> Simulated_Dual_Fan
Simulated_Evaporative_Cooler --> Simulated_Water_Level
Simulated_Evaporative_Cooler --> Water_Level
Simulated_Water_Level --|> Water_Level
Simulated_Water_Level --> Actor
Stop_Msg --|> Message
Stop_Msg --> Actor
Stop_Msg --> Message_Enqueuer
Swap_Controllers_Msg --|> Message
Swap_Controllers_Msg --* Cooler_Controller
Swap_Controllers_Msg --> Actor
Swap_Controllers_Msg --> Air_Cooler_Application
Swap_Controllers_Msg --> Cooler_Controller
Swap_Controllers_Msg --> Message_Enqueuer
Timed_Loop_Actor --|> Actor
Timed_Loop_Actor --> Actor
Update_Current_Temperature_Msg --|> Message
Update_Current_Temperature_Msg --> Actor
Update_Current_Temperature_Msg --> Cooler_Controller
Update_Current_Temperature_Msg --> Message_Enqueuer
Update_Fan_Status_Msg --|> Message
Update_Fan_Status_Msg --> Actor
Update_Fan_Status_Msg --> Evaporative_Cooler_Controller
Update_Fan_Status_Msg --> Message_Enqueuer
Update_Msg --|> Message
Update_Msg --> Actor
Update_Msg --> Message_Enqueuer
Update_Msg --> Timed_Loop_Actor
Update_Pump_State_Msg --|> Message
Update_Pump_State_Msg --> Actor
Update_Pump_State_Msg --> Evaporative_Cooler_Controller
Update_Pump_State_Msg --> Message_Enqueuer
Update_Water_Level_Msg --|> Message
Update_Water_Level_Msg --> Actor
Update_Water_Level_Msg --> Evaporative_Cooler_Controller
Update_Water_Level_Msg --> Message_Enqueuer
Water_Level --|> Level_Controller
Water_Level --* Update_Water_Level_Msg
Water_Level --> Update_Water_Level_Msg
Write_Controller_Enqueuer_Msg --|> Message
Write_Controller_Enqueuer_Msg --* Message_Enqueuer
Write_Controller_Enqueuer_Msg --> Actor
Write_Controller_Enqueuer_Msg --> Cooler
Write_Controller_Enqueuer_Msg --> Message_Enqueuer
Write_Cooler_Enqueuer_Msg --|> Message
Write_Cooler_Enqueuer_Msg --* Message_Enqueuer
Write_Cooler_Enqueuer_Msg --> Actor
Write_Cooler_Enqueuer_Msg --> Cooler_Controller
Write_Cooler_Enqueuer_Msg --> Message_Enqueuer
Write_Deadband_Msg --|> Message
Write_Deadband_Msg --> Actor
Write_Deadband_Msg --> Level_Controller
Write_Deadband_Msg --> Message_Enqueuer
Write_Desired_Temperature_Msg --|> Message
Write_Desired_Temperature_Msg --> Actor
Write_Desired_Temperature_Msg --> Cooler
Write_Desired_Temperature_Msg --> Message_Enqueuer

The resulting diagram is so big that Plant UML cannot handle it as one PNGThe resulting diagram is so big that Plant UML cannot handle it as one PNG

 

Piotr Kruczkowski
Certified TestStand Architect
Certified LabVIEW Architect
Message 3 of 9
(6,882 Views)

@PrimaryKey wrote:

For big designs it is absolutely critical to only show the classes and relationships you are actually interested in.


That's one of the things I am struggling with. I almost made a comment on that in my first post, but didn't want to make things complex straight away.

 

What would be perfect is to have 'views' of some sort that do adapt to changes, but somehow limit the diagrams that are made. I did get that working, by simply blacklisting\whitelisting names (reg.ex. of course), but it's all done by programming. Going from a concept with VIs to a useable GUI is a big, big step...

 

I've found that what you want as a diagram can be completely different depending on how (and by who) it's going to be used.

 

The difficulty isn't really in the programming. It's about the requirements. I'm still figuring this out. I use mostly ad hoc diagrams now, but it's a lot of manual labor.

 

It would be perfect if what you made could be fed into an existing tool, and if the tool had views\rules to make the appropriate diagrams. Just so we don't have to make it.

 

Ah, well, we see how far we can take it Smiley Very Happy.

Message 4 of 9
(6,863 Views)

I love this idea with managed visual representations, where you just save the rules how you want to create them e.g. which relationships and which classes. Give those rules each a name and you can easily switch between diagrams.

Piotr Kruczkowski
Certified TestStand Architect
Certified LabVIEW Architect
0 Kudos
Message 5 of 9
(6,854 Views)

Hi,

Here is a LabView 2020 update that includes methods and interfaces. The code could need some more cleanup but it works fine as far as I can tell. Classes now can use spaces in their title.

There is also a separation between inheritance and interface implementation (..|>) now.

I've also written a primitive import plugin for StarUML (v5.1) to import plantUML, which is useful for large project since you can select what to view and move the elements around.

All credits go to the original authors.

 

Kind regards,

  Chris

 

Edit: Included missing file

Download All
Message 6 of 9
(3,809 Views)

Thanks Chris for the update for LV2020!

 

I tried running the script you uploaded and it is missing "SetIsInterface.vi"

0 Kudos
Message 7 of 9
(452 Views)

Hi,

Sorry for the inconvenience. I've attached the file, please let me know if anything else is missing.

Message 8 of 9
(448 Views)

I recently looked into Mermaid.

 

The main reason was that GitLab automatically turns Mermaid text in documentation into diagrams...

 

The markup is quite different compared to PlantUML, but if the datamining is split well enough from the output generation, it should not be too hard to output to any format out there (PlantUML, Mermaid, XMI, GraphML, StarUML, ...).

 

I'm still open to suggestions\experiences about how to limit the diagrams. Showing 400 classes in 80 hierarchies in one diagram is useless.

 

BTW: Mermaid markup is very simple, but it doesn't seem to be designed for names with spaces, '(', ')' and '.' in the class, property and method names... I don't recall if I got all that working in the end.

0 Kudos
Message 9 of 9
(439 Views)