Graphviz 소개

1. Graphviz 란?

http://www.graphviz.org 에서 개발중인 오픈소스 다이어그램 생성기입니다.

웹 버전은 http://viz-js.com 에서 보실수 있죠

Markdown 처럼 문서로 다이어그램을 표기하고자 하는 욕망은 개발자에게 항상 있습니다. Plantuml 도 있지만 좀더 유연한 그래프가 필요할때 Graphviz 를 사용할수 있습니다.

2. 기본 문법

graph	:	[ strict ] (graph | digraph) [ ID ] '{' stmt_list '}'
stmt_list	:	[ stmt [ ';' ] stmt_list ]
stmt	:	node_stmt
|	edge_stmt
|	attr_stmt
|	ID '=' ID
|	subgraph
attr_stmt	:	(graph | node | edge) attr_list
attr_list	:	'[' [ a_list ] ']' [ attr_list ]
a_list	:	ID '=' ID [ (';' | ',') ] [ a_list ]
edge_stmt	:	(node_id | subgraph) edgeRHS [ attr_list ]
edgeRHS	:	edgeop (node_id | subgraph) [ edgeRHS ]
node_stmt	:	node_id [ attr_list ]
node_id	:	ID [ port ]
port	:	':' ID [ ':' compass_pt ]
|	':' compass_pt
subgraph	:	[ subgraph [ ID ] ] '{' stmt_list '}'
compass_pt	:	(n | ne | e | se | s | sw | w | nw | c | _)

이걸 보고 바로 이해 하는 분은 없을겁니다.

3. 기본적인거 따라해보기

하나씩 따라해보죠

asciidoctor를 쓰시는 분은 asciidoctor-diagram 을 세팅하시고(Asciidoc을 이용한 기술 문서 작성 참고)

다음처럼 기술하시면 바로 그래프를 쓸수 있습니다.

[graphviz]
....
graph {
	a
}
....

3.2. 라벨 속성 주기

여기에서 a 는 그려질 노드의 id 입니다. 별도로 label을 주지 않으면 id를 label로 사용하죠

graph {
	a [label="Node A"]
}
diag 06ce4adc9352d6d1c2a44bceef73de86

이런식으로 각 노드에 [] 로 노드의 속성을 기술할수 있습니다.

3.3. 여러 노드 그리기

노드를 두개 그려 볼까요?

graph {
	a
	b
}
diag 7c53f5f5945af8753948896ba6e26174

당연히 둘다 라벨을 줄수 있습니다.

graph {
	a [label="Node A"]
	b [label="Node B"]
}
diag 51589103ef71c19926974ff7acde8579

3.4. 여러 속성

이번엔 색상 속성을 주어 볼까요?

graph {
	a [label="Node A" color=red]
}
diag d67b50981eb406b3b9d2d42018e7af8e

색상명을 주면 그래프의 색상이 변경됩니다

색상 이름 목록은 https://graphviz.gitlab.io/_pages/doc/info/colors.html 를 참고하세요

RGB 형태로 줄수도 있습니다.

graph {
	a [label="Node A" color="#FF0000"]
}
diag e9798d98c69e6c4950eb0dc9d6c34a7c
전체 속성 목록은 https://graphviz.gitlab.io/_pages/doc/info/attrs.html 에서 참고하시면 됩니다.

3.5. 노드 연결

그래프라 함은 서로 연결선이 있어야 하겠죠?

graph {
	a -- b
}
diag 949b966e263ae115bbb227ec8ba24caf

-- 좌 우에 노드를 기술해주면 됩니다.

3.6. 하나가 여러개에 연결될땐 어떻게 할까요?

graph {
	a [label="Node A"]
	b [label="Node B"]
	c [label="Node C"]
	a -- {b c}

}
diag e34a39a754bcbee5c1db0cbff5e691d0

4. 그럼 화살표는?

화살표를 가지는 그래프는 digraph 입니다.

digraph {
	a [label="Node A"]
	b [label="Node B"]
	a -- b
}
diag 21542f57913be647a4ee27a32f6fde2a

5. Edge 에 속성 주기

물론 graph 에서도 화살표를 표현할수는 있지만 기본적으로는 화살표를 표현하지 않습니다.

graph {
	a [label="Node A"]
	b [label=Node B]
	a -- b [dir="forward"]
}
diag ac443cf7a787ef5bd7f531df8b68cece

-- 로 표시된 것은 edge를 표시하는 것이며, edge에도 위처럼 속성을 줄수 있습니다.

6. 원은 질렸다 다른 모양은?

graph {
	a
	b [shape=box]
	c [shape=ellipse]
	d [shape=oval]
	e [shape=circle]
	f [shape=point]
	h [shape=diamond]
	i [shape=cylinder]
	j [shape=note]
	k [shape=tab]

}
diag 408623560980fb26b5f3e0eb829bec6a
다음 URL에서 지원하는 모든 Shape를 볼수 있습니다. https://graphviz.gitlab.io/_pages/doc/info/shapes.html#polygon

7. 난 기본으로 사강형을 쓰고 싶은데?

graph {
	# 이 그래프에서의 node 기본값 지정
	node [shape=box]

	a
	b
	c
	d
	e
	f
}
diag 1382930396022095c03b0e8c32d462b9

8. 묶음 처리는 어떻게?

graph {
	subgraph cluster01 {
		label="Cluster 1"
		a -- b
		a -- c
		b -- c
		c
	}
	subgraph cluster02 {
		d
		e
		f
	}
	# 서브그래프 를 벗어 나는 연결은 바깥쪽에 기술
	c -- d
}
diag 904c21b9a978146b8ccedee69da9edd9

9. b,c 가 같은 레벨이면 좋겠는데?

graph {
	subgraph cluster01 {
			a -- b
			a -- c
			b -- c
			{rank = same; b; c;}
	}
	subgraph cluster02 {
		d
		e
		f
	}
}
diag 4126a5bfbcf8c76f4921c3dda988483b

기본적으로 graphvis는 계층을 가지는 다이어그램을 그려주는 툴이므로, 같은 계층에 위치한 노드들을 나열하여 정리 할수 있다.

낮은 계층은 왼쪽 위, 높은 계층은 오른쪽 아래에 위치한다.

rank는 다음의 값을 가질수 있다.

  • "same" : 같은 계층에 위치한다.

  • "min": 제일 낮은 계층에 위치한다.

  • "source"

  • "max": 제일 높은 계층에 위치한다.

  • "sink": max와 같다.

rank 같은 속성은 괄호 안에 기술해야함

10. Class diagram을 그려야 하는데 화살표가 부족해

graph {
	# 기본값이  normal입니다.
	a -- b1 [dir="forward"]
	a -- b2 [dir="forward" arrowhead=normal]
	a -- c [dir="forward" arrowhead=onormal]
	a -- d [dir="forward" arrowhead=diamond]
	a -- e [dir="forward" arrowhead=odiamond]
	a -- f [dir="forward" arrowhead=vee]
	# 까치발 ^^
	a -- g [dir="forward" arrowhead=crow]
	a -- h [dir="forward" arrowhead=dot]
}
diag 9444834df7c867b1f2f980d8a3c1af7f

o 로 시작하면 비어있는 화살표가 됩니다.



옵션이 훨씬 더 많이 있습니다. https://graphviz.gitlab.io/_pages/doc/info/arrows.html 참조 하세요.

11. 점선을 쓰고 싶은데?

11.1. 노드를 변경할떄

graph {
	a [style=solid]
	b [style=dashed]
	c [style=dotted]
	d [style=bold]
	e [style=filled]
}
diag 46b41f352dc6fc0dc370e7ffd6b92b92

11.2. 연결선을 변경할떄

graph {
	a -- b0 [dir="forward" style=solid]
	a -- b1 [dir="forward" style=dashed]
	a -- b2 [dir="forward" style=dotted]
	a -- b3 [dir="forward" style=bold]

}
diag f2e6445bff4dc306798d757c65a5fa9d
더 많은 스타일은 https://graphviz.gitlab.io/_pages/doc/info/attrs.html#k:style 에서 참고 하세요

12. 연결선이 직선 말고는 없나?

digraph Line {
  graph [label="Line edges", splines=line, nodesep=0.8]
  node [shape=box]
  a->{b c}
  b->{d e}
  c->{f g}
}
diag 0c9770cc5bb30e67e6fbab6ce7f5c1d2
digraph Orthogonal {
  graph [label="Orthogonal edges", splines=ortho, nodesep=0.8]
  node [shape=box]
  a->{b c}
  b->{d e}
  c->{f g}
}
diag ec7b95571cbb085ca3f6429199bd627e
digraph Curved {
  graph [label="Curved edges", splines=curved, nodesep=0.8]
  node [shape=box]
  a->{b c}
  b->{d e}
  c->{f g}
}
diag 24236cb14d39f02af75334f5a156a115
Tags: diagram   graphviz