structurizr / cli

A command line utility for Structurizr.
https://docs.structurizr.com/cli
Apache License 2.0
491 stars 75 forks source link

Open Source interactive diagrams... #58

Closed pmorch closed 2 years ago

pmorch commented 2 years ago

Are there any options for interacting with diagrams using a purely open source toolchain?

This structurizr/cli repo's export is (as far as I'm aware) the only Open Source way to create viewable output from a workspace.dsl file, and according to https://structurizr.org/#rendering, the only tools that can be interfactive are Structurizr and Ilograph, neither of which are open source. So I'm guessing the current answer is "no".

I've taken a look at the PlantUML export format and have a suggestion for how this could be made interactive. But I'm hoping that there are there better/easier ways...

If not, then in that suggestion, I'm asking for a -linkprefix option as an improvement suggestion.

Simon, I realize this is an open core business model, so you might not be too keen on providing / catering for open source interactivity, but I just saw your talk at Goto Copenhagen 2021, where you where adamant that diagrams should be interactive and not static .png files, so I'm hoping you'll sympathize :-)

(Ugly?) Suggestion: Interactive C4 diagrams with PlantUML

I'll be using the default DSL example from https://structurizr.com/dsl in the following.

Running

docker run -u $(id -u):$(id -g) -it --rm -v $PWD:/usr/local/structurizr structurizr/cli export  -workspace example/workspace.dsl -format plantuml/c4plantuml -output example

Generates two .puml files. If I modify example/structurizr-SoftwareSystem-SystemContext.puml with:

$ diff -uw example/structurizr-SoftwareSystem-SystemContext.puml.orig example/structurizr-SoftwareSystem-SystemContext.puml      
--- example/structurizr-SoftwareSystem-SystemContext.puml.orig  2021-11-26 05:16:22.464691300 +0100
+++ example/structurizr-SoftwareSystem-SystemContext.puml   2021-11-26 05:17:11.364691300 +0100
@@ -7,7 +7,7 @@
 !includeurl https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Context.puml

 Person(User, "User", "")
-System(SoftwareSystem, "Software System", "")
+System(SoftwareSystem, "Software System", "") [[http://server/path/to/structurizr-SoftwareSystem-SystemContext.svg]]

 Rel_D(User, SoftwareSystem, "Uses")

Then I get svg output from PlantUML like:

<a xmlns="http://www.w3.org/2000/svg" href="http://server/path/to/structurizr-SoftwareSystem-SystemContext.svg" target="_top" title="http://server/path/to/structurizr-SoftwareSystem-SystemContext.svg" xlink:actuate="onRequest" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://server/path/to/structurizr-SoftwareSystem-SystemContext.svg" xlink:show="new" xlink:title="http://server/path/to/structurizr-SoftwareSystem-SystemContext.svg" xlink:type="simple">
  <rect fill="#1168BD" height="38.625" style="stroke:#3C7FC0;stroke-width:1.5;" width="173" x="172" y="51.9531"/>
  <text fill="#FFFFFF" font-family="sans-serif" font-size="16" font-weight="bold" lengthAdjust="spacing" textLength="153" x="182" y="76.8047">Software System</text>
</a>

That is exactly enough to create an interactive tool with: An HTML page that shows the top-level .svg file in an <object src="..."></object> tag, and once it's loaded, adds a javascript event listener to that svg object so that clicking on the "Software System" doesn't follow the link, but instead loads another .svg file into the same <object></object> tag.

Adding the links to the .puml files after generation is non-trivial in the generic case, especially since the names in the PlantUML files don't match the names in the workspace.dsl file or output from list 100%. But it could be done. However, would this project be open to adding e.g. a -linkprefix option so that:

docker run -u $(id -u):$(id -g) -it --rm -v $PWD:/usr/local/structurizr structurizr/cli export  -workspace example/workspace.dsl -format plantuml/c4plantuml -output example -linkprefix http://server/path/to/

would add the links to the .puml output?

Does anybody see a cleaner / better way of achieving this?

Also, does anybody have hints about whether PlantUML or e.g. Mermaid output is "prettier" in the long run? Or whether e.g. the Mermaid export and tool chain are better suited for interactivity leading to a simpler solution than this suggestion?

simonbrowndotje commented 2 years ago

the only tools that can be interfactive are Structurizr and Ilograph, neither of which are open source. So I'm guessing the current answer is "no".

Correct, they're not open source; Ilograph has a free plan, and Structurizr Lite is free to use though.

I've heard of teams who have built their own toolchain for assembling PlantUML diagrams into an interactive website, but none of them have open sourced their solutions unfortunately. If you do build such an open source tool, do let me know and I'll make sure that it's linked/mention it in my talks. 👍

If you're looking for collaborators, feel free to join the Structurizr Slack group.

pmorch commented 2 years ago

Hi Simon,

Structurizr Lite only allows for interactivity on localhost, which means it can't be shared by the team. Fair enough.

Cool! I just might. Timing is a little off, though :-). Today I'm finishing a week of isolation due to having been tested Corona positive, but I've had no symptoms. Had I known all this a week ago, that would've been a fun project for all the time I've had om my hands! :-)

simonbrowndotje commented 2 years ago

Structurizr Lite only allows for interactivity on localhost, which means it can't be shared by the team.

Correct, but you could commit the diagram source (*.dsl), diagram layout (workspace.json, if using manual layout) into your source code control system, along with a shell script that starts Structurizr Lite. Other team members can then view the diagrams interactively on their own computers.

Sorry to hear that ... hopefully you didn't pick it up at the conference!

pmorch commented 2 years ago

Correct, but you could commit the diagram source (*.dsl), diagram layout (workspace.json, if using manual layout) into your source code control system, along with a shell script that starts Structurizr Lite. Other team members can then view the diagrams interactively on their own computers.

I already did that :-)

No I don't think i got it at the conference; I then would've tested positive sooner.

pmorch commented 2 years ago

I think I'm missing a piece of this interactivity puzzle. E.g. for big-bank-plc.dsl, the first three views are:

    views {
        systemlandscape "SystemLandscape" {
           <snip>
        }

        systemcontext internetBankingSystem "SystemContext" {
           <snip>
        }

        container internetBankingSystem "Containers" {
           <snip>
        }
       <snip>
    }

Short version: there are two views for internetBankingSystem: a systemcontext and a container view. But only one url field for internetBankingSystem.

Longer version:

Structurizr Lite is smart and so from diagrams#SystemLandscape the link to "Internet Banking System" is a link to diagrams#SystemContext but from diagrams#SystemContext the link to the same "Internet Banking System" is to diagrams#Containers.

And I can't really do that if I'm to use the approach where internetBankingSystem has a single url field. Because I need the URLs to be different in the two diagrams#SystemLandscape and diagrams#SystemContext views.

Any good ideas on how to handle this?

My idea right now is that the tool picks a one of the possible values for the url field, e.g. diagrams#SystemContext. And then generates the .puml files. Because of the chosen default value, structurizr-SystemLandscape.puml will have the correct link. But then the new app is smart enough to modify structurizr-SystemContext.puml after generation to modify the [[link]] field. Now the app is back to brittle and non-trivial modification of the .puml file, but it could be made to work.

But is the root issue that a single url field is really not enough? Are there other cases where the URL for the entity depends on which view we're in? Could properties (of which there can be multiple) somehow come into play?

Also, keep in mind, that this is somewhat beyond my own current itch. I don't yet have any container views, so this is still a little academic for me.

simonbrowndotje commented 2 years ago

It depends how you're planning to build your tooling. If you're relying on the exports created by the CLI, then you're stuck with a single URL. One alternative is to build your tooling in Java (using structurizr-client, structurizr-dsl, structurizr-export, etc), where you could recreate the way that Structurizr Lite links views together:

  1. Parse the DSL, and create an in-memory version of the workspace.
  2. For each view { determine the view type and which elements should be hyperlinked, modifying their url properties based upon the view type; export the view to C4-PlantUML format }.
pmorch commented 2 years ago

Thanks!

pmorch commented 2 years ago

Thanks for your suggestion on how to do it in java. Inspiration can be had from looking at com.structurizr.cli.ExportCommand#run

simonbrowndotje commented 2 years ago

You're welcome! If you also include a dependency on PlantUML (it's distributed as a JAR file), you could generate the SVG in the same process.

pmorch commented 2 years ago

I've created https://github.com/pmorch/c4viz - there is a demo at http://c4viz.morch.com:9000/ :-)

Simon, are you ok with me using the structurizr favicon and logo or would you like for me to use another?

simonbrowndotje commented 2 years ago

That looks great, I'll add some links to the structurizr.org and DSL pages.

Simon, are you ok with me using the structurizr favicon and logo or would you like for me to use another?

Your own logo please, to avoid any confusion between this and Structurizr Lite.