D2 2. Special Object - swkim0128/PARA GitHub Wiki
Text & Code
Latex
Icons & Images
Add shape: image for standalone icon shapes
SQL Tables
Classes
Sequence Diagrams
Sequence diagrams are D2 objects
explanation: |md
# I can do headers
- lists
- lists
And other normal markdown stuff
|
λλΆλΆμ κ²½μ° D2λ μ€κ΅μ΄, μΌλ³Έμ΄, νκ΅μ΄μ κ°μ λΉλΌν΄ λ¬Έμλ₯Ό ν¬ν¨νμ¬ μ¬μ©νκ³ μΆμ μ΄λ€ μΈμ΄λ μ§ μ§μν©λλ€. μ¬μ§μ΄ μ΄λͺ¨μ§λ κ°λ₯ν©λλ€!
Latex μΈμ΄ λΈλ‘μ μ§μ νλ λ° latex
λλ tex
λ₯Ό μ¬μ©ν μ μμ΅λλ€.
plankton -> formula: will steal
formula: {
equation: |latex
\\lim_{h \\rightarrow 0 } \\frac{f(x+h)-f(x)}{h}
|
}
Latex λΈλ‘μ λν΄ μ£Όμν΄μΌ ν λͺ κ°μ§ μ¬νμ΄ μμ΅λλ€:
- μμ μμμ λ³Ό μ μλ―μ΄, μ΄μ€μΌμ΄ν λ¬Έμλ‘ μ¬μ©λλ
\
λ₯Ό μ΄μ€μΌμ΄νν΄μΌ ν©λλ€.\\
λ₯Ό μ¬μ©ν κ²μ μ°Έκ³ νμΈμ. - λΌν
λΈλ‘μ
font-size
μ€νμΌμ μ μ©νμ§ μμ΅λλ€. λμ λΌν μ€ν¬λ¦½νΈ λ΄μμ λͺ λ Ήμ΄λ₯Ό μ¬μ©νμ¬ μ€νμΌμ μ μ©ν΄μΌ ν©λλ€:\tiny{ }
\small{ }
\normal{ }
\large{ }
\huge{ }
- κΈ°μ μ μΌλ‘, μ΄κ²μ MathJaxλ₯Ό μ¬μ©νκ³ μμ΅λλ€. μ΄κ²μ μμ ν λΌν μ€κ° μλλλ€ (μμ ν λΌν μ€λ λ¬Έμ λ μ΄μμ μμ§μ΄ ν¬ν¨λ©λλ€). D2μ λΌν μ€ λΈλ‘μ μνμ μΈ νκΈ°λ²μ νμνκΈ° μν κ²μ΄λ©°, κΈ°μ‘΄ λΌν μ€ λ¬Έμμ νμμ μ§μνμ§ μμ΅λλ€. μ§μλλ λͺ¨λ λͺ λ Ήμ΄ λͺ©λ‘μ μ¬κΈ°λ₯Ό μ°Έμ‘°νμμμ€.
μΌλ°μ μΌλ‘, κΈ΄ ννμ ν
μ€νΈλ λ€μ΄μ΄κ·Έλ¨μ νΉμ μμμ μμΈν λ΄μ©μ μΆκ°ν©λλ€. near
ν€μλλ₯Ό μ¬μ©νμ¬ μ΄λ μμΉμ μΆκ°ν μ§ μ§μ ν μ μμ΅λλ€.
You can set near
to either
- the ID of another shape
- a constant value
aws: {
load_balancer -> api
api -> db
}
gcloud: {
auth -> db
}
gcloud -> aws
explanation: |md
# Why do we use AWS?
- It has more uptime than GCloud
- We have free credits
| {
near: aws
}
ν
μ€νΈκ° aws
λ
Έλ κ·Όμ²μ μμΉνκ³ gcloud
λ
Έλ κ·Όμ²μ μμΉνμ§ μλ κ²μ μ£Όλͺ©ν΄λ³΄μΈμ.
Important
POSSIBLE CONSTANT VALUEStop-left, top-center, top-right,center-left, center-right,bottom-left, bottom-center, bottom-right
title: |md
# A winning strategy
| { near: top-center }
poll the people -> results
results -> unfavorable -> poll the people
results -> favorable -> will of the people
μ½λ λΈλ‘μ νλ‘κ·Έλλ° μΈμ΄λ₯Ό md
μμ λ€λ₯Έ μΈμ΄λ‘ λ³κ²½
aws: {
load_balancer -> api
api -> db
}
gcloud: {
auth -> db
}
gcloud -> aws
explanation: |go
awsSession := From(c.Request.Context())
client := s3.New(awsSession)
ctx, cancelFn := context.WithTimeout(c.Request.Context(), AWS_TIMEOUT)
defer cancelFn()
| {
near: aws
}
μΌλΆ κ²½μ°μλ λ§ν¬λ€μ΄ ν
μ€νΈκ° νμνμ§ μμ μ μμ΅λλ€. μλ§λ λ§ν¬λ€μ΄μ΄ λ§μμ λ€μ§ μκ±°λ D2μμ μ¬μ©νλ GitHub μ€νμΌλ§μ μνμ§ μμ μλ μκ³ , λνμ λΉ λ₯΄κ² ν
μ€νΈλ‘ λ³κ²½νλ €κ³ ν μλ μμ΅λλ€. κ·Έλλ shape: text
λ‘ μ€μ νλ©΄ λ©λλ€.
title: A winning strategy {
shape: text
near: top-center
style: {
font-size: 55
italic: true
}
}
poll the people -> results
results -> unfavorable -> poll the people
results -> favorable -> will of the people
λ§μ½ TypeScriptλ₯Ό μμ±νλ κ²½μ° νμ΄ν κΈ°νΈ |
κ° μΌλ°μ μΌλ‘ μ¬μ©λ©λλ€. κ·Έλ λ€λ©΄ λ λ€λ₯Έ νμ΄ν ||
λ₯Ό μΆκ°νλ©΄ λ©λλ€.
my_code: ||ts
declare function getSmallPet(): Fish | Bird;
||
μ€μ λ‘ Typescriptλ ||
μ μ¬μ©νκΈ° λλ¬Έμ, κ·Έλ κ² νλ©΄ μλνμ§ μμ΅λλ€. κ³μ μ§νν©μλ€.
my_code: |||ts
declare function getSmallPet(): Fish | Bird;
const works = (a > 1) || (b < 2)
|||
μλ§λ μΌμ€ νμ΄νκ° μ¬μ©λλ μΈμ΄λ μλ리μ€κ° μμ κ²μ
λλ€. D2λ μ€μ λ‘ μ²« λ²μ§Έ νμ΄ν λ€μ μνλ²³, μ«μ, 곡백 λλ _
κ° μλ νΉμ κΈ°νΈλ₯Ό μ¬μ©ν μ μκ² ν΄μ€λλ€:
# Much cleaner!
my_code: |`ts
declare function getSmallPet(): Fish | Bird;
const works = (a > 1) || (b < 2)
`|
D2μλ λ€μκ³Ό κ°μ λΌν μ€ νλ¬κ·ΈμΈμ΄ ν¬ν¨λμ΄ μμ΅λλ€:
amscd plugin: {
ex: |tex
\\begin{CD} B @>{\\text{very long label}}>> C S^{{\\mathcal{W}}_\\Lambda}\\otimes T @>j>> T\\\\ @VVV V \\end{CD}
|
}
braket plugin: {
ex: |tex
\\bra{a}\\ket{b}
|
}
cancel plugin: {
ex: |tex
\\cancel{Culture + 5}
|
}
color plugin: {
ex: |tex
\\textcolor{red}{y} = \\textcolor{green}{\\sin} x
|
}
gensymb plugin: {
ex: |tex
\\lambda = 10.6\\,\\micro\\mathrm{m}
|
}
mhchem plugin: {
ex: |tex
\ce{SO4^2- + Ba^2+ -> BaSO4 v}
|
}
physics plugin: {
ex: |tex
\\var{F[g(x)]}
\\dd(\\cos\\theta)
|
}
multilines: {
ex: |tex
\\displaylines{x = a + b \\\\ y = b + c}
\\sum_{k=1}^{n} h_{k} \\int_{0}^{1} \\bigl(\\partial_{k} f(x_{k-1}+t h_{k} e_{k}) -\\partial_{k} f(a)\\bigr) \\,dt
|
}
Icons and images are an essential part of production-ready diagrams.
You can use any URL as value.
μμ΄μ½κ³Ό μ΄λ―Έμ§λ μ ν μμ°μ© λ€μ΄μ΄κ·Έλ¨μ νμμ μΈ λΆλΆμ λλ€.
κ°μΌλ‘λ μ΄λ€ URLμ΄λ μ¬μ©ν μ μμ΅λλ€.
my network: {
icon: https://icons.terrastruct.com/infra/019-network.svg
}
μμ΄μ½ λ°°μΉλ μλμ λλ€. λ μ΄μμ μμ§μ λ°λΌ κ³ λ € μ¬νμ΄ λ€λ₯΄μ§λ§, λΌλ²¨κ³Ό ν¨κ» μ‘΄μ¬νλμ§, 컨ν μ΄λμΈμ§ μ¬λΆ λ±μ΄ μμ΄μ½μ κ°λ¦¬μ§ μλλ‘ λ°°μΉνλλ° μν₯μ λ―ΈμΉ©λλ€. λ€μ λ€μ΄μ΄κ·Έλ¨μμλ 컨ν μ΄λ μμ΄μ½μ΄ μΌμͺ½ μλ¨μ μμΉνκ³ μ»¨ν μ΄λκ° μλ μμ΄μ½μ΄ μ€μμ μμΉνλ κ²μ λ³Ό μ μμ΅λλ€.
vpc: VPC 1 10.1.0.0./16 {
icon: https://icons.terrastruct.com/aws%2F_Group%20Icons%2FVirtual-private-cloud-VPC_light-bg.svg
style: {
stroke: green
font-color: green
fill: white
}
az: Availability Zone A {
style: {
stroke: blue
font-color: blue
stroke-dash: 3
fill: white
}
firewall: Firewall Subnet A {
icon: https://icons.terrastruct.com/aws%2FNetworking%20&%20Content%20Delivery%2FAmazon-Route-53_Hosted-Zone_light-bg.svg
style: {
stroke: purple
font-color: purple
fill: "\#e1d5e7"
}
ec2: EC2 Instance {
icon: https://icons.terrastruct.com/aws%2FCompute%2F_Instance%2FAmazon-EC2_C4-Instance_light-bg.svg
}
}
}
}
server: {
shape: image
icon: https://icons.terrastruct.com/tech/022-server.svg
}
github: {
shape: image
icon: https://icons.terrastruct.com/dev/github.svg
}
server -> github
D2μμλ sql_table
λͺ¨μμ μ¬μ©νμ¬ μν°ν°-κ΄κ³ λ€μ΄μ΄κ·Έλ¨(ERD)μ μ½κ² 그릴 μ μμ΅λλ€. λ€μμ μ΅μνμ μμ μ
λλ€:
my_table: {
shape: sql_table
# This is defined using the shorthand syntax for labels discussed in the containers section.
# But here it's for the type of a constraint.
# The id field becomes a map that looks like {type: int; constraint: primary_key}
id: int {constraint: primary_key}
last_updated: timestamp with time zone
}
SQL ν μ΄λΈ λͺ¨μμ κ° ν€λ νμ μ μν©λλ€. κ° νμ κΈ°λ³Έ κ°(μ½λ‘ λ€μμλ κ²)μ ν΄λΉ νμ μ νμ μ μν©λλ€.
κ° νμ μ μ½ μ‘°κ±΄ κ°μ ν΄λΉ SQL μ μ½ μ‘°κ±΄μ μ μν©λλ€. D2λ μΈμνμ¬ μ€μΌ μ μμ΅λλ€:
constraint | short |
primary_key | PK |
foreign_key | FK |
unique | UNQ |
νμ§λ§ μνλ μ μ½ μ‘°κ±΄μ μ€μ ν μ μμ΅λλ€. μΈμλμ§ μμΌλ©΄ λ¨μΆλμ§ μμ λΏμ λλ€.
λ ν μ΄λΈ κ° μΈλ ν€ μ°κ²°μ μ μνλ λ°©λ²μ μμμ λλ€:
objects: {
shape: sql_table
id: int {constraint: primary_key}
disk: int {constraint: foreign_key}
json: jsonb {constraint: unique}
last_updated: timestamp with time zone
}
disks: {
shape: sql_table
id: int {constraint: primary_key}
}
objects.disk -> disks.id
μ£Ό ν€ λλ μΈλ ν€ μμ 컀μλ₯Ό μ¬λ¦¬λ©΄ ν΄λΉ ν€κ° κ°μ‘° νμλλ κ²μ μ μ μμ΅λλ€.
λ€λ₯Έ λͺ¨λ λνλ€κ³Ό λ§μ°¬κ°μ§λ‘, sql_tables
μ 컨ν
μ΄λμ μ€μ²©μν€κ³ λ€λ₯Έ λͺ¨μμΌλ‘λΆν° μ£μ§λ₯Ό μ μν μ μμ΅λλ€. λ€μμ μμμ
λλ€:
cloud: {
disks: {
shape: sql_table
id: int {constraint: primary_key}
}
blocks: {
shape: sql_table
id: int {constraint: primary_key}
disk: int {constraint: foreign_key}
blob: blob
}
blocks.disk -> disks.id
AWS S3 Vancouver -> disks
}
D2 fully supports UML Class diagrams. Here's a minimal example:
D2λ UML ν΄λμ€ λ€μ΄μ΄κ·Έλ¨μ μμ ν μ§μν©λλ€. λ€μμ μ΅μνμ μμμ λλ€:
MyClass: {
shape: class
field: "[]string"
method(a uint64): (x, y int)
}
ν΄λμ€μ κ° ν€λ νλ λλ λ©μλλ₯Ό μ μν©λλ€.
νλ ν€μ κ°μ ν΄λΉ νλμ νμ μ λλ€.
(
λ₯Ό ν¬ν¨νλ λͺ¨λ ν€λ λ°ν νμ
μ΄ μλ λ©μλμ
λλ€.
κ°μ΄ μλ λ©μλ ν€λ λ°ν νμ μ΄ voidμ λλ€.
νλ/λ©μλ κ°μμ±μ λνλ΄λ UML μ€νμΌ μ λμ¬λ₯Ό μ¬μ©ν μλ μμ΅λλ€.
visiblity prefix | meaning |
none | public |
+ | public |
- | private |
# | protected |
λ€μ λ§ν¬λ₯Ό μ°Έμ‘°νμμμ€: https://www.uml-diagrams.org/visibility.html
λ€μμ μλ‘ λ€λ₯Έ κ°μμ±κ³Ό λ 볡μ‘ν μ νμ κ°λ μμμ λλ€:
D2 Parser: {
shape: class
# Default visibility is + so no need to specify.
+reader: io.RuneReader
readerPos: d2ast.Position
# Private field.
-lookahead: "[]rune"
# Protected field.
# We have to escape the # to prevent the line from being parsed as a comment.
\#lookaheadPos: d2ast.Position
+peek(): (r rune, eof bool)
rewind()
commit()
\#peekn(n int): (s string, eof bool)
}
"github.com/terrastruct/d2parser.git" -> D2 Parser
μνμ€ λ€μ΄μ΄κ·Έλ¨μ κ°μ²΄μ shape: sequence_diagram
μ μ€μ νμ¬ μμ±λ©λλ€.
shape: sequence_diagram
alice -> bob: What does it mean\nto be well-adjusted?
bob -> alice: The ability to play bridge or\ngolf as if they were games.
λ€λ₯Έ λꡬμ λ¬λ¦¬, μμλλ₯Ό μν΄ λ°°μμΌ ν νΉλ³ν κ΅¬λ¬Έμ΄ μμ΅λλ€. κ·μΉμ D2 μ 체μμ κ±°μ λμΌνλ©°, λ κ°μ§ μ£Όλͺ©ν λ§ν μ°¨μ΄μ μ΄ μμ΅λλ€.
μνμ€ λ€μ΄μ΄κ·Έλ¨μ μμ μμλ€μ μνμ€ λ€μ΄μ΄κ·Έλ¨ μ 체μμ λμΌν λ²μλ₯Ό 곡μ ν©λλ€.
μλ₯Ό λ€μ΄:
Office chatter: {
shape: sequence_diagram
alice: Alice
bob: Bobby
awkward small talk: {
alice -> bob: uhm, hi
bob -> alice: oh, hello
icebreaker attempt: {
alice -> bob: what did you have for lunch?
}
unfortunate outcome: {
bob -> alice: that's personal
}
}
}
μνμ€ λ€μ΄μ΄κ·Έλ¨ μΈλΆμμλ alice
μ bob
μ 컨ν
μ΄λ λ²μκ° λ€λ₯΄κΈ° λλ¬Έμ μ¬λ¬ μΈμ€ν΄μ€κ° μμ μ μμ΅λλ€. κ·Έλ¬λ shape: sequence_diagram
νμμ μ€μ²©λλ©΄ λμΌν alice
μ bob
μ μ°Έμ‘°ν©λλ€.
D2μ λ€λ₯Έ κ³³μμλ μμ κ°λ μ΄ μ‘΄μ¬νμ§ μμ΅λλ€. λ€λ₯Έ μ°κ²°μ μ μν νμ μ°κ²°μ μ μνλ©΄ μκ°μ μΌλ‘ λνλμ§ μμ μ μμ΅λλ€. κ·Έλ¬λ μμλμμλ μμκ° μ€μν©λλ€. λͺ¨λ κ²μ μ μνλ μμκ° λνλλ μμμ λλ€.
μ΄κ²μ λ°°μ°λ ν¬ν¨λ©λλ€. νΉλ³ν κ·Έλ£Ήμμ μ²μ λνλ λλ₯Ό μ μΈνκ³ λ λͺ μ μ μΌλ‘ λ°°μ°λ₯Ό μ μ ν νμλ μμ§λ§, νΉμ μμλ₯Ό μ μνλ €λ©΄ κ·Έλ κ² ν μ μμ΅λλ€.
shape: sequence_diagram
# Remember that semicolons allow multiple objects to be defined in one line
# Actors will appear from left-to-right as a, b, c, d...
a; b; c; d
# ... even if the connections are in a different order
c -> d
d -> a
b -> d
λ€λ₯Έ D2 κ°μ²΄μ λ§μ°¬κ°μ§λ‘, μ΄λ€μ ν¬ν¨, μ°κ²°, λΌλ²¨ λ³κ²½, μ¬μ€νμΌλ§ λ° λ€λ₯Έ κ°μ²΄μ λ§μ°¬κ°μ§λ‘ μ²λ¦¬λ μ μμ΅λλ€.
direction: right
Before and after becoming friends: {
2007: Office chatter in 2007 {
shape: sequence_diagram
alice: Alice
bob: Bobby
awkward small talk: {
alice -> bob: uhm, hi
bob -> alice: oh, hello
icebreaker attempt: {
alice -> bob: what did you have for lunch?
}
unfortunate outcome: {
bob -> alice: that's personal
}
}
}
2012: Office chatter in 2012 {
shape: sequence_diagram
alice: Alice
bob: Bobby
alice -> bob: Want to play with ChatGPT?
bob -> alice: Yes!
bob -> alice.play: Write a play...
alice.play -> bob.play: about 2 friends...
bob.play -> alice.play: who find love...
alice.play -> bob.play: in a sequence diagram
}
2007 -> 2012: Five\nyears\nlater
}
μ€ν¬μ μνμ€ λ€μ΄μ΄κ·Έλ¨ λ΄μμ μνΈμμ©μ μμκ³Ό λμ μ λ¬ν©λλ€.
μ‘ν°μ μ€μ²©λ κ°μ²΄λ₯Ό μ°κ²°νμ¬ μ€ν¬μ μ§μ ν μ μμ΅λλ€.
shape: sequence_diagram
alice.t1 -> bob
alice.t2 -> bob.a
alice.t2.a -> bob.a
alice.t2.a <- bob.a
alice.t2 <- bob.a
κ·Έλ£Ήμ μΌλ ¨μ λ€μ΄μ΄κ·Έλ¨ μ€ μΌλΆλ₯Ό λΌλ²¨λ§νλ λ° λμμ΄ λ©λλ€.
μ°λ¦¬λ λ²μ κ·μΉμ μ€λͺ
ν λ μ΄μ μμ μμ μ΄λ₯Ό λ³Ό μ μμμ΅λλ€. λ ꡬ체μ μΌλ‘ λ§νλ©΄, κ·Έλ£Ήμ΄λ μ무κ²κ³Όλ μ°κ²°λμ΄ μμ§ μμ§λ§ μ°κ²° λλ κ°μ²΄κ° ν¬ν¨λ sequence_diagram
λͺ¨μ λ΄λΆμ 컨ν
μ΄λμ
λλ€.
shape: sequence_diagram
# Predefine actors
alice; bob
shower thoughts: {
alice -> bob: A physicist is an atom's way of knowing about atoms.
alice -> bob: Today is the first day of the rest of your life.
}
life advice: {
bob -> alice: If all else fails, lower your standards.
}
λ ΈνΈλ μ°κ²°λ νλͺ©μ΄ μλ λ°°μ°μ λν΄ μ€μ²© κ°μ²΄λ₯Ό μ μνμ¬ μ μΈλ©λλ€.
shape: sequence_diagram
alice -> bob
bob."In the eyes of my dog, I'm a man."
# Notes can go into groups, too
important insight: {
bob."Cold hands, no gloves."
}
bob -> alice: Chocolate chip.
μ‘ν°μμ μκΈ° μμ μΌλ‘ μ ν-μ°Έμ‘° λ©μμ§λ₯Ό μ μΈν μ μμ΅λλ€.
shape: sequence_diagram
son -> father: Can I borrow your car?
friend -> father: Never lend your car to anyone to whom you have given birth.
father -> father: internal debate ensues
λ€λ₯Έ κ²κ³Ό λ§μ°¬κ°μ§λ‘ λͺ¨μκ³Ό μ°κ²°μ μ€νμΌλ§ν μ μμ΅λλ€. μ¬κΈ°μλ μΌλΆ λ©μμ§λ₯Ό μ μ μΌλ‘ λ§λ€κ³ λͺ¨μμ λ°°μ°μμκ² μ€μ ν©λλ€.
shape: sequence_diagram
scorer: { shape: person }
scorer.t -> itemResponse.t: getItem()
scorer.t <- itemResponse.t: item {
stroke-dash: 5
}
scorer.t -> item.t1: getRubric()
scorer.t <- item.t1: rubric {
stroke-dash: 5
}
scorer.t -> essayRubric.t: applyTo(essayResp)
itemResponse -> essayRubric.t.c
essayRubric.t.c -> concept.t: match(essayResponse)
scorer <- essayRubric.t: score {
stroke-dash: 5
}
scorer.t -> itemOutcome.t1: new
scorer.t -> item.t2: getNormalMinimum()
scorer.t -> item.t3: getNormalMaximum()
scorer.t -> itemOutcome.t2: setScore(score)
scorer.t -> itemOutcome.t3: setFeedback(missingConcepts)