글의 작성 시각은 상동 23시 50분으로 초는 생략한다.
이러한 연유로 목적하는 글의 내용에 부합하지 않을 것이라 판단한 독자는 이 4줄의 글로 글을 계속 읽어나갈지 아니면 중단할지를 결정하기를 추천한다.
-------------------------------------------------(절취)-----------------------------------------------------------
각설, 필자는 본 Windows Presentation Foundation(이하 WPF)의 작업을 위하여 여럿 차트(Chart: 이하 차트)를 제공해주는 라이브러리를 검색하였다. 그 결과로 찾아낸 수많은 라이브러리(Library: 이하 LIB)들 중 비용에 상관없이 자유로이 사용 가능한 것, 기능을 다양하게, 그러면서도 적합하게 제공해 주는 것, 개발이 편한 것 등 기준을 기반으로 한 거르기 작업을 통해 다음 첫 문단을 시작하는 열린 자원 LIB(이하 Open Source;오픈소스)을 찾게 되었다. 물론 이 외의 수많은 무료 LIB가 있었으나 지면상 별도로 언급하거나 다루지는 않는다.
OxyPlot은 주소 http://www.oxyplot.org/에서 공식으로 배포 및 지원하고 있으며 현재까지 필자가 확인한 최신 버전은 글 작성일을 기준으로 동년 동월 18일로 게시되어 있다. 위 주소를 통해 확인한다면 본 코드는 매사추세츠 공과대학교 허가서(Massachusetts Institute of Technology License:이하 MIT license) 하에 허가되어 있으며 상업 목적으로 자유로이 사용가능하거니와 사용자 의지대로 맘껏 변조를 할 수 있다고 약술되어 있다. 이하 자세한 설명은 본 글의 지루도를 줄이기 위하여 해당 웹 페이지에 접속하여 확인하기를 청한다.
필자의 의견으로는 OxyPlot에 대한 문서화가 부실하다는 점이 치명적으로 느껴졌다. 물론 직접 소스코드가 제공되므로 이를 열람하여 모든 자료형 및 메서드 등의 정보를 적나라하게 확인할 수 있으나 이는 무척이나 피곤한 작업임이 틀림없기에 필자는 치명적이라 표현했다. 또한 제한점(한계)을 공식적으로 3가지를 들고 있다. 프로퍼티(차트에 속한 데이터) 혹은 컬렉션(차트에 속한 데이터의 집합)의 변경 통보 이벤트를 제공하지 않는다는 것과 영상(Animation)기능이 없는 것 그리고 Gradient(선형으로 배열된 색상)과 Hatch Brushes(교차된 평행선 무늬들 따위의 채색)을 지원하지 않는 것이 그들이다.
그러나 OxyPlot이 제공하는 확대, 축 변환 등의 화려하고도 넋을 빼앗길만한 기능을 생각한다면 얻지 못한 아쉬움으로 보아도 크게 무방하지 않으리라 생각한다.
서두를 마치고 본론을 시작하고자 한다. 그간 지루한 서론에 보답하기 위하여 이미지를 최대한 살려 작성하도록 하겠다. 그러나 전술한 바와 같이 본 글의 내용 특성상, 읽기에 눈이 그리 즐겁지는 않을 것이다. 그러나 글을 일부러 나누지 않은 것은 본 글이 본 글의 첫 시도임과 동시에 추후 개선점을 유도하기 위해서이다.
01. OxyPlot의 설치
본 글을 이해하기 위하여나 또는 위 OxyPlot을 사용하기 위하여는 관련 파일들을 참조(Reference)하여야 한다. 그러나 필자가 확인한 OxyPlot은 다중 플랫폼-재사용을 목적으로 하고 있으므로 그 관련된 파일들(.dll, .xml etc)이 단번에 세어지고 파악되어지기가 쉽지 않았다. 이에 이를 (확인한 바에 따르면)간편하게 처리해 주는 기능을 Visual Studio 2012(이하 VS12) 도구에서 제공해 준다하여 이를 소개하고자 한다.
NuGet(http://nuget.codeplex.com/)이 그 대망의 주인공이다. VS12에서 메뉴 중 [도구]에서 <라이브러리 패키지 관리자> 하위 메뉴를 선택하여 <솔루션용 NuGet 패키지 관리...>를 최종적으로 선택한다.
[그림 1]
우측 상단에 별도로 이미지에 수정을 가하지 않았으나 육안으로 확인되는 '만든사람:objo' 위에 문자열 입력란이 있다. [그림 1]과 같이 oxyplot을 대소문자 구분없이, 공백없이 입력한다. 그 결과 나온 화면이 [그림 1]이다. 사용할 패키지는(묶음이라 패키지라 표현하였다) WPF를 위한 것이기 때문에 [그림 1]에서 파란 영역으로 선택된 것과 같이 .Wpf로 끝나는 리스트박스 내의 항목을 클릭하고 [설치]를 누르면 된다. 문제는 그 설치 버튼이 [그림 1]에서는 보이지 않는다. 이에 [그림 2]를 붙인다.
[그림 2]
필요한 사람은 [그림 2]를 참고하면 되겠다. 그런데 문제가 발생했다.
[그림 3]
[그림 3-1] 콘솔로 시도했으나 실패한 장면
필자는 당혹감을 감출수가 없었다. 자세한 내용은 패키지 작성자에게 문의하라는, 친절하지만 사람을 흥분시키는 붉은색의 글씨를 천천히 읽고 작성자에게 문의할 방법을 찾기 시작했다. 답은 가까웠다. 다만 시간이 많이 소요되었을 뿐이다.
[그림 4]
개발 도구인 IDE(Integrated development environment)의 호환성(Compatibility; 필자의 번역 어휘 선택에 시비를 걸지 말기를 바란다)이 VS12에서는 Update 3 또는 그 이후에서 가능하다는 정보가 웹 페이지에 적나라하게 드러나 있었다. 필자가 사용하는 VS12의 버전을 한번 확인해보자.
[그림 5]
버전정보에 Update 1이라 당당히 문구가 박혀있다. 바람을 가르며 키보드를 잡고 Ctrl + T 조합키를 누르며(당시 크롬을 사용중이었다) 뒤이어 날숨이 다 나가기 전에 다음과 같은 문구를 입력해냈다.
[그림 6]
[그림 7]
위 연이은 [그림 6]과 [그림 7]은 필자가 업데이트를 서둘렀음을 알리는 것이다.
[그림 8]
타이머 기록 1:08:23 22' 시간이 흘러서야 [그림 8]과 같은 화면을 접했고 이후 OxyPlot을 문제 없이 설치할 수 있었다. 기쁘지 아니할 수 있었다.
[그림 9]
설치는 완료되었다. 누군가가 말했었다. 시작이 어렵다고.
02. Client 에 필요한 레이아웃을 위한 기능 사용법 분석
글읽기가 지루하다. 이에 잠깐 화제를 돌린다. 싫다.
필자는 팀장님으로부터 넘겨받은 자료를 토대로 필요한 기능을 분석해 보았다. 필요한 차트를 각각 기괴하리만큼 꺾일 수 있는 영역 그래프와 가지각색 초코파이 도표차트, 항목 차트에 꺾은선 그래프를 연동한 차트로 필자는 정의하겠다만 독자 입장에서 '대체 그게 무슨 그래프야'하는 의문을 가질 수 있음을 인지한 바 노파심에 백번 보는 것이 낫다는 선조들의 말을 받들어 선심을 쓰고자 한다.
[그림 10] [그림 11] [그림 12]
각각이 필자가 멋대로 묘사한 차트의 모습이다. 한번 보니 그래도 제법 훌륭한 묘사였다는 것이 실감난다.
[그림 10]에 해당되는 차트를 표기하는 것부터 시작하여 [그림 12]에 해당되는 글까지 쓰는 것으로 본 글은 끝난다. 그러니 조금만 더 인내하여 읽기를 바란다.
먼저 OxyPlot은 화면상에 동일하게 인터페이스를 표현하는데 있어서 대표적으로 하나에서 두가지의 방법을 제공한다. 첫째는 직접적으로 코드차원에서 접근하여 작성하는 방법이고 둘째는 Xaml을 이용하는 방법이다. 물론 전자는 데이터 모델링(용어는 추후 알게 된다)만을 코드상으로 제공할 뿐이다. 아쉽게도 후자의 방법을 사용할 수 없는 경우도 있는데 후에 차차 설명하겠다.
필자가 [그림 10]에 해당되는 차트를 표현하기 위해서는(물론 [그림 11]과 [그림 12]도 포함) 다음 개념을 알아야 했다.
1. 설치된 패키지의 이름경로(namespace)를 Window 태그 내에 Xaml 속성으로 추가해 주어야 한다는 것이다.
[그림 13]
[그림 13]에서 커서가 위치한 부분이 바로 그것이다. 필자는 아직 xmlns 속성에 대해 파악하진 못하였으나 저 한 줄을 추가하는 것이 중요하다는 것을 여기서 언급하겠다. [그림 13]에 대한 설명은 뒤에서 할 예정이다.
2. 데이터 바인딩을 위해 별도의 사용자(개발자)가 사용하는 이름공간을 명시해야 한다.
Xaml 파일상에 기재된 여러 태그(엘리먼트 혹은 컨트롤)들에 Cs파일상의 데이터 정보를 연동시키는 것을 WPF 세계에서 바인딩(Binding)이라 칭한다. 2번의 '명시'는 소스 코드상에서의 using 구문을 사용하는 것과 동일하다고 볼 수 있었다. 이는 [그림 13]에서 xmlns:local="clr-namesapce:OxyPlotTestProject"로 표기되어 있다. 물론 여기서 OxyPlotTestProject는 필자가 사용한 이름공간의 이름이므로 독자가 만에 하나라도 스스로 명시를 하고자 한다면 독자가 사용한 이름공간 이름을 사용해야 마땅하다.
3. OxyPlot에서의 Xaml 태그(이하 태그로 통일; 요소=엘리먼트=태그=컨트롤)를 사용할 때는 항상 접두어(?) oxy:가 붙는다. 또한 클래스들을 태그명으로 사용할 수 있는데 특정 태그는 정해진 부모 태그의 몸체 안에서만 사용이 가능하다는 것이다.
무슨 말인지 도무지 이해가 되지 않을 것이다. 필자가 필력이 좋지 못함에 혀만 내두르며 비판하는 것으로만 불만해소를 만족해 주었으면 한다.
[그림 10]에 해당되는 차트는 AreaSeries 하나로 해결된다.
먼저 [그림 13]에서 <Window.DataContext>로 된 부분(하단 3줄)을 살펴보길 바란다. 여기서 DataContext란 용어가 자주 등장한다. 이는 해당 Xaml에서 그 주인( . 앞에 있는 태그를 필자가 일부러 주인이라 표기하였다, 여기선 Window)이 참조할 Cs파일 상에서의 데이터 정보를 담고 있는 클래스를 지정하기 위한 속성명이라 보면 된다. [그림 13]에서 해당 태그 밑의 몸체로 <local: 로 시작하고 바로 클래스명을 입력하는 코드가 있는데 이를 주의하여 보길 바란다. 이와 같이 추가하는 것들이 DataContext가 될 것이다.
필자는 Cs파일에서 MainViewModel3이라는 클래스를 만들었다. 하품좀 하고 오겠다.
준비된 Xaml 파일은 다음과 같다.
[그림 14]
아 한숨좀 같이 쉬겠다. 필자는 이를 어찌 설명해야 하는지, 독자는 이를 언제 다 이해하여야 할지에 대한 고민으로 말이다.
[그림 13]까지의 내용은 거의 정형화된 내용이다. 중요한 것은 전술하였듯이 이름공간을 두 개 명시하는 것이다. 하나는 OxyPlot의 패키지이며 나머지 하나는 local에서 사용자(개발자)가 사용하는 이름공간이다.
[그림 15]
이 부분([그림 15])은 본 글의 목적을 벗어난다. 그러나 작성한다.
TabCotrol : [그림 16]에서와 같이 화면에 책갈피와 같은 기능을 추가하고자 할 때 쓰이며 [그림 15]에 들어간 Margin은 '양대환 선배(님)'의 글을 참고하길 바란다.
TabItem : [그림 16]에서 TabControl을 각각 구분하는, 하나의 책갈피에 해당된다고 보면 된다. 이 태그 몸체로 들어간 요소들은 해당 책갈피의 내용으로 들어가게 된다. Header 속성은 책갈피명이다.
[그림 16]
[그림 17]
위 [그림 17]의 예는 Xaml을 이용하여 화면 인터페이스를 구성하는 방법에 속한다. [그림 17]은 [그림 14]의 일부로 전혀 새 코드가 아니다. 다음은 이 방식의 일반적 접근방법이다.
가장 상위는 Plot으로 시작한다(물론 필수는 아니다).
그 하위에 바로 축을 먼저 정의한다(Series뒤에 축을 정의할 수 없다).
그 다음 Series를 정의한다.
태그명은 클래스 객체로 내부필드에 접근하듯이 '.'을 이용하여 연결하여 태그로 사용할 수 있다.
속성을 적절히 이용하여 차트를 구성한다.
데이터 삽입은 바인딩을 통해 구분한다.
필자는 성실하지 못하다. 이에 따로따로 설명하지 않고 [그림 17]과 같이 여러 Series를 한번에 융합하여 설명하려 한다. 그러려니 해도 좋다.
벌써 시간이 이렇게 되었는가. 다시 하품좀 하고 오겠다. 필자의 체력 저하를 이해해 달라는 뜻이다.
Legend는 다들 잘 아는 '범례'이다. 범례의 단어 뜻마저 모르는 자가 간혹 있었다. 그러나 이를 설명하는 것은 필자의 책임 밖이다. 혹 여기서 흐름상 Legend를 '전설, 설화'의 뜻으로 이해한 자는 없으리라.
경고: 이 이하는 지루할 수 있다. 중복된 속성명은 생략하였으며 필자가 표를 따로 정리하지 않아 가독성이 떨어지더라도 이해 바란다.
Plot
LegendPlacement : 범례를 차트 내부에 적용시킬 것인지 외부에 적용시킬 것인지 설정한다. 값 Inside/Outside 택1
LegendPosition : 범례를 표기할 위치를 지정한다. 값은 RightTop, LeftMiddle 등 종류가 많다.
LegendOrientation : 범례를 표시할 방향을 지정한다. 수직이 기본으로 적용된다. 값 Horizontal/Vertical 택1
Axes
CategoryAxis : [그림 16]에서 차트 표 하단에 있는 'Apples(빨강 과일)', 'Pears(주황 과일)', 'Bananas(노랑 과일)'과 같은 방식으로 카테고리(범주)별로 구분을 하고자 할때 쓰인다.
ItemsSource : 데이터를 바인딩하는데 쓰인다. '{'를 열고 Binding 이라는 예약어를 입력한 뒤 뒤이어 인자로 [그림 13]에서 local로 정의한 사용자 네임스페이스 내에서 접근 가능한 객체(인스턴스) 변수명을 그대로 적으면 된다. 그리고 '}'로 닫는다. 자세히 말하면 [그림 13]의 Window.DataContext 태그 몸체에 있는 <local:에 지정된 클래스 내 멤버변수들이 될 것이다.
LinearAxis : 가장 일반적인 축이다. [그림 16]에서 우측에 표기된 축을 담당한다. [그림 16]상의 수치들은 위 예제에서는 자동적으로 기입된 것이며 최대 숫자와 최소 숫자 범위를 직접 지정할 수도 있다.
MinimumPadding : 최소 간격이라 한다. 필자는 아직 파악 미숙이다.
AbsoluteMinimum: 절대적인 최소값이다. 이 이하의 값은 표시되지 않는다.
Position : 축의 위치를 지정한다. 생략 시 각 축의 특성에 알맞는 위치로 자동 배정된다. 중복될 경우 자동으로 조절되거나 오류를 내뱉는다.
Series
AreaSeries : 차트에 표현될 그래프를 영역으로 칠하여 표현하는 그래프의 한 종류이다.
Tiltle : 범례에 표기될 문자열이다.
DataFieldX : 그래프를 수평으로 칠하는 경우의 최좌단 경계로 이곳에 지정될 값은 필자가 파악하기 다소 어려웠다. 이 태그에 바인딩된 객체의 멤버이름이 값으로 들어간다 생각하면 된다. 이해가 될지 모르겠으나 [그림 17]에서 보이는 이 곳의 값 Time은 이 AreaSeries 태그에 바인딩된 객체인 Measurements의 내부 맴버변수이다.
DataFieldY: 그래프를 수직으로 칠하는 경우의 최하단 경계로 이곳에 지정될 값은 바인딩된 객체의 멤버변수명이다.
DataFieldX2: 경계 최우단이다.
DataFieldY2: 경계 최상단이다.
Fill : 영역의 색을 지정하는 것으로 이미 지정된 예약어(ex: green)를 지정하거나 색상코드(#00FF00)를 지정할 수 있다.
StrokeThickness : 보통 영역을 둘러싸는 경계선의 두께를 지정한다.
ColumnSeries : 필자를 상당히 헛갈리게 만든 부분으로 세로막대는 BarSeries가 아니라 ColumnSeries를 이용해야 했다.
ValueField: 바인딩된 데이터의 내부 변수명이 들어가되, 축에서 정의된 CategoryAxis에 바인딩된 데이터와 이곳에 바인딩된 데이터가 같음을 주목할 수 있다. 물론 같을 필요는 없으나 이것이 시사하는 바는 바인딩된 데이터내의 요소 갯수가 서로 같아야 한다는 것이다. 범주가 4개인데 반해 표시될 세로막대가 5개일 수 없는 노릇이다.
[그림 18] 하나는 범주가 없잖아..?
LineSeries : [그림 16]에서 빨강색으로 된 꺽은선 그래프를 표시할 때 사용가능하다.
MarkerType : 꺽은선 그래프의 선 모양을 결정한다. [그림 16]에서 중간중간에 다이아몬드가 들어간 것을 확인할 수 있다.
여기서 언급못한 속성도 상당하다. 그러나 본 글의 목적상 이 책임은 필자에게 있다.
자 이제 각각 [그림 17]에서 보인 바인딩된 데이터들의 실체를 본다. Window.DataContext에 지정한 클래스명을 기억하는가? 그렇다. MainViewModel3이다.
갑자기 코드 설명이 시작되어 당황했다면 다음을 생각하길 권한다. 지금까지 설명한 부분은 Xaml을 작성하는 것이었다. 실제로 이와 같이 작성하는 경우 파일은 반드시 2 부류 이상이 되게 되는데 하나는 Xaml이 되고 나머지 하나는 cs파일이다. 이 둘이 반드시 존재하게 된다. cs파일에는 데이터들 값들이 모두 들어가 있다. 그렇기에 이제 MainViewModel3 클래스를 살펴보고자 한다.
[그림 19] 별도 추가한 using 구문
[그림 19]를 유심히 본다. 그렇다. Java에서의 import 선언이다 C에서의 전처리기와 비슷한(거의 같은) 이유로 추가한 내용이다.
자 그러면 생성자를 살펴본다. (지면 한계상 전체 코드를 싣지 않는다)
[그림 20] 생성자 초기
우리가 본 바인딩 된 대상들(Title, Points)이 선언되어 있다. 그런데 변수 선언부가 안 보인다. 어떻게 생겼을까 안 궁금한가.
[그림 21] 선언부
너무나 평범하게 생겼다. 특히 Title의 경우는. 그런데 Points의 경우 List로 이루어져 있으며 그 내부 데이터구조가 DataPoint이다. 이는 OxyPlot 이름공간에 있는 클래스로 대부분 실수 2개를 인자로 받는다.
[그림 22]
다음으로 바인딩된 대상인 Items이다. 역시 평범하지 않다. 컬렉션이라 불리는 클래스의 객체를 Items에 대입 받는데 그 객체인 Collection의 내부가 Item이라는 보도듣도 못한 클래스로 지정되어 있다. 아 대체 또 언제까지 더 알아야 하는건가. 불평은 좋다. 그러나 한가지만 더 말하자면 필자 또한 언제까지 더 설명해야 하는가 고민이다. 그러니 서로 타협하자.
[그림 23]
또 하나의 바인딩된 대상인 Measurements... 키보드로 의미없는 문자를 초당 32타씩 눌렀다 지우고 하기를 3회, 참고 적는다. 무지 복잡하다. 그렇지만 위는 단지 그 값들을 초기화하기 위한 코드일 뿐이다(뿐이라고 했으니 제발 그냥 넘어가달라). 아래의 5줄만 제대로 보라. 항목에 추가하는 내용이 범상치 않다. 새 Measurement 뭐시기 클래스의 새 객체를 Add 메서드의 인자로 넣는데 그 객체 초기화 인자로 4개가 들어간다(이름명명 방식; 이름=값). 만일 독자 스스로 초기화 인자에 들어간 이름명명이 [그림 17]에서 바인딩된 대상의 맴버 변수명을 넣는다는 설명에 근거한(?) 값들과 이름이 같다는 것을 알았다면 스스로 박수쳐라. 가령 AreaSeries의 DataFieldX의 값과 [그림 23]의 아래서 6번째에 위치한 Time이라든가...
[그림 24] Items 프로퍼티 선언
역시 자료형만을 유심히 살피자.
[그림 25] 아 배고프다.
역시 자료형만을 유심히 살피자(2). 친절히 반복횟수도 표기하는 필자.
[그림 26] 드디어 등장한 Item 클래스
아까부터 뭔지 몰라 답답해 했을 Item이라는 클래스의 구조다. 내부 멤버로 Label, Value1~3을 가지는데 이도 역시 [그림 17]에서 바인딩된 데이터들의 멤버 변수명을 갖는다는 속성들의 값과 이름명명이 같음을 확인하자. ColumnSeries를 보자..
[그림 27] 드디어 등장!
Item과 마찬가지로 내부에 프로퍼티들이 선언되있다. 이 역시 프로퍼티 값들이 무엇과 비슷하다(이정도면 이제 유추하자).
약소하게 정리하면 Xaml로 View(화면에 보이는 부분)를 그리고 그에 대응되는 데이터들은 Cs파일과 같은 곳에서 정의하여 넣는다고 하겠다.
그렇게 하면 이후 코드 작성 전략이 눈에 훤히 들어온다.
지루한가.
마지막이다.
아니 저 글자가 마지막이란게 아니라... 마지막 부분이란 뜻이다.
필자가 가지각색의 몽쉘 차트인가라고 묘사한 차트가 있었다. 필자가 확인한 바에 따르면 아쉽게도 이 부류의 Pie 차트(원형 차트)는 Xaml을 적용한 방식으로 View(화면에 보이는 부분)을 처리하는 방법을 아직 제공하지 않고 있다.
그럼에도 불구하고 다른 라이브러리를 찾지 않고 이를 그대로 기록에 남기는 것은 굉장한 업데이트 주기에 곧 적용될 것이란 믿음과 더불어 이것이 지니는 장점을 더욱이 쓰고 싶었기 때문이다. 물론 여기까지 파악해 놓았는데 버리기 힘들었다.
아주 간단하게 끝난다. 이제 설명할 코드상에서 추가할 수 밖에 없는 이 방법은 Xaml에서 아주 간단히 작성된다.
[그림 28]
이거 한 줄이면 끝난다. 누가봐도 바인딩된 인자인 PieModel은 클래스 객체란 것을 알 수 없을 것이다. 소스 코드를 살핀다.
모든 소스 코드 사진은 같은 파일 내에 있다.
[그림 29] 바인딩 대상 선언부
설명은 하지 않는다.
[그림 30] 바인딩 대상의 적용부(핵심 부분)
이곳이 핵심이다. 필자가 사용하고자 하는 PieSeries를 먼저 인스턴스화하는 것이 급선무다. 그리고 나서 그 프로퍼티 중 Slices에 항목들을 추가해야 한다. PieSeries는 그 내부 자료들로 PieSlice라는 클래스를 이용하게 되는데 이 클래스의 멤버는 상당히 많다. 위 코드에서 ps.Slices.Add( 하는 부분이 있다. 이곳에 추가되는 부분을 설명한다.
PieSlice의 첫째 인자로 들어가는 것은 [그림 31]에서 확인하라.
PieSlice의 둘째 인자로 들어가는 것은 [그림 31]에서 비율로 나타나게 된다.
PieSlice의 이름명명으로 들어간 IsExploded 속성은 그 값이 참(True)일 경우 [그림 31]에서와 같이 원점에서 튀어나온 조각 모양을 하게 된다. 이는 ExplodedDistance에 따라 거리가 조절된다. [그림 30]에서 보면 이 값은 0.2로 들어간다.
[그림 30]의 PieSeries의 객체인 ps의 프로퍼티를 통한 값 설정 부분에서 InnerDiameter를 쓰게 되면 원형 차트는 도넛 차트가 된다. 독자는 항상 성격이 급하기 때문에 이를 [그림 32]에서 보인다. 이 값을 0.2로 변경한 결과이다.
Stroke는 각 부채꼴과 수치([그림 31]에서에 %값)들을 잇는 선의 색상이다. 검정색으로 설정하였다.
StrokeThickness는 각 부채꼴과 수치([그림 31]에서에 %값)들을 잇는 선의 굵기이다. 0.0으로 설정하여 보이지 않는다.
AngleSpan은 원형 차트의 100%기준을 정하는 것으로 180으로 지정하면 반원이 100%의 기준이 된다(그래프도 반원만 나온다).
StartAngle은 값의 0을 기준으로 할 각도를 degree로 나타내어 지정하면 된다.
[그림 31]
[그림 32] InnerDiameter 값을 0.2로 변경
[그림 32]에서는 StrokeThickness 또한 1.0으로 변경하여 각 부채꼴과 수치([그림 31]에서에 %값)들을 잇는 선이 검정색으로 표현되는 것을 알 수 있다.
03. 정리
다음부터는 이렇게 글을 쓰지 않을 것이다. 필자는 글을 쓰면서 많은 생각을 하게 되었다.
하얀색 글씨는 보고 싶은 독자에 한해서 읽으면 된다.
이상 두서 없는 글 마친다.
어서 자야지.
댓글 없음:
댓글 쓰기