Mermaid 다이어그램 가이드 Part 2: Flowchart 심화 - Subgraph와 레이아웃 제어
이 글은 Claude Opus 4.5 을 이용해 초안이 작성되었으며, 이후 퇴고를 거쳤습니다.
Subgraph 기본#
Subgraph는 관련된 노드들을 논리적으로 그룹화하는 기능입니다. 시스템의 계층 구조나 도메인 영역을 시각적으로 구분할 때 유용합니다.
기본 문법#
flowchart TB
subgraph 그룹명
A --> B
end
C --> A
ID와 제목 분리#
Subgraph에 별도의 ID를 지정하면 참조가 쉬워집니다.
flowchart TB
subgraph api[API Layer]
A[Controller]
B[Service]
end
subgraph db[Data Layer]
C[(MySQL)]
D[(Redis)]
end
A --> B
B --> C
B --> D
Subgraph 방향 제어#
이것이 Mermaid 레이아웃의 핵심입니다. direction 키워드로 각 subgraph 내부의 배치 방향을 개별적으로 지정할 수 있습니다.
direction 키워드#
flowchart LR
subgraph TOP[상단 영역]
direction TB
A --> B --> C
end
subgraph BOTTOM[하단 영역]
direction TB
D --> E --> F
end
TOP --> BOTTOM
주의사항#
중요: Subgraph 내부의 노드가 외부 노드와 직접 연결되면, 해당 subgraph의 direction 설정이 무시되고 부모 flowchart의 방향을 따릅니다.
flowchart LR
subgraph sub1[Direction이 무시되는 경우]
direction TB
A --> B
end
B --> C
%% B가 외부 노드 C와 연결되어 direction TB가 무시됨
레이아웃 패턴 마스터하기#
패턴 1: 수평으로 나란한 그룹들 (메인 LR)#
전체는 좌→우로 배치하고, 각 그룹 내부는 위→아래로 배치합니다.
flowchart LR
subgraph Frontend[프론트엔드]
direction TB
F1[React App]
F2[Redux Store]
F3[API Client]
F1 --> F2 --> F3
end
subgraph Backend[백엔드]
direction TB
B1[API Gateway]
B2[Auth Service]
B3[Core Service]
B1 --> B2
B1 --> B3
end
subgraph Database[데이터베이스]
direction TB
D1[(PostgreSQL)]
D2[(Redis Cache)]
D1 --- D2
end
Frontend --> Backend --> Database
패턴 2: 수직으로 쌓인 그룹들 (메인 TB)#
전체는 위→아래로 배치하고, 각 그룹 내부는 좌→우로 배치합니다.
flowchart TB
subgraph Presentation[프레젠테이션 계층]
direction LR
P1[Web UI] --- P2[Mobile App] --- P3[Admin Panel]
end
subgraph Business[비즈니스 계층]
direction LR
B1[User Service] --- B2[Order Service] --- B3[Payment Service]
end
subgraph Data[데이터 계층]
direction LR
D1[(Users DB)] --- D2[(Orders DB)] --- D3[(Payment DB)]
end
Presentation --> Business --> Data
패턴 3: 3열 그리드 레이아웃#
flowchart TB
subgraph Row1[입력 처리]
direction LR
A1[HTTP 요청] --- A2[검증] --- A3[파싱]
end
subgraph Row2[비즈니스 로직]
direction LR
B1[인증] --- B2[권한확인] --- B3[처리]
end
subgraph Row3[출력 처리]
direction LR
C1[직렬화] --- C2[압축] --- C3[응답]
end
Row1 --> Row2 --> Row3
패턴 4: 중첩 Subgraph#
Subgraph는 중첩이 가능합니다.
flowchart TB
subgraph Cloud[AWS Cloud]
subgraph VPC[VPC]
subgraph Public[Public Subnet]
ALB[Application Load Balancer]
end
subgraph Private[Private Subnet]
EC2[EC2 Instances]
RDS[(RDS)]
end
end
end
User[사용자] --> ALB
ALB --> EC2
EC2 --> RDS
패턴 5: 마이크로서비스 아키텍처#
flowchart LR
Client[Client App]
subgraph Gateway[API Gateway]
direction TB
Kong[Kong]
Auth[Auth Middleware]
Kong --> Auth
end
subgraph Services[Microservices]
direction TB
subgraph Core[Core Domain]
direction LR
UserSvc[User Service]
OrderSvc[Order Service]
end
subgraph Support[Support Domain]
direction LR
NotifySvc[Notification]
LogSvc[Logging]
end
end
subgraph Data[Data Stores]
direction TB
MySQL[(MySQL)]
Redis[(Redis)]
Kafka[Kafka]
end
Client --> Gateway --> Services
Core --> Data
Support --> Kafka
Subgraph 간 연결#
Subgraph 자체를 노드처럼 연결할 수 있습니다.
flowchart LR
subgraph A[서비스 A]
A1 --> A2
end
subgraph B[서비스 B]
B1 --> B2
end
subgraph C[서비스 C]
C1 --> C2
end
A --> B
B --> C
A --> C
내부 노드와 외부를 연결할 수도 있습니다.
flowchart LR
subgraph Producer[Producer]
P[메시지 생성]
end
Queue[(Message Queue)]
subgraph Consumer[Consumer]
C[메시지 처리]
end
P --> Queue --> C
스타일링#
classDef로 스타일 정의#
flowchart LR
classDef primary fill:#4F46E5,stroke:#3730A3,color:white
classDef secondary fill:#10B981,stroke:#059669,color:white
classDef danger fill:#EF4444,stroke:#DC2626,color:white
classDef database fill:#F59E0B,stroke:#D97706,color:black
A[시작]:::primary --> B[처리]:::secondary
B --> C{조건}
C -->|성공| D[(저장)]:::database
C -->|실패| E[에러]:::danger
여러 노드에 스타일 적용#
flowchart LR
classDef serviceStyle fill:#E0E7FF,stroke:#4F46E5
A[Service A]
B[Service B]
C[Service C]
class A,B,C serviceStyle
A --> B --> C
연결선 스타일링#
flowchart LR
A --> B --> C --> D
linkStyle 0 stroke:#ff3,stroke-width:4px
linkStyle 1 stroke:#3f3,stroke-width:2px
linkStyle 2 stroke:#33f,stroke-width:2px,stroke-dasharray:5
linkStyle 뒤의 숫자는 0부터 시작하는 연결선의 순서입니다.
default 클래스#
default라는 이름의 클래스는 모든 노드에 자동 적용됩니다.
flowchart LR
classDef default fill:#f9f9f9,stroke:#333,stroke-width:1px
A --> B --> C
실전 예제: 주문 처리 시스템#
flowchart TB
classDef userAction fill:#DBEAFE,stroke:#3B82F6
classDef process fill:#D1FAE5,stroke:#10B981
classDef decision fill:#FEF3C7,stroke:#F59E0B
classDef data fill:#E0E7FF,stroke:#6366F1
classDef error fill:#FEE2E2,stroke:#EF4444
subgraph Client[클라이언트]
direction LR
Order[주문 요청]:::userAction
end
subgraph OrderService[주문 서비스]
direction TB
Validate[주문 검증]:::process
CheckStock{재고 확인}:::decision
Reserve[재고 예약]:::process
NoStock[재고 부족]:::error
end
subgraph PaymentService[결제 서비스]
direction TB
Payment[결제 처리]:::process
PayResult{결제 결과}:::decision
PayFail[결제 실패]:::error
end
subgraph FulfillmentService[배송 서비스]
direction TB
Ship[배송 준비]:::process
Notify[알림 발송]:::process
end
subgraph DataStores[데이터 저장소]
direction LR
OrderDB[(주문 DB)]:::data
InventoryDB[(재고 DB)]:::data
EventBus[Event Bus]:::data
end
Order --> Validate
Validate --> CheckStock
CheckStock -->|있음| Reserve
CheckStock -->|없음| NoStock
Reserve --> Payment
Payment --> PayResult
PayResult -->|성공| Ship
PayResult -->|실패| PayFail
Ship --> Notify
Reserve --> InventoryDB
Payment --> OrderDB
Notify --> EventBus
보이지 않는 연결선으로 레이아웃 조정#
때로는 노드 배치를 원하는 대로 조정하기 위해 보이지 않는 연결선이 필요합니다.
flowchart LR
A --> B
B --> C
%% D를 C와 같은 높이에 배치하고 싶을 때
A ~~~ D
D --> E
~~~는 보이지 않는 연결선을 만듭니다. 렌더링 엔진에게 노드 간의 관계를 암시하여 배치를 조정합니다.
Configuration으로 전역 설정#
YAML frontmatter로 다이어그램 전체 설정을 변경할 수 있습니다.
---
config:
flowchart:
curve: basis
defaultRenderer: elk
---
flowchart LR
A --> B --> C
주요 설정 옵션#
| 옵션 | 설명 | 기본값 |
|---|---|---|
curve |
연결선 곡선 스타일 | basis |
defaultRenderer |
렌더러 (dagre, elk) |
dagre |
nodeSpacing |
노드 간 간격 | 50 |
rankSpacing |
계층 간 간격 | 50 |
ELK 렌더러#
복잡한 다이어그램에서는 elk 렌더러가 더 나은 레이아웃을 제공하기도 합니다.
---
config:
flowchart:
defaultRenderer: elk
---
flowchart TB
subgraph A[Group A]
A1 --> A2 --> A3
end
subgraph B[Group B]
B1 --> B2 --> B3
end
A1 --> B1
A2 --> B2
A3 --> B3
레이아웃 제어 요약 치트시트#
| 원하는 결과 | 메인 방향 | Subgraph 내부 방향 |
|---|---|---|
| 그룹들이 가로로 나란히, 내부는 세로 | LR |
direction TB |
| 그룹들이 세로로 쌓임, 내부는 가로 | TB |
direction LR |
| 모두 가로로 | LR |
direction LR |
| 모두 세로로 | TB |
direction TB |
배치 원칙#
- 외부 연결 주의: Subgraph 내부 노드가 외부와 연결되면 direction이 무시됨
- Subgraph 단위 연결 권장: 복잡한 레이아웃에서는 subgraph 자체를 연결
- 보이지 않는 연결선 활용:
~~~로 배치 힌트 제공 - ELK 렌더러 시도: 기본 렌더러로 원하는 결과가 안 나오면 elk 사용
Read other posts