Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic support for C4 model primitives. #508

Merged
merged 7 commits into from
Sep 5, 2022
Merged

Conversation

mbruggmann
Copy link
Contributor

@mbruggmann mbruggmann commented Apr 12, 2021

C4 is a model for visualizing software architecture. It defines a common terminology and a few core diagrams at different abstraction levels. We primarily use the System Landscape, System Context and Container diagrams so I started with just the entities needed for those.

For a definition like this:

from diagrams import Diagram
from diagrams.c4 import Person, Container, Database, System, SystemBoundary, Relationship

graph_attr = {
    "splines": "spline",
}

with Diagram("Container diagram for Internet Banking System", direction="TB", graph_attr=graph_attr):
    customer = Person(
        name="Personal Banking Customer", description="A customer of the bank, with personal bank accounts."
    )

    with SystemBoundary("Internet Banking System"):
        webapp = Container(
            name="Web Application",
            technology="Java and Spring MVC",
            description="Delivers the static content and the Internet banking single page application.",
        )

        spa = Container(
            name="Single-Page Application",
            technology="Javascript and Angular",
            description="Provides all of the Internet banking functionality to customers via their web browser.",
        )

        mobileapp = Container(
            name="Mobile App",
            technology="Xamarin",
            description="Provides a limited subset of the Internet banking functionality to customers via their mobile device.",
        )

        api = Container(
            name="API Application",
            technology="Java and Spring MVC",
            description="Provides Internet banking functionality via a JSON/HTTPS API.",
        )

        database = Database(
            name="Database",
            technology="Oracle Database Schema",
            description="Stores user registration information, hashed authentication credentials, access logs, etc.",
        )

    email = System(name="E-mail System", description="The internal Microsoft Exchange e-mail system.", external=True)

    mainframe = System(
        name="Mainframe Banking System",
        description="Stores all of the core banking information about customers, accounts, transactions, etc.",
        external=True,
    )

    customer >> Relationship("Visits bigbank.com/ib using [HTTPS]") >> webapp
    customer >> Relationship("Views account balances, and makes payments using") >> [spa, mobileapp]
    webapp >> Relationship("Delivers to the customer's web browser") >> spa
    spa >> Relationship("Make API calls to [JSON/HTTPS]") >> api
    mobileapp >> Relationship("Make API calls to [JSON/HTTPS]") >> api

    api >> Relationship("reads from and writes to") >> database
    api >> Relationship("Sends email using [SMTP]") >> email
    api >> Relationship("Makes API calls to [XML/HTTPS]") >> mainframe
    customer << Relationship("Sends e-mails to") << email

It produces a diagram like this:
container_diagram_for_internet_banking_system

The implementation is a bit different from the other resources which are auto-generated based on images as far as I understand. If you'd prefer a different approach or would rather not have this upstream in diagrams, let me know! I also wasn't sure how to best integrate this in the documentation, but we could figure something out if this is a feature you'd like to see.

Original discussion in #489.

@mbruggmann
Copy link
Contributor Author

@mingrammer Any thoughts on this?

@gabriel-tessier
Copy link
Collaborator

@mbruggmann
It's a good start I can help to add more feature and documentation but I still want to wait if @mingrammer is interested to add it in diagrams.
I also checked about C4 website and I think that is better to confirm that we can implement (i.e feasibility) more feature before adding any C4 support, otherwise we will have a poor implementation.
Maybe we can start by listing what can be done and a roadmap!
If it's not merged in this lib we can always start a fork! 😀

@BBartosz
Copy link

BBartosz commented May 18, 2021

Would be great to see c4 support in diagrams. @mbruggmann implementation looks promising, it has everything what is important

With the record shape we used before, graphviz would trip over
edges that set constraint=False.
This makes the code more DRY, but also allows to add company-
specific extensions more easily. One need we have is to slightly
adapt the terminology. At Spotify, we happen to call `Container`
a `Component` for example. This is now easier to implement on top
of the shared `C4Node`.
@BBartosz
Copy link

BBartosz commented Jun 2, 2021

@mbruggmann I dont know diagrams capabilities much but is it possible to make those components clickable and animated? So lets say you have your internet banking system as system boundary, one box. You double click it and it expands to more granular version like we see on screenshot you attached?

@clayms
Copy link

clayms commented Jun 2, 2021

@clayms
Copy link

clayms commented Jun 2, 2021

@BBartosz I don't know of any native animation capability in graphviz or the wrapper libraries. Have a look at this library which uses d3 to animate https://github.com/magjac/d3-graphviz#examples

I have not tested, but it looks like to create your graphs with this library, save the dot files, then use the magjac/d3-graphviz animation library on the dot files.

@mbruggmann
Copy link
Contributor Author

@BBartosz What we do is roughly like this:

  • Have an internal website where we host diagram pages
  • Diagram pages follow a known URL scheme to address each system/container/..., like my.internal.website/diagrams/container-id
  • Use the URL or href attributes in the diagram to create links to other pages, eg diagrams.c4.Container(..., href='my.internal.website/diagrams/container-id')
  • Render the diagrams to svg to retain the links

Currently this is set up using PlantUML but I don't see a reason why it wouldn't work using diagrams in a similar fashion. I haven't tried though.

@BBartosz
Copy link

BBartosz commented Jun 3, 2021

@mbruggmann Thats also possibility. Just have CI to generate graphs and put them into static page manually/have a script to do this. Something similar is done here: https://adrianvlupu.github.io/C4-Builder/#/?id=overview

@mingrammer mingrammer self-requested a review June 14, 2021 02:55
@mingrammer mingrammer added comp/cluster Issue of cluster component comp/edge Issue of edge component comp/node Issue of node component proposal Suggestion proposed status/need-to-review Need to review labels Jun 14, 2021
@mingrammer
Copy link
Owner

Great. I'll review this feature soon.

@dineshdh
Copy link

@mingrammer are you able to review this. I would love to see this feature asap

@venthur
Copy link

venthur commented Sep 2, 2021

Is the "view" part strictly separated from the "model"? I.e. can you create exactly one model and derive different views from that?

@mbruggmann
Copy link
Contributor Author

@venthur At the moment, no. The suggested implementation is purely about rendering one view. So if you wanted to model entities/relationships, you'd need to do that outside of diagrams and just use this in the rendering path.

@jonesy1234
Copy link

@mingrammer Any way we can help get this PR over the line as would love to use this natively?

@kaimallea
Copy link

Looking forward to this feature! I just bought @mingrammer 5 coffees. Maybe a little caffeine is all that's needed to help get this across the finish line. 😉

@mingrammer
Copy link
Owner

I'll review this feature this week!! Sorry for the really late review.

@kupolak
Copy link

kupolak commented Aug 6, 2022

Hi @mingrammer, any chance to review and merge it soon? 😄 It would be awesome!

Copy link
Owner

@mingrammer mingrammer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Sorry for the really late review. Thanks for the great contributions! ❤️

But, I have the last suggestion. Could you please add the documentation for C4 model support to diagrams docs, and update the README?

@mingrammer mingrammer removed the status/need-to-review Need to review label Aug 10, 2022
@mingrammer mingrammer added the status/accepted Accepted proposal label Aug 10, 2022
@mbruggmann
Copy link
Contributor Author

@mingrammer Cool, no worries. Documentation added!

Copy link
Owner

@mingrammer mingrammer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thank you for great contributing!

@mingrammer
Copy link
Owner

mingrammer commented Sep 5, 2022

I'm on work time. I'll release the new version tomorrow morning. (KST)

@mingrammer mingrammer merged commit 90dd239 into mingrammer:master Sep 5, 2022
@mingrammer
Copy link
Owner

[email protected] is now released.

ngruelaneo pushed a commit to aneoconsulting/diagrams that referenced this pull request Nov 25, 2022
* Basic support for C4 model primitives.

* Use the "rect" shape for nodes

With the record shape we used before, graphviz would trip over
edges that set constraint=False.

* Adopt C4 terminology: Rename Dependency -> Relationship

* Adopt C4 terminology: Rename type -> technology

* Extract a shared C4Node

This makes the code more DRY, but also allows to add company-
specific extensions more easily. One need we have is to slightly
adapt the terminology. At Spotify, we happen to call `Container`
a `Component` for example. This is now easier to implement on top
of the shared `C4Node`.

* Add "C4" shield to the README

* Document how to produce a C4 diagram
ajmaradiaga pushed a commit to ajmaradiaga/diagrams that referenced this pull request Nov 8, 2023
* Basic support for C4 model primitives.

* Use the "rect" shape for nodes

With the record shape we used before, graphviz would trip over
edges that set constraint=False.

* Adopt C4 terminology: Rename Dependency -> Relationship

* Adopt C4 terminology: Rename type -> technology

* Extract a shared C4Node

This makes the code more DRY, but also allows to add company-
specific extensions more easily. One need we have is to slightly
adapt the terminology. At Spotify, we happen to call `Container`
a `Component` for example. This is now easier to implement on top
of the shared `C4Node`.

* Add "C4" shield to the README

* Document how to produce a C4 diagram
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
comp/cluster Issue of cluster component comp/edge Issue of edge component comp/node Issue of node component proposal Suggestion proposed status/accepted Accepted proposal
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants