structurizr / export Goto Github PK
View Code? Open in Web Editor NEWExport models and views to external formats.
Home Page: https://docs.structurizr.com/export
License: Apache License 2.0
Export models and views to external formats.
Home Page: https://docs.structurizr.com/export
License: Apache License 2.0
I'm not sure the best place to put this, but I'm using Structurizr lite in a container so will go with here for now :-)
C4-PlantUML allows for any number of Property attributes to be applied to a deployment node which can be useful for giving additional details (SKUs, sizing, IPs, hostnames etc) e.g.
SetPropertyHeader("Property","Value", "Description")
AddProperty("Prop1", "Value1", "Details1")
AddProperty("Prop2", "Value2", "Details2")
Deployment_Node_L(nodeAlias, "Label", "Optional Type", "Optional Description (with custom property header)") {
WithoutPropertyHeader()
AddProperty("PropC1", "ValueC1")
AddProperty("PropC2", "ValueC2")
Container(containerAlias, "Label", "Technology", "Optional Description (without property header)")
}
I noticed that the deploymentNodes rendered in the deployment diagrams by Structurizr Lite (and the CLI export) only show the values from name
and technology
and anything else is ignored / not rendered e.g. description
As a work around I can add anything of interest into name
or technology
, but do you think it would be useful to render a general set / table of properties similar to C4-PlantUML?
The official Structurizr DSL reference syntax for containers and components is:
container <name> [description] [technology] [tags]
component <name> [description] [technology] [tags]
Though to be more precise, that is slightly ambiguous, and most Structurizr tooling interpret it as:
container <name> [description [technology [tags]]]
component <name> [description [technology [tags]]]
Which is to say, tags
is the most-optional, followed-by technology
, then description
. This can be seen in ContainerParser::parse() and ComponentParser::parse().
However, when C4PlantUMLExporter::writeElement() generates C4-PlantUML Container(...)
and Component(...)
procedure calls, if technology
is not set, then description
ends up in the technology
argument's positional, and this description
gets rendered as a technology
.
workspace {
model {
enterprise "Demo" {
demoSystem = softwaresystem "demoSystem" {
demoContainer = container "demoContainer" "desc" "tech" "tags" {
component "component1" "component1 description" "component1 technology" "component1 tag1,tsg2"
component "component2" "component2 description" "component2 technology"
component "component3" "component3 description"
component "component4"
}
}
}
}
views {
component demoContainer {
include *
}
}
}
Render that via Structurizr, and C4-PlantUML, eg via https://structurizr.com/dsl
Observe that only component3
, and only in the C4-PlantUML rendering, the component3 description
text appears where the technology text should. See screenshots in the next section.
Here's a sample show how it is correct for the Structurizr output, for all four components:
And here, you can see how for the C4-PlantUML output, component3
's description appears in the technology position:
See "Steps to reproduce" above.
No response
Major
Low
I'm willing to fix this myself and raise a PR
Looking at the generated C4-PlantUML (for the above sample DSL), it includes:
Container_Boundary("demoSystem.demoContainer_boundary", "demoContainer", $tags="") {
Component(demoSystem.demoContainer.component1, "component1", "component1 technology", "component1 description", $tags="")
Component(demoSystem.demoContainer.component2, "component2", "component2 technology", "component2 description", $tags="")
Component(demoSystem.demoContainer.component3, "component3", "component3 description", $tags="")
Component(demoSystem.demoContainer.component4, "component4", "", $tags="")
}
You can see that for component3
, then description has shifted into the technology position.
For convenience, here are links to the relevant current C4-PlantUML procedure definitions:
And here's the code in C4PlantUMLExporter.java
that writes (sometimes incorrectly) those procedure calls (ie this is where I'd say the fixes should go):
Note, the components fix will likely conflict with my existing open PR #60, so I would strongly recommend merging that PR (assuming you're happy with it) before fixing this. Or branch off my PR.
I'd be happy to have a go at fixing this bug too. Just not sure when I'll have time to get to it.
Cheers!
I'm wondering why the functionality of translating the Structurizr-java workspace object to the Structurizr-dsl workspace.json file is not a feature yet.
For a school project we want to generate the DSL in one project using the Structurizr-java project, and then send it to another project that will implement Structurizr-ui and will render the workspace.
I am capable of creating this translation myself and making a PR, but I'm wondering why it hadn't been implemented yet. (maybe it is, but I haven't found it yet π)
Are there any reason why I wouldn't want to make this translation?
Would this be a valuable addition to the project?
Kind regards
Low
I have no budget, please add this feature for free
No response
for user = person "η¨ζ·1"
, export to plantuml, it becomes
person "==η¨ζ·1\n<size:10>[Person]</size>" <<1>> as 1
Hi,
I'm trying to separate my workspace in multiple files but I have encountered an issue with the deployment view generation. I have put together a small example that reproduce the issue.
parent_workspace.dsl
workspace {
model {
softwareSystem = softwareSystem "Software System"{
database = container "Core Container" "" "Database"
}
}
}
workspace.dsl
!include parent_workspace.dsl
workspace {
model {
!ref softwareSystem {
service = container "service"
}
service -> database "Reads from"
deploymentEnvironment "OnPremise" {
deploymentNode "Database Server" {
containerInstance database
}
deploymentNode "Other server"{
containerInstance service
}
}
}
views {
deployment * OnPremise "OnPremise" {
include *
}
}
}
The generation will produce this error message
Exporting workspace from workspace.dsl
- loading workspace from DSL
- using C4PlantUMLExporter
java.lang.NullPointerException: Cannot invoke "com.structurizr.model.Relationship.getTags()" because the return value of "com.structurizr.model.Model.getRelationship(String)" is null
at com.structurizr.export.plantuml.C4PlantUMLExporter.tagsOf(C4PlantUMLExporter.java:270)
at com.structurizr.export.plantuml.C4PlantUMLExporter.writeRelationship(C4PlantUMLExporter.java:306)
at com.structurizr.export.AbstractDiagramExporter.writeRelationships(AbstractDiagramExporter.java:553)
at com.structurizr.export.AbstractDiagramExporter.export(AbstractDiagramExporter.java:462)
at com.structurizr.export.AbstractDiagramExporter.export(AbstractDiagramExporter.java:439)
at com.structurizr.export.AbstractDiagramExporter.export(AbstractDiagramExporter.java:71)
at com.structurizr.cli.ExportCommand.run(ExportCommand.java:181)
at com.structurizr.cli.StructurizrCliApplication.run(StructurizrCliApplication.java:36)
at com.structurizr.cli.StructurizrCliApplication.main(StructurizrCliApplication.java:81)
One last thing to mention.
If the service and the database were in the same deploymentNode then it would work
This is a spinoff of #30, particularly from the clarifying comment #30 (comment)
Currently, structurizr shows "dotted" arrows in sequence diagrams when there exists a relationship with a certain name, and then the returning relation (inverted src/dest) with the same name.
I ask to allow returninig arrows with different names:
a->b "send data"
b->a "return results"
One possible solution is to create a new relationship style property:
relationship "return" {
properties {
sequence.return true
}
}
so I would add the return
tag in the relationships.
C4Plantuml allows to define directions for the relations, see here.
This can help in better laying out the generated C4 PlantUml diagrams when there are many relations in the diagram.
It would be nice if the C4PlantumlExporter would automatically create Rel_L, Rel_D, ... relation entries if the corresponding relationship in dsl has a specific tag.
This workspace:
workspace {
model {
softwareSystem = softwareSystem "Software System" {
webapp = container "Web Application"
}
}
views {
properties {
c4plantuml.tags true
}
container softwareSystem "Diagram2" {
include *
autoLayout lr
}
styles {
element "Element" {
background #007700
color #ffffff
}
}
}
}
Results in this diagram, which has a solid green background for the body of the boundary element.
Defining custom styles and applying them on diagram elements does not work when exporting to C4PlantUml format
However, @klu2 seems to have fixed this in his library.
Would it be possible to add this feature ?
In order to avoid high textual pollution, I use different styles for technologies or special component "styles".
For example, a blue dashed arrow means https. It would be useful to add such custom notation to the legend (based on tags), for example by adding a property to the styles:
styles {
relationship "https" {
c4plantuml.legend "HTTPS Connection"
}
}
I'm not sure if this is a bug in mermaid, an issue with my DSL, or a bug in the exporter.
When I generate a WebSequence export, the lines look like this:
title ANS - Dynamic - AllFlows
actor <<Person>>\nAPI User as API User
participant <<Component>>\nAPI Gateway as API Gateway
participant <<Component>>\nManages Event definition as Manages Event definition
Yet in Notion.so, it generates this error:
Unknown error: Error: Lexical error on line 5. Unrecognized text.
... - AllFlows"actor <<Person>>\nAPI User
_______________________^
If I fix that by removing <<Person>>\n
it'll generate the same errors for <<Component>>\n
Is this a Mermaid bug, or a Structurizr issue?
Also, I find Structurizr uses ->
when I think the expectation is ->>
and -->>
but maybe that's me?
structurizr.sh export -w ANS.dsl -f websequencediagrams
Fixing that gives:
workspace "test WebSequence" {
model {
customer = person "Customer"
onlineBookStore = softwareSystem "Online book store" {
webapp = container "Web Application"
database = container "Database"
}
customer -> webapp "Browses and makes purchases using"
webapp -> database "Reads from and writes to"
}
views {
dynamic onlineBookStore {
title "Request past orders feature"
customer -> webapp "Requests past orders from"
webapp -> database "Queries for orders using"
autoLayout lr
}
}
}
structurizr-cli: 1.33.1
structurizr-java: 1.26.1
structurizr-dsl: 1.32.0
structurizr-export: 1.16.1
structurizr-import: v1.5.0
Java: 11.0.20.1/Homebrew (/opt/homebrew/Cellar/openjdk@11/11.0.20.1/libexec/openjdk.jdk/Contents/Home)
OS: Mac OS X 14.0 (aarch64)
Minor
Low
I have no budget and there's no rush, please fix this for free
I might be able to fix myself, but we may be subscribing to the cloud service anyway.
I think that the exporters should set the font name, or there should be a font property in the styles or theme in order to ensure that the same font is used everywhere.
This causes that renders look very different in some cases, to the point to cause word wrap, and turn diagrams difficult to compare.
Given the following example of dynamic view including parallel sequence:
workspace {
model {
a = softwareSystem "A"
b = softwareSystem "B"
c = softwareSystem "C"
d = softwareSystem "D"
e = softwareSystem "E"
}
views {
dynamic * {
a -> b "Get data (id)"
{
b -> c "Get some subset 1 of data (id)"
c -> b "Subset 1 of data"
}
{
b -> d "Get some subset 2 of data (id)"
d -> b "Subset 2 of data"
}
{
b -> e "Get some subset 3 of data (id)"
e -> b "Subset 3 of data"
}
autoLayout
}
}
}
The PlantUML Sequence diagram generated looks like this:
I would expect that diagram to use "par" message block to determine the parallel sequences in PlantUML, genereting an diagram like this:
@startuml
title Dynamic
skinparam {
shadowing false
arrowFontSize 10
defaultTextAlignment center
wrapWidth 200
maxMessageSize 100
}
hide stereotype
skinparam sequenceParticipant<<A>> {
BackgroundColor #dddddd
FontColor #000000
BorderColor #9a9a9a
}
skinparam sequenceParticipant<<B>> {
BackgroundColor #dddddd
FontColor #000000
BorderColor #9a9a9a
}
skinparam sequenceParticipant<<C>> {
BackgroundColor #dddddd
FontColor #000000
BorderColor #9a9a9a
}
skinparam sequenceParticipant<<D>> {
BackgroundColor #dddddd
FontColor #000000
BorderColor #9a9a9a
}
skinparam sequenceParticipant<<E>> {
BackgroundColor #dddddd
FontColor #000000
BorderColor #9a9a9a
}
participant "A\n<size:10>[Software System]</size>" as A <<A>> #dddddd
participant "B\n<size:10>[Software System]</size>" as B <<B>> #dddddd
participant "C\n<size:10>[Software System]</size>" as C <<C>> #dddddd
participant "D\n<size:10>[Software System]</size>" as D <<D>> #dddddd
participant "E\n<size:10>[Software System]</size>" as E <<E>> #dddddd
A -[#707070]> B : Get data (id)
par
B -[#707070]> C : Get some subset 1 of data (id)
B <-[#707070]- C : Subset 1 of data
else
B -[#707070]> D : Get some subset 2 of data (id)
B <-[#707070]- D : Subset 2 of data
else
B -[#707070]> E : Get some subset 3 of data (id)
B <-[#707070]- E : Subset 3 of data
end
@enduml
This is related to #11 but not exactly.
Now that C4-Plantuml added the robot shape, it would be useful that the exporter honors the Robot shape in styles:
views {
styles {
element "robot_user" {
shape Robot
}
}
}
That should be translated as the sprite "robot".
As it is on your website, I would like to have the diagram elements to be linked to the next diagram.
I know, that c4plantuml does support a $link argument in a c4-element and there is another way by using plain plantuml links at the end of the line (like you use fur the url property in dsl)
Low
I'm willing to add this feature myself and raise a PR
I tried to implement this feature, but run into trouble by determining the target file name of the next diagram because this is defined in the cli module (prefix(workspaceId)
is the problem here).
Possible solution would be to add a unique placeholder in the diagram.definition which then later can be replaced in the cli module with the filename of the generated target-diagram.
I am not sure, if you even want to implement this feature, because it was declined in a similar request structurizr/cli#58
If you approve the feature request, I would create a pull request in export and cli module.
Given
workspace "Test Product Architecture" "Model of the Test Platform." {
!identifiers hierarchical
model {
user1 = person "User1" "" "users"
user2 = person "User2"
frontend_user = person "FE user"
webhooks_user = person "Webhooks User" "" "robot_user"
EAS = softwaresystem "EAS" "Service1" {
SP = container "Processor" "Process1" "Node.js"
engine = container "Engine" "Processes2" "Go"
SP -> engine "Sends data"
engine -> SP "Send results"
}
backend = softwaresystem "Backend" "Backend1" "multi" {
database = container "DB" "" "MongoDB" "DB"
app = container "App" "Backend Server" "Node.js" {
s1 = component "Service1"
s2 = component "Service2"
s1 -> s2
}
app -> database "Uses"
}
backend.app -> EAS.SP "Send data"
backend.app -> EAS.engine "Sends data 2"
EAS.SP -> backend.app "Send results"
}
views {
properties {
plantuml.includes https://raw.githubusercontent.com/plantuml/plantuml-stdlib/master/tupadr3/font-awesome-5/users.puml
c4plantuml.tags true
c4plantuml.legend false
plantuml.sequenceDiagram true
}
systemlandscape TheSystemLandscape {
include *
autoLayout
}
component backend.app {
include *
autoLayout
}
theme default
styles {
element "DB" {
shape Cylinder
}
element "dataset" {
background #006400
}
element "robot_user" {
properties {
c4plantuml.sprite robot
}
}
element "users" {
properties {
c4plantuml.sprite users
}
}
element "multi" {
properties {
c4plantuml.shadow true
}
}
}
}
}
Commenting out the include does not change the behavior.
I couldn't isolate exactly what causes the stereotypes to show up.
I had to call HIDE_STEREOTYPES()
in an external puml include in order to workaround this.
Please consider
workspace "Test Product Architecture" "Model of the Test Platform." {
!identifiers hierarchical
model {
ss = softwaresystem "SS" "Software System" {
cont1 = container "Container1" {
comp11 = component "Component11"
comp12 = component "Component12"
comp11 -> comp12 "one\ntwo" "" "dashed"
}
cont2 = container "Container2" {
comp21 = component "Component21"
}
cont1.comp11 -> cont2.comp21 "Relation1" "" "dashed"
cont1.comp12 -> cont2.comp21 "Relation2"
}
}
views {
properties {
plantuml.sequenceDiagram true
}
container ss {
include *
autoLayout
}
component ss.cont1 {
include *
autoLayout
}
dynamic ss.cont1 {
ss.cont1.comp11 -> ss.cont1.comp12
}
styles {
relationship "dashed" {
dashed true
style dashed
}
}
theme default
}
}
(sorry long example)
Note that the arrow is not styled as dashed.
When exporting with format plantuml/c4plantuml
then includes at the top of the file look like this
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4.puml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Context.puml
Given that C4 is part of the PlantUML standard library (https://github.com/plantuml/plantuml-stdlib) which is included with PlantUML it is possible to include them with the following syntax
!include <C4/C4>
!include <C4/C4_Context>
This would make a life a little easier as I'm behind a corporate proxy and this will keep everything self contained.
Thanks.
Hi, I use Structurizr Site Generatr, which uses C4PlantUMLExporter to generate diagrams.
There are, of course, known limitations with that exporter, but one thing that works well, is the Structurizr DSL's style.shape
for Containers. It appears that C4PlantUMLExporter
is converting Cylinder
to ContainerDb
and Pipe
to ContainerQueue
(around lines 441 to 454).
However, there is no such conversion currently implemented for Components, which I would really like to have. I see that C4-PlantUML does provide equivalent ComponentDb and ComponentQueue procedures, so I'm wondering if it's simply a matter of inserting the equivalent shape-to-procedure mapping code into the conditional Component block too (around line 455)?
I'm happy to have a go at adding it, but as I'm not a Java developer, it might take be some time to get the dev tools etc setup (or not π€·π»ββοΈ). So any hints or suggestions, or reasons you know this won't work, would be great to hear early π
(And of course, if someone wants to beat me too it, that would be awesome too π).
Thanks!
Medium
I have no budget, please add this feature for free
No response
When I use the CLI (v1.18.0) to export the demo workspace Big Bank into dot using structurizr-cli export -w demo.dsl -f dot
and render the resulting dot file using Graphvis Online I cannot find any shape for Persons.
In contrast, Structurizr Online-Service renders the System Context and its Person Shape as expected.
Is there any way to export shapes to dot?
The dsl already allows to define element properties. It would be very cool if the properties could also be exported to the C4Plantuml files on demand via a views property.
How properties are defined in C4Plantuml is defined here: https://github.com/plantuml-stdlib/C4-PlantUML#element-properties
Once it could be useful to use the code to create model I would like to have the way to export is as the DSL or at last the JSON format so it could be used in other places as references.
Low
I have no budget, please add this feature for free
No response
Currently, the c4plantuml exporter gives an error when plantuml.sequenceDiagrams
is used, no matter the value.
In order to be able to export the same DSL for both expoerters (plain plantuml and c4plantuml), please allow the property by considering the value: let c4plantuml exporter accept it if the property is set to false
.
This issue supersedes structurizr/dsl#183
@qequ is developing this new export format, which will create a BlockDiagram's nwdiag diagram based on the information of the deployment view and the associated deploymentEnvironment.
@simonbrowndotje if you like it, you can add it to structurizr once finished. The result so far is very promising and provides more concise and qualitative information than the regular deployment diagram.
Mapping specification:
cylinder
shape but we will add it.The reason we chose the original BlockDiag's nwdiag over the PlantUML's one is because of limitations of the latter, such as not being able to have colored nodes, and lacking of validations. It's easier to add the cylinder shape to BlockDiag than to fix the coloring of the node background.
Hello!
I use C4PlantUMLExporter for puml schema generation from codebase. I don't use any tags for my elements in code, but when puml file generated, there are some $tags, witch I don't want to see :)
Such behavior exists because
com.structurizr.model.ModelItem.getDefaultTags
add default tags for each element, also each element in C4-PlantUml styles has default name
rectangle "$getPerson($label, $type, $descr, $sprite)$getProps()" $toStereos("person", $tags) as $alias $getLink($link)
How can I fix such behavior?
com.structurizr:structurizr-core:1.10.0
com.structurizr:structurizr-export:1.3.0
By default the PlantUML SVG export set target="_top"
for all links in the SVG export which is causing issues when trying to embed exported SVGs in an iFrame. Clicking links in the SVG causes the page to break out of the iFrame.
PlantUML has an option for skinparam svgLinkTarget x
where x is a user supplied value like _self
or a user supplied iFrame ID which will change the default link target used in the sag export.
I would love if an option could be added to support adding/changing this default.
Low
I'm willing to add this feature myself and raise a PR
No response
The group element is shown in almost every view type. I have defined a group of components which is visible in the component view.
Now I have defined a dynamic view with these components but the grouping is no more visible in the generated C4plantuml diagrams.
It would be very nice if the group is also visible in the dynamic views to be consistent with the static component view.
As title ... if relationship descriptions are not provided in the dynamic view definition, the WSD output shows blank relationship descriptions, rather than taking them from the actual relationship.
Problem:
If StructurizrPlantUMLExporter is compiled into a native binary with graalvm, it crashes at runtime since AWT classes are not available,
Context:
The plant UML exporter uses java.awt.image.BufferedImage to determine the icon size but this is not available on the classpath currently in graalvm builds.
There is currently an UnsatisfiedLinkError that is thrown when this happens but since the try/catch handler in the method that uses BufferedImage is only catching Exception, this isn't caught.
Solution:
I believe the simplest solution is to simply catch ANY Throwables inStructurizrPlantUMLExporter#calculateIconScale
This will allow the process to continue on, without completely failing. Possibly we could just also just swallow UnsatisfiedLinkErrors rather than printing the stacktrace in that case, since this is a known error and not one we'd want to spam the logs for.
Using this example (https://structurizr.com/dsl?example=big-bank-plc), when I try to export PlantUML sequence diagram by selecting the dynamic view, I got the below Output:
http://www.plantuml.com/plantuml/img/hPDFJy904CNl-oacS3Ma5AfeW20QRrxKn8CnPkWExOPsjzaTWd_YTtSMqK3LczkaIT_ilj_RoNGM63slwqe5OWZKe4Ts7gopf5HO6HkL6juKG2XHkusn1Ion2YGAUkysLyxohNabw6SYQLhYkk8xUkRpoXIs9ikGoukyL3SUctkZkOH-aiXtZS_N508MzEaWuhigZIO8Se0SlpG7CJpbZBQeQ3n-OeysY2pUq-asuDnvJVx2LNA1lMgiOBugl5jR_Lirtk2d_lu7kFz5QtbsHzbYiKmE_Bh9ThMoTJCzId4aX6zRw4mc5wvkfEsMEx2bxFCrCYum23xz2pySZBJE3l7BxMhZKpfEJpF1Vxb-qYsZiUIFu78dnnpfOOwzFWp-CKYh3zz9xca1SvcnG3w66SGmUtjxKMmD0WOOgY7q7hedINoEk3JvoigKJTB7tXI6S0QTSHu3dEssJ6-eGZREXj8q7QNKZAoMV-83
No response
No response
Minor
Low
I have no budget, please fix this for free
No response
The dynamic block, as is, has the enough information to create both a collaboration-type diagram and a sequence-type diagram.
I'm proposing to allow the user to choose the type for each block type, probably as a property (or a language keyword).
The mermaid exporter generates diagrams that are well supported by light-mode interfaces, but are harder to read in dark-mode interfaces. See the following example rendered in Github using dark-mode preference;
Suggestion would be to wrap all elements with a subgraph that has a solid background colour, in effect forcing light-mode as demonstrated below;
graph TB
subgraph 99 [Title]
style 99 fill:#ffffff,stroke:#444444
1["<div style='font-weight: bold'>Personal Banking Customer</div><div style='font-size: 70%; margin-top: 0px'>[Person]</div><div style='font-size: 80%; margin-top:10px'>A customer of the bank, with<br />personal bank accounts.</div>"]
style 1 fill:#08427b,stroke:#052e56,color:#ffffff
4["<div style='font-weight: bold'>Mainframe Banking System</div><div style='font-size: 70%; margin-top: 0px'>[Software System]</div><div style='font-size: 80%; margin-top:10px'>Stores all of the core<br />banking information about<br />customers, accounts,<br />transactions, etc.</div>"]
style 4 fill:#999,stroke:#6b6b6b,color:#ffffff
6["<div style='font-weight: bold'>E-mail System</div><div style='font-size: 70%; margin-top: 0px'>[Software System]</div><div style='font-size: 80%; margin-top:10px'>The internal Microsoft<br />Exchange e-mail system.</div>"]
style 6 fill:#999,stroke:#6b6b6b,color:#ffffff
subgraph 2 [Internet Banking System]
style 2 fill:#fff,stroke:#444,color:#444
17["<div style='font-weight: bold'>Single-Page Application</div><div style='font-size: 70%; margin-top: 0px'>[Container: JavaScript and Angular]</div><div style='font-size: 80%; margin-top:10px'>Provides all of the Internet<br />banking functionality to<br />customers via their web<br />browser.</div>"]
style 17 fill:#438dd5,stroke:#2e6295,color:#ffffff
18["<div style='font-weight: bold'>Mobile App</div><div style='font-size: 70%; margin-top: 0px'>[Container: Xamarin]</div><div style='font-size: 80%; margin-top:10px'>Provides a limited subset of<br />the Internet banking<br />functionality to customers<br />via their mobile device.</div>"]
style 18 fill:#438dd5,stroke:#2e6295,color:#ffffff
19["<div style='font-weight: bold'>Web Application</div><div style='font-size: 70%; margin-top: 0px'>[Container: Java and Spring MVC]</div><div style='font-size: 80%; margin-top:10px'>Delivers the static content<br />and the Internet banking<br />single page application.</div>"]
style 19 fill:#438dd5,stroke:#2e6295,color:#ffffff
20["<div style='font-weight: bold'>API Application</div><div style='font-size: 70%; margin-top: 0px'>[Container: Java and Spring MVC]</div><div style='font-size: 80%; margin-top:10px'>Provides Internet banking<br />functionality via a<br />JSON/HTTPS API.</div>"]
style 20 fill:#438dd5,stroke:#2e6295,color:#ffffff
21[("<div style='font-weight: bold'>Database</div><div style='font-size: 70%; margin-top: 0px'>[Container: Oracle Database Schema]</div><div style='font-size: 80%; margin-top:10px'>Stores user registration<br />information, hashed<br />authentication credentials,<br />access logs, etc.</div>")]
style 21 fill:#438dd5,stroke:#2e6295,color:#ffffff
end
end
1-. "<div>Visits bigbank.com/ib using</div><div style='font-size: 70%'>[HTTPS]</div>" .->19
1-. "<div>Views account balances, and<br />makes payments using</div><div style='font-size: 70%'></div>" .->17
1-. "<div>Views account balances, and<br />makes payments using</div><div style='font-size: 70%'></div>" .->18
19-. "<div>Delivers to the customer's<br />web browser</div><div style='font-size: 70%'></div>" .->17
20-. "<div>Reads from and writes to</div><div style='font-size: 70%'>[JDBC]</div>" .->21
20-. "<div>Makes API calls to</div><div style='font-size: 70%'>[XML/HTTPS]</div>" .->4
20-. "<div>Sends e-mail using</div><div style='font-size: 70%'>[SMTP]</div>" .->6
17-. "<div>Makes API calls to</div><div style='font-size: 70%'>[JSON/HTTPS]</div>" .->20
18-. "<div>Makes API calls to</div><div style='font-size: 70%'>[JSON/HTTPS]</div>" .->20
6-. "<div>Sends e-mails to</div><div style='font-size: 70%'></div>" .->1
I have 2 software systems, each of them with a group "backend" and "frontend". When creating a dynamic view, containers of software system 2 are placed inside of software system 1 (probably because the groups in software system 1 have the same name).
When giving the groups different names (e.g. "backend software system 1") everything works as expected.
run code sample
workspace {
model {
s1 = softwareSystem "S1" {
b1 = group "backend" {
c1b = container "C1 Backend"
}
f1 = group "frontend" {
c1f = container "C1 Frontend"
}
c1f -> c1b "call"
}
s2 = softwareSystem "S2" {
b2 = group "backend" {
c2b = container "C2 Backend"
}
f2 = group "frontend" {
c2f = container "C2 Frontend"
}
c2f -> c2b "call"
}
}
views {
dynamic s2 test {
c1f -> c1b
c2f -> c2b
}
}
structurizr CLI 1.30.0 (via docker)
Minor
Low
I have no budget, please fix this for free
No response
When I export diagrams from my Structurizr DSL model to C4-PlantUML, external persons are rendered as internal persons. For example:
I expect the external person to be rendered in a gray color, rather than a blue color.
Given this workspace:
workspace {
model {
enterprise "Customer" {
person_internal = person "Internal user"
system = softwareSystem "Test system"
}
person_external = person "External user"
person_internal -> system "Uses"
person_external -> system "Uses"
}
views {
systemContext system {
include *
}
}
}
When I export the system context diagram to C4-PlantUML, this PUML file is generated:
@startuml
title Test system - System Context
top to bottom direction
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4.puml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Context.puml
Enterprise_Boundary(enterprise, "Customer") {
Person(Internaluser, "Internal user", "", $tags="Element+Person")
System(Testsystem, "Test system", "", $tags="Element+Software System")
}
Person_Ext(Externaluser, "External user", "", $tags="Element+Person")
Rel_D(Internaluser, Testsystem, "Uses", $tags="Relationship")
Rel_D(Externaluser, Testsystem, "Uses", $tags="Relationship")
SHOW_LEGEND()
@enduml
Resulting in the above image.
This is caused by the Person
tag that's being assigned to the Person_Ext
element in the PUML file. When this tag is replaced by Person_Ext
or when it's omitted entirely then the external person is rendered correctly.
Before creating this issue, I double-checked whether or not this is intended behaviour for C4-PlantUML: plantuml-stdlib/C4-PlantUML#228.
Person_Ext
tag instead of the Person
tag.There are some exporter-specific properties.
And, some views are generated with different exporters.
That's why I suggest to be able to specify properties specific for each exporter, by adding the list of exporters next to the properties
keyword (or *
for all the exporters).
For example:
views {
properties * {
plantuml.includes extra_styles.puml
plantuml.legend false
}
properties "plantuml" {
plantuml.sequenceDiagrams true
}
properties "plantuml/c4plantuml" {
c4plantuml.tags true
}
}
A more complete solution would be to be able to specify the exporter per view, as a property. I understand this might be more challenging. For example, I would like to generate the landscape view with c4plantuml, and the dynamic diagrams with plain plantuml.
recently, support has been added with v2.7:
https://github.com/plantuml-stdlib/C4-PlantUML/tree/master#c4-styled-sequence-diagram
using
https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Sequence.puml
It would be nice, if the cli export would produce meaningful sequence diagrams when using "plantuml.sequenceDiagram" true
on views.properties. Currently it doesn't export anything meaningful.
Low
I have no budget, please add this feature for free
No response
At the moment when container or other diagrams are generated they C4 include directives are pointing to github URLs.
At least in my use case my CI/CD system where I have integrated the exporter does not have Internet connection.
To make it work I have some patch script that replaces the link to Github by some local path. But this also means I have to keep the C4 puml files in my Git repo.
It would be much better if the C4 puml files would be referenced in "plantuml std lib" syntax, since all the C4 Puml files are part of the plantuml stdlib, see below for an example
@startuml
title My dummy title
top to bottom direction
!include <C4/C4>
!include <C4/C4_Context>
!include <C4/C4_Container>
!include styles.puml
PlantUML allows to pass sprites to diagrams in order to have all kinds of logos in the generated diagrams, see https://github.com/plantuml-stdlib/C4-PlantUML#getting-started
In the code that looks like that:
@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml
!define DEVICONS https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/master/devicons
!define FONTAWESOME https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/master/font-awesome-5
!include DEVICONS/angular.puml
!include DEVICONS/java.puml
!include DEVICONS/msql_server.puml
!include FONTAWESOME/users.puml
LAYOUT_WITH_LEGEND()
Person(user, "Customer", "People that need products", $sprite="users")
Container(spa, "SPA", "angular", "The main interface that the customer interacts with", $sprite="angular")
Container(api, "API", "java", "Handles all business logic", $sprite="java")
ContainerDb(db, "Database", "Microsoft SQL", "Holds product, order and invoice information", $sprite="msql_server")
Rel(user, spa, "Uses", "https")
Rel(spa, api, "Uses", "https")
Rel_R(api, db, "Reads/Writes")
@enduml
which results in such a diagram:
It would be great to have that in the C4PlantUMLExporter
.
Adding separate includes is already possible via com.structurizr.export.plantuml.AbstractPlantUMLExporter#PLANTUML_INCLUDES_PROPERTY
, what we need to achieve is to add the sprites somehow from the model.
I thought a bit how that could be integrated into the method com.structurizr.export.plantuml.C4PlantUMLExporter#writeElement
without breaking things. We could of course pass the content of container.getTechnology()
or component.getTechnology()
as sprite to the writer
but that will make the diagram look weird when no sprite can be found for a given technology (besides that I don't know if a technology is always the best indicator for a sprite).
I'd therefore extract the code which finally writes the Container or Component to the writer to a strategy interface which can be exchanged by clients, leaving the default-implementation as-is in the current repo in order to not break existing things.
If you want I can provide a PR how that could look like.
Probably I could catch #2 then as well.
It works properly with plantuml, but with "plantuml/c4plantuml" the "Container(...)" line is missing so the Infrastructure Node shows up as a circle outside of any Deployment Nodes.
The generation of the static views are impacted depending on plantuml.sequenceDiagrams true
.
Given
workspace "Test Product Architecture" "Model of the Test Platform." {
!identifiers hierarchical
model {
group Customer {
ees_user = person "EES users" "" "users"
ends_user = person "ENDS user"
frontend_user = person "FE user"
webhooks_user = person "Webhooks User" "" "robot_user"
EAS = softwaresystem "EAS" "Service1" {
SP = container "Processor" "Something" "Node.js"
engine = container "Engine" "Processes the data" "Go"
SP -> engine "Sends data"
engine -> SP "Send results"
}
backend = softwaresystem "Backend" "Backend1" "multi" {
database = container "DB" "" "MongoDB" "DB"
app = container "App" "Backend Server" "Node.js" {
s1 = component "Service1"
s2 = component "Service2"
s1 -> s2
}
app -> database "Uses"
}
backend.app -> EAS.SP "Send data"
EAS.SP -> backend.app "Send results"
}
}
views {
properties {
"plantuml.includes" "extra_styles.puml"
#"c4plantuml.tags" "true"
"plantuml.legend" "false"
plantuml.sequenceDiagrams true
}
systemlandscape TheSystemLandscape {
include *
autoLayout
}
component backend.app {
include *
autoLayout
}
theme default
styles {
element "DB" {
shape Cylinder
}
element "dataset" {
background #006400
}
element "robot_user" {
properties {
c4plantuml.sprite robot
}
}
element "users" {
properties {
c4plantuml.sprite users
}
}
element "multi" {
properties {
c4plantuml.shadow true
}
}
}
}
}
However, when plantuml.sequenceDiagrams true
is not in the properties block, the same diagrams are generated as following:
I think that the first pair is broken since the enclosing scopes (group, container) are not drawn.
Given this example:
workspace {
model {
a = softwareSystem "A"
b = softwareSystem "B"
c = softwareSystem "C"
}
views {
dynamic * {
a -> b "Sends customer data to"
b -> c "Sends customer data to"
autoLayout
}
}
}
The communication diagram and sequence diagram generated using PlantUML exporters looks like this:
Even though sequence number is relevant for the communication diagram to understand the order of messages, itβs not the case for a sequence diagram, where the order is already implicit to the diagram. I can see WebSequenceDiagrams exporter is not including order number as part of the message description.
It would be great if messages in sequence diagrams don't include the sequence number.
Thanks.
We rely heavily on filtered views to visualize our development roadmap as in https://github.com/structurizr/java/blob/master/docs/filtered-views.md
Currently the export command only exports the corresponding base view.
Our and similar use cases would profit greatly from an option to export filtered views as well.
currently we have c4plantuml.shadow
Could you please generalize this property for both exporters?
The PlantUML exporter can export dynamic views to a free format diagram and a sequence diagram, but the Mermaid exporter only supports a free format diagram. Mermaid does support sequence diagrams though, so perhaps this should be added. I don't know how many people are using the Mermaid exports, so add a reaction/comment if you'd like to see this.
C4 PlantUML V2.8.0 has added the capability to set the border style and border thickness on elements and boundaries.
I would like to be able to utilize these new values so that I can create new styles for tags like 'new' and 'depricated' so that I can produce future state diagrams that stand out from current state.
Medium
I'm willing to add this feature myself and raise a PR
This looks like a simple enough change to add the two new properties to the export based on the current style ( similar to how borderColor is currently done ).
I will attempt a PR for the changes.
I was using the cli 1.20.1 for exporting to C4plantuml files quite successfully. In my dsl file I only changed the default styling for two elements based on a tag (have selected a different shape) and I configured that a "styles.puml" shall be included.
I used the feature to include a styles.puml that allowed me to change the default C4 styling for elements based on the tags given in the C4 dsl model file. I used this primarily to add nice icons to certain elements because the default styling is covering all my needs.
Since I wanted to use the feature to include the standard C4 puml files from the plantuml stdlib (meaning instead of getting http... references to the C4 puml files I wanted to have <c4/...> I moved to version 1.25.0 of the cli.
Now to simply get the tags back again (as I thought) I had to enable the property c4plantuml.tags. With this I now have the problem that all the default styles that are defined in the C4.puml files are all overriden (due to the default add...Tag functions in the generated puml files) and I would be forced to redefine the complete styling (acc to C4.puml implemented default styling) for default and customized elements in the dsl file since also then only the related tags are added at all to the elements in generated plantuml files. If I really wanted to redefine the whole styling I would be using the structurizr exporter and not the c4plantuml exporter.
I know that this "feature" is described in the official docs of the exporter but honestly from my perspective this makes this exporter now really worse than before and no more usable (at least for me). The only thing I need to allow for perfect customizing is to get the tags from the model elements to the elements in the generated puml file. All the customizations (adding sprite definition files and adding addElementTag, updateELementStyle calls can be done by just adding it to the includes puml file that can be configured in the dsl).
This also makes the dsl file much less cluttered with c4plantuml specific information.
Because of that I would be really happy if you could add an option/property or change the behaviour of the C4PlantumlExporter in such a way that "only" the model element tags are added to the c4plantuml file elements and nothing else is changed in the plantuml file related to styling.
Hi there,
Commit structurizr/dsl@0eda61d introduced the structurizr.dsl.identifier
property. Unfortunately this property shows up on all elements when "c4plantuml.elementProperties" "true"
is set in the view configuration. See e.g. at https://avisi-cloud.github.io/structurizr-site-generatr/main/internet-banking-system/context/
I think it would be nice if the exporter filters this (and may be future) internal property so that only properties from the model appear in the generated diagrams.
Kind regards
plantUML sequence diagrams allow declaring the participants order with the participant
keyword.
This can greatly improve the readability of the generated diagrams.
I propose to create a new view property, namely participants.plantuml
or alike, where the user can provide the (ordered) list of participants, which would then just be exported as a prologue of participants statements.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.