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"]
}
Diagram

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

3.3. 여러 노드 그리기

노드를 두개 그려 볼까요?

graph {
        a
        b
}
Diagram

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

graph {
        a [label="Node A"]
        b [label="Node B"]
}
Diagram

3.4. 여러 속성

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

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

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

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

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

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

3.5. 노드 연결

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

graph {
        a -- b
}
Diagram

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

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

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

}
Diagram

4. 그럼 화살표는?

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

digraph {
        a [label="Node A"]
        b [label="Node B"]
        a -- b
}
Diagram

5. Edge 에 속성 주기

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

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

-- 로 표시된 것은 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]

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

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

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

        a
        b
        c
        d
        e
        f
}
Diagram

8. 묶음 처리는 어떻게?

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

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

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

기본적으로 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]
}
Diagram

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]
}
Diagram

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]

}
Diagram
더 많은 스타일은 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}
}
Diagram
digraph Orthogonal {
  graph [label="Orthogonal edges", splines=ortho, nodesep=0.8]
  node [shape=box]
  a->{b c}
  b->{d e}
  c->{f g}
}
Diagram
digraph Curved {
  graph [label="Curved edges", splines=curved, nodesep=0.8]
  node [shape=box]
  a->{b c}
  b->{d e}
  c->{f g}
}
Diagram
Tags: diagram   graphviz