Skip to content

Dynamic Diagram

A dynamic diagram shows how existing elements collaborate at runtime to implement a user story, use case, or feature. It is aimed at readers who need to understand interaction order without switching to a full sequence diagram.

Supported DSL Classes

Use DynamicDiagram with the element classes that participate in the runtime flow:

  • people, systems, containers, components, and their external variants
  • boundaries when they help locate the participating elements
  • portable Rel

The portable model records relationships in declaration order. PlantUML dynamic index helpers such as Index, LastIndex, and SetIndex are backend-owned helpers from c4.contrib.plantuml, not portable core features.

Portable Example

from c4 import DynamicDiagram, Person, Rel, System, SystemExt


with DynamicDiagram(title="Checkout flow") as diagram:
    customer = Person("Customer", "Places an order.")
    store = System("Online Store", "Accepts checkout requests.")
    payments = SystemExt("Payment Gateway", "Authorizes card payments.")

    customer >> Rel("1. Places order", "HTTPS") >> store
    store >> Rel("2. Authorizes payment", "REST API") >> payments
    payments >> Rel("3. Returns authorization result", "HTTPS") >> store

plantuml_source = diagram.as_plantuml()
mermaid_source = diagram.as_mermaid()

PlantUML enhanced example

Non-portable PlantUML example

This snippet uses PlantUML-only relationship direction, layout, styling, and index hints. Render it with the PlantUML rendering backend when keeping those hints.

The generated PlantUML example uses PlantUML-only relationship direction, layout, styling, and explicit relationship indexes.

from c4 import (
    DynamicDiagram,
    Person,
    Rel,
    System,
    SystemExt,
)
from c4.contrib.plantuml import (
    LayD,
    LayR,
    RelBack,
)
from c4.renderers import (
    PlantUMLRenderOptionsBuilder,
)


with DynamicDiagram(title='Order Fulfillment Flow') as diagram:
    customer = Person('Customer', 'Places orders in the online store.', plantuml={'tags': ['person', 'customer']}, alias='customer')

    online_store = System('Online Store', 'Customer-facing commerce platform.', plantuml={'tags': ['system', 'core'], 'type': 'Software System'}, alias='online_store')

    payment_gateway = SystemExt('Payment Gateway', 'External provider that authorizes card payments.', plantuml={'tags': ['system', 'external'], 'type': 'External System'}, alias='payment_gateway')

    warehouse_system = SystemExt('Warehouse System', 'External warehouse platform that reserves and ships items.', plantuml={'tags': ['system', 'external', 'fulfillment'], 'type': 'External System'}, alias='warehouse_system')

    customer >> Rel('Places order', technology='HTTPS', plantuml={'index': '1', 'tags': ['request']}) >> online_store
    online_store >> Rel('Authorizes payment', technology='REST API', plantuml={'index': '2', 'tags': ['payment_call', 'request']}) >> payment_gateway
    payment_gateway >> RelBack('Returns authorization result', technology='HTTPS', plantuml={'index': '3', 'tags': ['payment_call', 'response']}) >> online_store
    online_store >> Rel('Sends fulfillment request', technology='AMQP', plantuml={'index': '4', 'tags': ['fulfillment_call']}) >> warehouse_system
    warehouse_system >> RelBack('Confirms reservation', technology='AMQP', plantuml={'index': '5', 'tags': ['fulfillment_call', 'response']}) >> online_store
    LayR(customer, online_store)

    LayR(online_store, payment_gateway)

    LayD(payment_gateway, warehouse_system)


plantuml_render_options = (
    PlantUMLRenderOptionsBuilder()
    .layout_left_right()
    .show_legend(
        details='Normal',
    )
    .update_legend_title(
        'Dynamic Flow Legend',
    )
    .add_person_tag(
        tag_stereo='customer',
        bg_color='#08427B',
        font_color='#FFFFFF',
        border_color='#052E56',
        shadowing=False,
        legend_text='Customer actor',
    )
    .add_system_tag(
        tag_stereo='core',
        bg_color='#1168BD',
        font_color='#FFFFFF',
        border_color='#0B4884',
        shadowing=False,
        legend_text='Core internal system',
    )
    .add_external_system_tag(
        tag_stereo='external',
        bg_color='#999999',
        font_color='#FFFFFF',
        border_color='#6B6B6B',
        shadowing=False,
        legend_text='External system',
    )
    .add_rel_tag(
        tag_stereo='payment_call',
        text_color='#0B4884',
        line_color='#0B4884',
        legend_text='Payment interaction',
        line_style='BoldLine',
    )
    .add_rel_tag(
        tag_stereo='fulfillment_call',
        text_color='#1B5E20',
        line_color='#1B5E20',
        legend_text='Fulfillment interaction',
    )
    .add_rel_tag(
        tag_stereo='response',
        text_color='#6B6B6B',
        line_color='#6B6B6B',
        legend_text='Response message',
        line_style='DottedLine',
    )
    .update_element_style(
        element_name='person',
        font_color='#FFFFFF',
    )
    .update_element_style(
        element_name='system',
        font_color='#FFFFFF',
    )
    .update_rel_style(
        text_color='#222222',
        line_color='#444444',
    )
    .build()
)

diagram.set_render_options(
    plantuml=plantuml_render_options,
)

Renderer Behavior

PlantUML supports C4-PlantUML dynamic relationship indexes through plantuml={"index": ...} and helper values from c4.contrib.plantuml. Mermaid can render the common elements and relationships, but it does not support PlantUML dynamic index helpers or PlantUML layout helpers.

Generated Source and Image

Generated PlantUML source
@startuml
' convert it with additional command line argument -DRELATIVE_INCLUDE="relative/absolute" to use locally
!if %variable_exists("RELATIVE_INCLUDE")
    !include %get_variable_value("RELATIVE_INCLUDE")/C4_Dynamic.puml
!else
    !include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Dynamic.puml
!endif

AddPersonTag("customer", $bgColor="#08427B", $fontColor="#FFFFFF", $borderColor="#052E56", $shadowing="false", $legendText="Customer actor")
AddSystemTag("core", $bgColor="#1168BD", $fontColor="#FFFFFF", $borderColor="#0B4884", $shadowing="false", $legendText="Core internal system")
AddExternalSystemTag("external", $bgColor="#999999", $fontColor="#FFFFFF", $borderColor="#6B6B6B", $shadowing="false", $legendText="External system")
AddRelTag("payment_call", $textColor="#0B4884", $lineColor="#0B4884", $lineStyle=BoldLine(), $legendText="Payment interaction")
AddRelTag("fulfillment_call", $textColor="#1B5E20", $lineColor="#1B5E20", $legendText="Fulfillment interaction")
AddRelTag("response", $textColor="#6B6B6B", $lineColor="#6B6B6B", $lineStyle=DottedLine(), $legendText="Response message")

UpdateElementStyle("person", $fontColor="#FFFFFF")
UpdateElementStyle("system", $fontColor="#FFFFFF")
UpdateRelStyle($textColor="#222222", $lineColor="#444444")

LAYOUT_LEFT_RIGHT()
UpdateLegendTitle("Dynamic Flow Legend")

title Order Fulfillment Flow

Person(customer, "Customer", "Places orders in the online store.", $tags="person+customer")

System(online_store, "Online Store", "Customer-facing commerce platform.", $tags="system+core", $type="Software System")

System_Ext(payment_gateway, "Payment Gateway", "External provider that authorizes card payments.", $tags="system+external", $type="External System")

System_Ext(warehouse_system, "Warehouse System", "External warehouse platform that reserves and ships items.", $tags="system+external+fulfillment", $type="External System")

Rel(customer, online_store, "Places order", "HTTPS", $tags="request", $index=1)
Rel(online_store, payment_gateway, "Authorizes payment", "REST API", $tags="payment_call+request", $index=2)
Rel_Back(payment_gateway, online_store, "Returns authorization result", "HTTPS", $tags="payment_call+response", $index=3)
Rel(online_store, warehouse_system, "Sends fulfillment request", "AMQP", $tags="fulfillment_call", $index=4)
Rel_Back(warehouse_system, online_store, "Confirms reservation", "AMQP", $tags="fulfillment_call+response", $index=5)
Lay_R(customer, online_store)
Lay_R(online_store, payment_gateway)
Lay_D(payment_gateway, warehouse_system)

SHOW_LEGEND($details=Normal())

@enduml

Dynamic diagram