11-05-2019 04:48 AM
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.
I hope this helps. Enjoy!
11-05-2019 05:43 AM - edited 11-05-2019 05:47 AM
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...
11-05-2019 05:53 AM - edited 11-05-2019 06:06 AM
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
11-05-2019 06:25 AM
@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 .
11-05-2019 06:40 AM
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.
01-26-2023 11:13 AM - edited 11-14-2024 08:38 AM
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
11-14-2024 08:21 AM
Thanks Chris for the update for LV2020!
I tried running the script you uploaded and it is missing "SetIsInterface.vi"
11-14-2024 08:33 AM
Hi,
Sorry for the inconvenience. I've attached the file, please let me know if anything else is missing.
11-14-2024 09:15 AM - edited 11-14-2024 09:26 AM
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.