Ayden's journal

D2 Diagram Language

D2 Diagram Language는 간결하고 직관적인 다이어그램을 생성할 수 있는 도메인 특화 언어다. D2는 특히 텍스트 기반으로 다이어그램을 그릴 수 있는 기능을 제공하여, 복잡한 그래픽 툴 없이 코드처럼 간단하게 다이어그램을 정의하고, 이를 자동으로 시각화할 수 있다.

주로 시스템 아키텍처, 플로우 차트, 클래스 다이어그램 등 다양한 다이어그램을 생성하는 데 사용되며, 코드와 같은 방식으로 다이어그램을 관리할 수 있어 버전 관리가 용이하다. 또한, D2는 매우 간결한 문법을 제공하여, 복잡한 시각적 요소를 쉽게 표현할 수 있도록 돕고, 개발자와 협업하는 데 유리한 도구이다.

아래의 명령줄을 입력하여 설치할 수 있으며, VS Code에서는 [ D2 ] 익스텐션을 사용하여 즉각적인 시각적 피드백을 받을 수 있다.

curl -fsSL https://d2lang.com/install.sh | sh -s --

 

변수

D2에서 변수는 노드, 엣지, 텍스트 등을 정의하는 데 사용될 수 있으며, 다이어그램을 구성하는 요소들의 값을 설정하는 방식으로 활용된다.

a
b
a -> b

 

변수에 콜론을 사용해 별칭을 붙여줄 수 있다

a: front end server
b: back end server
a -> b

 

 

변수 내에 shape 프로퍼티를 사용하여 상자의 모양을 지정해줄 수 있고, 변수 내에 변수를 선언하여 포함 관계를 구현할 수 있다.

a: front end server {
shape: cloud
nodejs {
shape: page
}
}
b: back end server
a.nodejs -> b

 

이런 식으로 코드 상자와 마크다운 상자를 구현할 수도 있다. 다만, 이 경우 shape 프로퍼티 등은 적용할 수 없는 듯하다.

code: |ts
const a: number = 1
|
explanation: |md
# I can do headers
- lists
- lists
And other normal markdown stuff
|

 

연결

D2는 네 가지 방식의 변수 연결을 지원한다. 이 연결 관계 또한 일종의 변수로 취급할 수 있다. 이 연결에서 앞에 오는 게 source이고 뒤에 오는 게 target이다.

  • --
  • ->
  • <-
  • <->
a: front end server
b: back end server
a -> b: modifies {
style.stroke-dash: 5
source-arrowhead: * ... 1
target-arrowhead: 1 {
shape: diamond
style.filled: true
}
}

 

SQL 테이블

D2에서 shape을 sql_table로 설정한다면 계체-관계 다이어그램(ERD)을 쉽게 나타낼 수 있다.

User: {
shape: sql_table
width: 500
id: String {constraint: [primary_key; unique;]}
role: Role
email: String {constraint: unique}
password: String
nickname: String {constraint: unique}
profileImage: String?
bio: String?
createdAt: DateTime
updatedAt: DateTime
report: Array<Report> {constraint: foreign_key}
reportLikes: Array<ReportLike> {constraint: foreign_key}
receivedNotification: Array<Notification> {constraint: foreign_key}
sentNotification: Array<Notification> {constraint: foreign_key}
comments: Array<Comment> {constraint: foreign_key}
}
Report: {
shape: sql_table
width: 500
id: String {constraint: [primary_key; unique;]}
title: String
content: String
tags: Array<String>
createdAt: DateTime
updatedAt: DateTime
userId: String
isbn13: String?
user: User {constraint: foreign_key}
userLiked: Array<ReportLike> {constraint: foreign_key}
book: Book? {constraint: foreign_key}
editorsPick: EditorsPick? {constraint: foreign_key}
comments: Array<Comment> {constraint: foreign_key}
Notification: Array<Notification> {constraint: foreign_key}
}
User.report -> Report.id

 

UML 클래스

D2에서 shape을 class로 설정한다면 UML 클래스 다이어그램을 쉽게 나타낼 수 있다.

Ihandler: <<interface>>\nIHandler {
shape: class;
handle(props HandleMethodProps\<T\>): string | null
}
RequiredHandler {
shape: class;
handle(props HandleMethodProps\<T\>): string | null
}
MinLengthHandler {
shape: class;
handle(props HandleMethodProps\<T\>): string | null
}
MaxLengthHandler {
shape: class;
handle(props HandleMethodProps\<T\>): string | null
}
Ihandler <- RequiredHandler {
style.stroke-dash: 5
}
Ihandler <- MinLengthHandler {
style.stroke-dash: 5
}
Ihandler <- MaxLengthHandler {
style.stroke-dash: 5
}
HandlerChain: HandlerChain<T extends InitState> {
shape: class;
-handlers: Array<IHandler<T>>
-handlerMap: Map<ValidateKey, IHandler<T>>
-setError: (action: Partial<T>) => void
addHandler(handlerKey ValidateKey): void;
doHandle(props HandleMethodProps\<T\>): void;
}
HandlerChain -> Ihandler {
style.stroke-dash: 5
target-arrowhead {
shape: arrow
}
}
블로그의 프로필 사진

블로그의 정보

Ayden's journal

Beard Weard Ayden

활동하기