Notice
Recent Posts
Recent Comments
Link
«   2025/06   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Tags
more
Archives
Today
Total
관리 메뉴

구마찌의 이진수 여행기

[Javascript]Highcharts를 이용한 동적 그래프 그리기 본문

JAVA/Javascript

[Javascript]Highcharts를 이용한 동적 그래프 그리기

구마찌 2018. 8. 30. 18:05

1. HIGHCHARTS ?


여러가지 그래프들(선형 그래프, 막대 그래프, 원형 그래프)을 쉽게 이용할 수 있도록 제공된 API


> https://www.highcharts.com/



2. Parsing - 파싱 ?


사전적인 풀이는 엄청 어렵다. 


나는 사용할 파일이나 데이터를 내가 이용하기 위한 파일 / 데이터 형태로 바꿔주어 상황에 맞게 쓰게끔 만들어주는 행위


라고 쉽게 정의 내렸다. 



3. HIGHCHARTS 이해하기


찾아보니 그래프 오픈소스 중 Highcharts가 있었다. 한번도 다루지 않았기 때문에 api문서 보면서 각 클래스가 어떤 역할


을 하는지에 대해 아는 것이 중요했다. (사실상 이거 몰라서 거의 3~4일은 헤맸다...) 



> 출처 https://www.highcharts.com/demo/line-boost


나는 센서 데이터로부터 받게되는 진동 센서 데이터 CSV형태를 파싱해서 그래프에 동적으로 보여주고 싶었다.


그러기 위해서는 파동이 보이는 그래프를 사용해야했고, 이 그래프는 심지어 확대도 된다!


> 우리가 보게될 결과 화면 


일단, 그래프에 필요한게 무엇일까? (진동데이터는 '가속도계' 그래프를 기반으로 한다.)


X축은 어떤 것으로 잡을지, Y축은 어떤 것으로 잡을지, 결국에 내가 보여줘야하는 Value는 무엇인지 <구성


데이터는 어떻게 받아올지, 내가 받는 파일은 어떤 형식으로 파싱이 되어 있는지 < 대입할 값


진동파 그래프는 동적으로 보여줘야 하는데, 정적인 html파일로 어떻게 동적 구상을 보여줄지 < Perspective 




각각의 요소들을 highcharts에서는 위와 같이 괄호안의 방식으로 받고 있다. 


나는 이제 이 필드들을 가지고 그에 맞게 데이터를 넣어주면 된다.



4. Apply



데이터를 파싱했다. ( 파싱된 데이터는 String형태다. -Javascript는 기본형이 모두 var로 통일)


String 형태의 데이터를 가지고 그래프에 맞게 ( 정도를 나타내야 하니 정수형이나 숫자로 바꿔줘야 함 )


바꿔야 하기 때문에 어떤 형태에 담아야 한다. 여기서는 편하게 데이터 그릇 - 미리 담아두고 거쳐가는 곳 이라고 부른다.


데이터 그릇에서 하나씩 꺼내서 그래프에 맞게 넣어주어야 한다. 


하나씩 꺼낸다?


변수, 그러니까 하나의 value만 담을 수 있는 바구니에서 하나씩 꺼내기에는 너무 귀찮지 않을까? 


파싱한 데이터는 똑같은 데이터 형태를 가지고 있다. 똑같은 데이터는 한두개가 아니라 분명 여러개. 


이것을 잠시 담아두려면 배열이 좋지 않을까? 배열로 사용한다.


배열을 통해 그래프에서 하나씩 (어느 방법으로든) 꺼내서 값을 대입한다. 



4-1 데이터 가져오기 


> WebContent 아래에 data_1.csv와 test.html을 같이 뒀다



/* * 파일을 백그라운드에서 받기위한 Ajax */ function getLog() { $ .ajax({ url : 'data_1.csv', // 읽어올 파일의 경로 dataType : 'text',         // 읽어온 파일을 활용하기 위한 형태 success : function(data) { // ajax 성공시, var allRow = data.split(/\r?\n|\r/); // 띄어쓰기 단위로 구분 for (var singleRow = 0; singleRow < allRow.length; singleRow++) { collapse = allRow[singleRow].split(","); // 콤마 단위로 구분 for (var count = 0; count < collapse.length; count++) { textIn = collapse[count]; // 구분된 문자열을 문자 단위로 쪼개서 삽입 textLine = parseInt(textIn); // 그래프 파싱을 위해 Int형 변환         // console.log(textLine); arr.push(textLine); // 배열에 삽입 } } setTimeout(getLog, 60000); // refresh every 60 seconds } }); } getLog();                                // getLog() 실행



데이터 그릇에 몇번을 담았는지 모르겠다. 


띄어쓰기 구분 -> 콤마 구분 -> 구분해서 나온 문자 하나하나 -> Int형으로 바꾸기 -> 배열에 추가 -> 반복


반복을 왜 시키지 ? 나는 파일을 실시간으로 받아오고싶다. 실시간으로 받아오는 방법은 두가지가 있다. 내가 데이터를 


삽입한 사실을 파일이 알아서 마지막 읽은 구간부터 읽는 방법과, 파일을 리로드 하는 방법이 있다. 


첫번째는 파일이 인공지능이 아니기 때문에 불가능 하고, 두번째는 불필요한 데이터가 또 쓰인다. 또한 파일에 데이터가 


계속 쌓이게 되면서 파일은 크고 무거워진다. 파일을 읽는 시간은 점점 길어질 것이고 그것은 가늠할 수 없을만큼 커질 것


이다. 


하지만 파싱이 완료 되었고, 실시간 데이터가 계속 쌓이는지 보기 위해 나는 후자의 방법을 선택했다.



> 보완해야 할 사항  


많은 데이터들을 실시간으로 받아야 한다면 그 많은 양의 데이터를 한 파일에 담지 않고 파일을 세분화 시키면 된다.


파일 이름들을 sequence로 두고 변수에 담아 그 변수를 증가시키는 방법으로, 한 파일 다 읽고 다음 파일 Read하는 


방법이 있다. 하지만 데이터를 보내는 사람과 받는 사람이 다르고, 그에 해당하는 데이터가 다 다르기 때문에 파일을 


분할하게 되면 Read시점과 Out시점이 같아버리게 되는 경우가 생기는데, 이때는 데이터가 누락된다. 이 부분을 더 


생각해 봐야겠다.



4-2 X축에 들어갈 데이터 

/* * 현재 시간 받아오는 함수 */ function getTime() { var d = new Date(); var s = leadingZeros(d.getFullYear(), 4) + '-' + leadingZeros(d.getMonth() + 1, 2) + '-' + leadingZeros(d.getDate(), 2) + ' ' + leadingZeros(d.getHours(), 2) + ':' + leadingZeros(d.getMinutes(), 2); return s; }


X축에 해당하는 데이터는 시간이다. 현재에 해당하는 데이터를 보여주기 위해서는 현재 시간을 반복해서 받아야 한다.



4-3 그래프 및 Y축 데이터



Highcharts.chart('graph1', {

chart : { type : 'spline',     // 곡선형 그래프

zoomType : 'x', // x축 방향으로 그래프 그리기 가능 events : {          // 차트 이벤트 load : function() { var series = this.series[0]; // Series의 index 0을 대입 var i = 0; /* * 500ms단위로 데이터를 받아서 동적 그래프에 그려주기 위한 Interval함수 */ setInterval(function() { x = (new Date()).getTime(); // 현재 시간 y = arr[i]; // 파싱한 데이터 i++; // index값 증가 console.log("X Data insert : " + y); series.addPoint([ x, y ], true, true); // series에 데이터 추가 }, 500); // interval end }          // load end } // events end },          // charts end title : { text : 'vibrate graph' // 그래프 이름 }, subtitle : {

text : 'x' // 서브 타이틀 }, tooltip : { crosshairs : [ false, true ], // 특정 포인트를 짚으면 [x, y] 축 둘중 하나의 축에 대한 라인이 생긴다. valueDecimals : 2 // long형 데이터를 받기 위함 }, xAxis : { type : 'int' // x축 단위 }, yAxis : { labels : { formatter : function() { return this.value + ' dps';     // y축 단위 } // formatter end }, // labels end type : 'linear', // 선형 그래프 gridLineWidth : 1 // 선 굵기 }, /* * 데이터 -> 그래프 삽입 부분 */ series : [ { data : (function() { var data = [], time = (new Date()).getTime(), i; // 보여질 데이터, 시간, 반복문 인자 for (i = -19; i <= 0; i++) { data.push({ x : time + i * 1000 }); } return data; })(), lineWidth : 1,     // 라인 넓이 name : 'longitudinal wave'             // 데이터 이름 } ] });

파란색 부분은 해석을 잘 못하겠다. 아마 X축에 들어갈 수 있는 최대 데이터가 19개라서 19개부터 해준게 아닌가 싶다.


0부터 시작을 하면 그래프 맨 왼쪽부터 보여지고, 데이터가 20개 이상이 되면 동적으로 움직이게 된다. 


왼쪽으로 넘어가는 그래프라서 마이너스부터 시작하는 건가?



4-4 Container


<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>Insert title here</title>
</head>

<div id="graph1" style="height: 400px"></div> 			<!-- X그래프 -->
<div id="graph2" style="height: 400px"></div>			<!-- Y그래프 -->
<div id="graph3" style="height: 400px"></div>			<!-- Z그래프 -->


</body>
</html>

X,Y,Z 그래프 총 세개를 그려야 해서 container를 세개를 만들어 줬다. 



5. 정리


테스트용으로 하나의 csv파일을 가지고 세개의 그래프를 그려줬다. 정식 테스트는 해보지 않았지만 


데이터가 잘 나와서 너무 기뻤다! 코드도 잘 나오지 않았고 구조적인 생각도 참 어려웠다.


결과 화면은 3. 우리가 보게될 결과 화면 

'JAVA > Javascript' 카테고리의 다른 글

[Javascript]CSV 파일 읽어오기  (3) 2018.08.27
Comments