mermaid-js / mermaid

Generation of diagrams like flowcharts or sequence diagrams from text in a similar manner as markdown
https://mermaid.js.org
MIT License
72.74k stars 6.64k forks source link

Support for C4 Models #1276

Open lwalker-kforce opened 4 years ago

lwalker-kforce commented 4 years ago

We adopted C4 Models and use Azure DevOps Wiki's for our documentation. Currently, we model in Vizio, etc. and paste a screen shot into our wiki docs or have tried to use PlantUML. Azure DevOps supports mermaid natively now so I would like to see if there is already an easy way to support C4 and/or Azure shapes using Flowchart(s) + CSS or if there is an opportunity to support them some other way.

I have used PlantUML and extensions for both C4 and Azure models in our wiki docs. Here are a few extensions to help explain the intent hopefully.

https://github.com/RicardoNiepel/C4-PlantUML https://github.com/adrianvlupu/C4-PlantUML https://github.com/RicardoNiepel/Azure-PlantUML https://github.com/dcasati/Azure-PlantUML

Perhaps an enhancement similar to the font-awesome support?

jgreywolf commented 4 years ago

Just playing around a bit - I created this using current flowchart functionality. I get that this does not completely match the example (Message Bus and Microservices) but like I said, just playing around...

Repro in Mermaid Live Editor

nicholasf commented 4 years ago

Having C4 in Mermaid would be terrific.

vasylnakvasiuk commented 4 years ago

Just playing around a bit - I created this using current flowchart functionality. I get that this does not completely match the example (Message Bus and Microservices) but like I said, just playing around...

Repro in Mermaid Live Editor

Agree, but we need more figures (database, message bus, etc.) Plus would be a killer feature, if somehow you add clickable transition from 1 graph to another. So I will be able to describe different levels of my project (classes diagram, component diagram, context diagram) and connect 1 box with (zoom in) 1 another graph. And obviously will be able to go back (zoom out).

fossro commented 3 years ago

Just adding my vote here, support for C4 models in mermaid would be awesome!

simonbrowndotje commented 3 years ago

Since this issue is still open ... I appreciate this isn't native Mermaid support, but you can do a Mermaid export from the open source Structurizr DSL & CLI combo:

haraldreingruber commented 3 years ago

@simonbrowndotje That sounds like a really nice approach, thanks for sharing!

marqh commented 3 years ago

native Mermaid support for C4 would be massively valuable.

Is there progress or intent in this domain?

fossro commented 3 years ago

Just want to add my support to this idea. Having support for C4 in Mermaid would be super valuable! What can we do to prioritize this feature?

ecofone commented 3 years ago

Will be really great to have C4 native support! any news?

simonbrowndotje commented 3 years ago

What can we do to prioritize this feature?

Perhaps it's worth discussing what you'd like to see in such a feature. "Supporting the C4 model" could range from some pre-defined styles and shapes through to adding new keywords to the Mermaid syntax (like you see with C4-PlantUML, for example). Each has a different level of effort required, and there are already solutions that provide similar functionality. You should also consider sponsoring the author if this feature has value to you. As I mentioned above, a Structurizr DSL to Mermaid exporter is already available too.

uadev commented 2 years ago

Just playing around a bit - I created this using current flowchart functionality. I get that this does not completely match the example (Message Bus and Microservices) but like I said, just playing around...

Repro in Mermaid Live Editor

If we look at this live editor repro, we see that just adding C4 shapes would cover > 80% of all cases.

jodosha commented 2 years ago

Please make it happen. 🙏

nrktkt commented 2 years ago

Having just tried to make a c4 diagram with plain mermaid for the past few days, as someone who doesn't care much about shapes and styles, I can say that the biggest issue right now is that flow diagrams are directional, and c4 (system) diagrams are not. This results in non-optimally placed nodes, crossed edges, and confusing edge labels.

I got this far

graph TD
    A(["A</br>[Container: ...]"])
    B["B<br/>[Software System: ...]<br/> ..."]

    subgraph "... </br>[Software System]"
    C("C</br>[Container: ...]</br>...")
    D("D </br>[Container: ...]</br>...")
    E("E </br>[Container: ...]</br> ...")
    F("F </br>[Container: ...]</br> ...")
    G("G </br>[Container: ...]")
    end

    A--"... </br> [...]"-->B-->C--"... </br> [...]"-->B
    A--"... </br> ...]"-->C

    C--"... </br> [...]"-->D
    E--"..."-->D
    E--"..."-->J("J </br>[Container: ...]</br> ...")
    H("H </br>[Container: ...]</br> ...")
    J-- ... -->H

    C--"... </br>  [...]"-->F
    G-- ... -->F
    I("... </br>[Container: ...]</br> ...")
    G-- ... -->I-- ... --> H

before deciding to stop because the output had become illegible.

If there were another mode in mermaid like the flowchart, but which doesn't try to enforce directionality, I think that would be sufficient for my (and most) usage.

simonbrowndotje commented 2 years ago

I can say that the biggest issue right now is that flow diagrams are directional, and c4 (system) diagrams are not.

It's really a tooling issue, and specifically the way that auto-layout algorithms work. As a human, it's relatively easy to create a nice diagram layout, and we can use contextual information that's not present in the diagram to organise elements to better tell a story. Here's a version of your example that I manually organised in <1 minute by dragging boxes around.

Manual layout

When it comes to automatic layout, most of the tools use a similar approach - they rank nodes based upon dependencies. You can sometimes influence the behaviour by changing the ordering of lines in your definition, change the node/edge/rank separation, and PlantUML provides some statements that can be used to tweak the algorithm. But ultimately the resulting layouts look very similar.

PlantUML

PlantUML

 Mermaid

Mermaid

Graphviz (viz.js)

Graphviz

In contrast to manual or automatic layouts, interactive visualisations don't make diagrams that are neatly embedded in traditional static documentation, but they do provide a lot more flexibility. These static screenshots don't do them justice, but here are a couple alternative ways to present the same information.

Ilograph

Ilogaph

d3.js

d3.js

It's all trade-offs. If you want to take a look at any of the above in more detail, here's a Structurizr DSL version of your diagram.

nrktkt commented 2 years ago

@simonbrowndotje would you mind updating those graphs you made (awesome comparison) with labels for the edges? I think the edge label locations is a huge part of the legibility problem I'm seeing. Mermaid seems to put labels on only a finite set of y axis positions, so there's a much higher likelihood of overlap (iirc plantuml doesn't do this).

most of the tools use a similar approach - they rank nodes based upon dependencies

I believe that mermaid ALSO ranks nodes based upon direction in flow diagram mode. So my suggestion is to do something like add a UD (undirected) mode to flow diagrams in addition to the existing TD and LR modes.

simonbrowndotje commented 2 years ago

Sure, here you go:

(if you click "View source", you can edit the descriptions)

dminca commented 2 years ago

Having C4 model would be really helpful to keep things DRY.

I've seen this vid about Diagrams as Code 2.0 by Simon Brown at Goto '21 and he actually has a DSL prepared for achieving this https://github.com/structurizr/dsl, hope this helps to give more clarity on the details of this feature.

simonbrowndotje commented 2 years ago

Having C4 model would be really helpful to keep things DRY.

hope this helps to give more clarity on the details of this feature

I think you'll need to be more specific in what you're looking for, because there's a fundamental mismatch of approach between Mermaid and the Structurizr DSL:

jgreywolf commented 1 year ago

There appears to be some interest in this diagram type. If you would like to see this please provide a little more detail on how you would expect this to look/work (syntax suggestions, etc)

Ogglas commented 1 year ago

@jgreywolf I think you are already on the right path in your own docs: https://mermaid.js.org/syntax/c4c.html that I think @ashishjain0512 and @pinghe started writing.

Fixing the unfinished features, getting out of experimental diagram and agreeing on syntax and properties this would be good to go in my world.

Your own examples on GitHub using Mermaid below (experimental so it might brake in the future). :)

C4 System Context Diagram (C4Context):

    C4Context
      title System Context diagram for Internet Banking System
      Enterprise_Boundary(b0, "BankBoundary0") {
        Person(customerA, "Banking Customer A", "A customer of the bank, with personal bank accounts.")
        Person(customerB, "Banking Customer B")
        Person_Ext(customerC, "Banking Customer C", "desc")

        Person(customerD, "Banking Customer D", "A customer of the bank, <br/> with personal bank accounts.")

        System(SystemAA, "Internet Banking System", "Allows customers to view information about their bank accounts, and make payments.")

        Enterprise_Boundary(b1, "BankBoundary") {

          SystemDb_Ext(SystemE, "Mainframe Banking System", "Stores all of the core banking information about customers, accounts, transactions, etc.")

          System_Boundary(b2, "BankBoundary2") {
            System(SystemA, "Banking System A")
            System(SystemB, "Banking System B", "A system of the bank, with personal bank accounts. next line.")
          }

          System_Ext(SystemC, "E-mail system", "The internal Microsoft Exchange e-mail system.")
          SystemDb(SystemD, "Banking System D Database", "A system of the bank, with personal bank accounts.")

          Boundary(b3, "BankBoundary3", "boundary") {
            SystemQueue(SystemF, "Banking System F Queue", "A system of the bank.")
            SystemQueue_Ext(SystemG, "Banking System G Queue", "A system of the bank, with personal bank accounts.")
          }
        }
      }

      BiRel(customerA, SystemAA, "Uses")
      BiRel(SystemAA, SystemE, "Uses")
      Rel(SystemAA, SystemC, "Sends e-mails", "SMTP")
      Rel(SystemC, customerA, "Sends e-mails to")

      UpdateElementStyle(customerA, $fontColor="red", $bgColor="grey", $borderColor="red")
      UpdateRelStyle(customerA, SystemAA, $textColor="blue", $lineColor="blue", $offsetX="5")
      UpdateRelStyle(SystemAA, SystemE, $textColor="blue", $lineColor="blue", $offsetY="-10")
      UpdateRelStyle(SystemAA, SystemC, $textColor="blue", $lineColor="blue", $offsetY="-40", $offsetX="-50")
      UpdateRelStyle(SystemC, customerA, $textColor="red", $lineColor="red", $offsetX="-50", $offsetY="20")

      UpdateLayoutConfig($c4ShapeInRow="3", $c4BoundaryInRow="1")

C4 Container diagram (C4Container):

    C4Container
    title Container diagram for Internet Banking System

    System_Ext(email_system, "E-Mail System", "The internal Microsoft Exchange system", $tags="v1.0")
    Person(customer, Customer, "A customer of the bank, with personal bank accounts", $tags="v1.0")

    Container_Boundary(c1, "Internet Banking") {
        Container(spa, "Single-Page App", "JavaScript, Angular", "Provides all the Internet banking functionality to cutomers via their web browser")
        Container_Ext(mobile_app, "Mobile App", "C#, Xamarin", "Provides a limited subset of the Internet banking functionality to customers via their mobile device")
        Container(web_app, "Web Application", "Java, Spring MVC", "Delivers the static content and the Internet banking SPA")
        ContainerDb(database, "Database", "SQL Database", "Stores user registration information, hashed auth credentials, access logs, etc.")
        ContainerDb_Ext(backend_api, "API Application", "Java, Docker Container", "Provides Internet banking functionality via API")

    }

    System_Ext(banking_system, "Mainframe Banking System", "Stores all of the core banking information about customers, accounts, transactions, etc.")

    Rel(customer, web_app, "Uses", "HTTPS")
    UpdateRelStyle(customer, web_app, $offsetY="60", $offsetX="90")
    Rel(customer, spa, "Uses", "HTTPS")
    UpdateRelStyle(customer, spa, $offsetY="-40")
    Rel(customer, mobile_app, "Uses")
    UpdateRelStyle(customer, mobile_app, $offsetY="-30")

    Rel(web_app, spa, "Delivers")
    UpdateRelStyle(web_app, spa, $offsetX="130")
    Rel(spa, backend_api, "Uses", "async, JSON/HTTPS")
    Rel(mobile_app, backend_api, "Uses", "async, JSON/HTTPS")
    Rel_Back(database, backend_api, "Reads from and writes to", "sync, JDBC")

    Rel(email_system, customer, "Sends e-mails to")
    UpdateRelStyle(email_system, customer, $offsetX="-45")
    Rel(backend_api, email_system, "Sends e-mails using", "sync, SMTP")
    UpdateRelStyle(backend_api, email_system, $offsetY="-60")
    Rel(backend_api, banking_system, "Uses", "sync/async, XML/HTTPS")
    UpdateRelStyle(backend_api, banking_system, $offsetY="-50", $offsetX="-140")
nrktkt commented 1 year ago

@Ogglas I think those examples highlight my issue with mermaid's layout engine for c4 usage. The relationship lines are all over each other and the objects; making the diagram illegible.

Ogglas commented 1 year ago

@nrktkt I agree but with experimental support I do not expect much more. Relationship lines can be solved and I still think they are on the right track here

CraigLager commented 1 year ago

Really hoping for better C4 support soon. The experimental version is pretty close but is basically unusable at the component level.

pinghe commented 1 year ago

@Ogglas I think those examples highlight my issue with mermaid's layout engine for c4 usage. The relationship lines are all over each other and the objects; making the diagram illegible.

For now this is just an experimental chart. You can use UpdateRelStyle(from, to, ?textColor, ?lineColor, ?offsetX, ?offsetY) to adjust the position of the labels to temporarily solve part of the problem!

UpdateRelStyle(customerA, bankA, "red", "blue", "-40", "60") UpdateRelStyle(customerA, bankA, $offsetX="-40", $offsetY="60", $lineColor="blue", $textColor="red") UpdateRelStyle(customerA, bankA, $offsetY="60")

kepler commented 1 year ago

Having C4 model would be really helpful to keep things DRY.

hope this helps to give more clarity on the details of this feature

I think you'll need to be more specific in what you're looking for, because there's a fundamental mismatch of approach between Mermaid and the Structurizr DSL:

* 1 Mermaid definition = 1 diagram

* 1 Structurizr DSL definition = many diagrams

Is there any clarification and decision made on whether this will stay as the case or if there are plans on supporting 1 model => several diagrams/views?

kputh commented 1 year ago

Perhaps it's worth discussing what you'd like to see in such a feature. "Supporting the C4 model" could range from some pre-defined styles and shapes through to adding new keywords to the Mermaid syntax (like you see with C4-PlantUML, for example).

(1) I'd like to see a solution that decouples architecture model and view (diagram) like Structurizr does. It would allow me to reuse my architecture model across any number of diagrams. Something else I like about Structurizr is the low number of DSL primitives.

(2) Also, I'd like to have distinguishable syntax for "boxes and arrows". Preferably one that looks like the other Mermaid diagram syntaxes. At the moment the C4 syntax looks like this:

Person(customerA, "Banking Customer A", "A customer of the bank, with personal bank accounts.")
System(SystemAA, "Internet Banking System", "Allows customers to view information about their bank accounts, and make payments.")
BiRel(customerA, SystemAA, "Uses")

and I'd rather have something like this:

Person CustomerA : "Banking Customer A" "A customer of the bank, with personal bank accounts."
System SystemAA : "Internet Banking System" "Allows customers to view information about their bank accounts, and make payments."
CustomerA --> SystemAA : "Uses"

(3) Furthermore, there are some recommendations ("Notation, notation, notation") for C4 diagrams. When you measure the current state of C4 diagrams in Mermaid against these, all relationships should be unidirectional.

(4) Just a thought: is the Structurizr DSL open-source and can Mermaid parse this kind of language? Maybe you don't have to invent a whole new DSL and can use the architecture model part of the Structurizr DSL in C4 diagrams.

simonbrowndotje commented 1 year ago

(1) I'd like to see a solution that decouples architecture model and view (diagram) like Structurizr does.

@kputh ... why not just use Structurizr, or one of the similar tools that decouples model from view? For example:

(4) Just a thought: is the Structurizr DSL open-source

Both the Structurizr DSL and underlying Structurizr for Java library are open source.

kputh commented 1 year ago

@kputh ... why not just use Structurizr, or one of the similar tools that decouples model from view?

Well, it's about reach. Big software development platforms like GitHub, GitLab and Azure DevOps support Mermaid out of the box. If something like Structurizr ends up in Mermaid, it will be available on all of these platforms and any on-premises installation – without the administrative hassle and cost associated with adding plugins/extensions/whatever. I tested the current draft of Mermaid C4 diagrams on gist/GitHub – it works –, and I doubt anybody at GitHub lost any thought on supporting C4 diagrams.

CraigLager commented 1 year ago

What @kputh is detailing is exactly my issue at the moment. We have a very good mermaid plugin for Confluence, but to use C4 diagrams we need to use an alternative (none of which are very good and all incur an extra cost)

By the way @simonbrowndotje, love your work!!

simonbrowndotje commented 1 year ago

Cloning the Structurizr DSL requires porting ~20K lines of Java code, in addition to building any specific interactive diagram features (e.g. double-click to zoom) ... so I would hope that somebody is willing to financially sponsor such a large feature request.

Big software development platforms like GitHub, GitLab and Azure DevOps support Mermaid out of the box.

We have a very good mermaid plugin for Confluence

As I said before, a Structurizr to Mermaid export already exists (code), and it's bundled into the Structurizr CLI. It's relatively trivial to setup something like a GitHub Action that runs the CLI export command against a Structurizr DSL file to generate a collection of Mermaid definitions, which can then be committed to the repo and rendered as usual via GitHub, GitLab, Azure DevOps, your existing Confluence plugins, etc.

garethcthomasdev commented 10 months ago

Hi, I'm a big fan of both c4 and mermaid. I'm currently exporting component diagrams directly from code as part of our CI/CD process, and in the PlantUML world I make use of the element properties

like this

SetPropertyHeader("Class","Method") AddProperty("MyService","MyMethod") AddProperty("MyService","MyOtherMethod") Component(mycomponentname, "demo component", "", "implements interfaces X,Y, Z ", "cogs", "")

is there anything I can do to help implement the same in the Mermaidjs ?

Here's the relevant documentation

https://github.com/plantuml-stdlib/C4-PlantUML/blob/master/README.md#element-and-relationship-properties