::NPTEAM:: Network Programer Team

검색 :
RSS 구독 : 글 / 댓글 / 트랙백 / 글+트랙백

글 검색 결과

프로그래밍/Graphviz
글 2개

AcroEdit로 편리하게 GraphViz 사용하기

Graphviz는 오픈소스 프로젝트로 DOT 언어로 그래프 형태로 변환해주는 프로그램이다.

Graphviz를 설치시 기본적으로 제공되는 GVedit를 이용하여 DOT 언어로 그래프를 표현할 수 있지만,
한국어를 지원하지 않는 단점이 있다.

프리웨어인 AcroEdit과 Graphviz를 연동하여 GVedit와 비슷한 환경을 만들어 보도록 하자.

준비물
1. AcroEdit 아크로 에디트(http://www.acrosoft.pe.kr)
위 3가지 프로그램을 다운로드 받아서 설치한다.


아크로 에디트가 인스톨된 폴더에 CommandCompile 폴더를 생성하고,

DotCompile.cmd 파일
을 생성한다.

DotCompile.cmd는 아래와 같이 작성한다.
1. dot.exe 파일 경로 수정
2. 이미지 뷰어 파일 경로 수정
@ECHO OFF
SET DOT_EXECUTE_PATH=C:\Program Files\Graphviz2.26.3\bin\dot.exe
SET DOT_INPUT_FILE=%1
SET EXPORT_FILE_NAME=%2
SET EXPORT_FILE_TYPE=png
SET EXPORT_FULL_PATH=%TEMP%\%EXPORT_FILE_NAME%.%EXPORT_FILE_TYPE%
"%DOT_EXECUTE_PATH%" -T%EXPORT_FILE_TYPE% -o"%EXPORT_FULL_PATH%" -Kdot "%DOT_INPUT_FILE%"

SET IMAGE_VIEWER=C:\Program Files\Google\Picasa3\PicasaPhotoViewer.exe
"%IMAGE_VIEWER%" "%EXPORT_FULL_PATH%"


아래와 같이 사용자 도구를 추가한다.
1. 메뉴이름 : Dot Compile
2. 명령 : DotCompile.cmd 파일의 절대경로
3. 인자 : %FULLNAME% %NAMEONLY%
4. 단축키 : F7


새 파일을 추가하고, 파일 형식을 UTF-8로 변경한다.

파일 -> 다른 이름으로 저장 -> 파일명.dot 로 저장한다.

DOT 언어 작성이 끝나면 단축키 F7을 눌러서 컴파일한다.

digraph G
{
    node [fontname="굴림" shape="record"]
    edge [fontname="굴림"]

    대기 -> "표 확인" [label="Step 1"]
    "표 확인" -> 대기 [label="Step 2 : 실패" fontcolor="red" color="red"]
    "표 확인" -> 통과 [label="Step 2 : 성공" fontcolor="blue" color="blue"]
    통과 -> 대기 [label="Step 3"]
}

결과 그래프는 아래와 같다.
2010/06/21 22:49 2010/06/21 22:49

맨 위로

Graphviz로 Uml 표현하기

Graphviz의 3요소
- graph(그래프)
- node(노드)
- edge(엣지)
위 3요소를 가지고 모든 그래프를 그릴 수 있다.

그래프(graph) : 방향성이 없는 그래프, 방향성을 포함한 그래프...
노드(node) : 그래프에서 보여지는 각각의 객체 ( 프로그래머 입장에서 이해하기 쉽도록 설명. )
엣지(edge) : 각 객체를 연결하는 선

우선 UML에서는 어떻게 매칭되는지 알아보자.
    1. 각각의 객체는 노드로 처리한다. - node
    2. 객체의 연관관계를 선(엣지)으로 표현한다. - edge
    3. 연관 관계에 방향성을 가져야 한다. - 방향성 있는 그래프(digraph)
이론상으로 1:1 매칭이 되기 때문에 UML을 표현할 수 있는 기반이 마련되었다.

그렇다면 이제 UML을 표현할 샘플을 구해야하는데...
객체지향을 배울때 많이 쓰는 CShape, CRect, CCircle, CTriangle을 표현해 보도록 하자.

우선 CShape는 도형을 추상화한 클래스이다.
CRect, CCircle, CTriangle은 CShape를 상속받은 클래스이다.
digraph Shape
{
	CRect -> CShape;
	CCircle -> CShape;
	CTriangle -> CShape;
}

아직 UML 모양은 갖추지 못했지만 최소한 CShape에서 상속받으려는 의도는 표시하였다.

이제 각 노드의 모양을 바꾸어보자.
digraph Shape
{
	node [ shape="record" ];
	CRect -> CShape;
	CCircle -> CShape;
	CTriangle -> CShape;
}
노드의 모양을 바꾸고 나니 화살표가 눈에 거슬린다.
UML에서는 상속을 받을때 안이 비어 있는 화살표를 사용하는 것이 원칙이다.
이번엔 각 edge 속성을 바꾸어 보자.
digraph Shape
{
	node [ shape = "record" ];
	edge [ arrowhead = "empty" ];
	CRect -> CShape;
	CCircle -> CShape;
	CTriangle -> CShape;
}
이제 어느정도 UML 모양새를 갖추기 시작하였다.
CShape public void draw() 함수를 만들고 각각 상속 받은 모양을 넣어보자.
digraph Shape
{
	node [ shape = "record" ];
	edge [ arrowhead = "empty" ];
	
	CShape [ label="{CShape||+ draw() : void\n}" ];
	
	CRect -> CShape;
	CCircle -> CShape;
	CTriangle -> CShape;
}
label : node의 이름을 재설정한다.
{ } :  태그로 묶은 부분을 하나의 Column으로 표시한다.
| : Row 단위로 나누기 위한 구분선을 표시한다.
\n : 다음 라인으로 넘긴다.
digraph Shape
{
	node [ shape = "record" ];
	edge [ arrowhead = "empty" ];
	
	CShape [ label="{CShape||+ draw() : void\n}" ];
	CRect [ label="{CRect||+ draw() : void\n}" ];
	CCircle [ label="{CCircle||+ draw() : void\n}" ];
	CTriangle [ label="{CTriangle||+ draw() : void\n}" ];
	
	CRect -> CShape;
	CCircle -> CShape;
	CTriangle -> CShape;
}
음... 상속까지 받았는데 뭔가 부족하다.
상속받은 클래스끼리 묶어서 그룹을 만들어 주자.
digraph Shape
{
	node [ shape = "record" ];
	edge [ arrowhead = "empty" ];
	
	CShape [ label="{CShape||+ draw() : void\n}" ];
	
	subgraph clusterDerivedObjectsFromCShape
	{
		label = "Derived Objects From CShape";
		
		CRect [ label="{CRect||+ draw() : void\n}" ];
		CCircle [ label="{CCircle||+ draw() : void\n}" ];
		CTriangle [ label="{CTriangle||+ draw() : void\n}" ];
	}
	
	CRect -> CShape;
	CCircle -> CShape;
	CTriangle -> CShape;
}
 
그룹핑을 하기 위해서 중요한 사항은 다음과 같다.
subgraph clusterXXX <-- cluster라는 이름으로 subgraph를 만들어야 한다.
{
    그룹으로 묶어줄 node들.
}
위와 같이 적용하면 그룹도 묶을 수 있다.

음... UML은 다 만들었는데... 꺼꾸로 뒤집혀 있어서 참 애매하다.
graphviz 는 항상  -> 화살표 방향으로 rank(순위)가 표현되기 때문에 CShape가 아래로 내려올 수 밖에 없다.
( <- 역방향 연산자는 지원하지 않는다. -_-; )

그렇다면 꺼꾸로 뒤집으면 될꺼 같은데... 다음과 같이 수정하면 된다.
digraph Shape
{
	rankdir = "BT"
	node [ shape = "record" ];
	edge [ arrowhead = "empty" ];
	
	CShape [ label="{CShape||+ draw() : void\n}" ];
	
	subgraph clusterDerivedObjectsFromCShape
	{
		label = "Derived Objects From CShape";
		
		CRect [ label="{CRect||+ draw() : void\n}" ];
		CCircle [ label="{CCircle||+ draw() : void\n}" ];
		CTriangle [ label="{CTriangle||+ draw() : void\n}" ];
	}
	
	CRect -> CShape;
	CCircle -> CShape;
	CTriangle -> CShape;
}

rankdir = BT 랭크 방향을 Bottom -> Top으로 꺼꾸로 뒤집으니 좀더 보기 좋은 그래프가 완성되었다.
Top = T
Bottom = B
Left = L
Right = R

위와 같이 상하좌우 방향을 바꿀 수 있으므로 각각의 옵션을 조절하면 된다.
2010/06/13 01:56 2010/06/13 01:56

맨 위로