본문 바로가기

HTML5

[그래픽 처리] 그래프 렌더링/꺽은선 그래프/모눈종이




[그래픽 처리] 그래프 렌더링/꺽은선 그래프/모눈종이


꺽은선 그래프를 렌더링하는 프로그램에 대해 설명하기 전에 먼저 캔버스에 기준선을 렌더링 해보겠습니다.

[1] 모눈종이(눈금) 렌더링

배경을 그라데이션으로 렌더링한 후, 가로선과 세로선을 렌더링합니다.
for 문을 이용해 선긋기를 반복합니다.
캔버스의 width속성, height속성을 이용해 캔버스 크기에 맞춰 렌더링 합니다. 




10x10dml 모눈종이를 나타내기 위해 'grid_cols'와 'grid_rows' 값을 10으로 지정했습니다.
 for문을 통해 'col'이 'grid_cols' 값인 10 보다 작을 때 col에 하나씩 더해져 10까지 반복하게 합니다.
'row'도 마찬가지겠죠.   
그리고
'cell_height'은 height속성을 이용해 a_canvas.height/grid_rows(10이겠죠.)로 셀의 높이를 지정하고,
'var x = col*cell_height' 수식으로 col 값에 셀 높이를 곱해 눈금이 생성되게 합니다.
셀 너비도 마찬가지겠죠.
   





[2] 꺽은선 그래프 렌더링

어떤 상품의 매출 데이터(12개월/단위: 백만원)를 꺽은선 그래프로 나타내보겠습니다.
데이터는 아래와 같다고 봅니다.

 1월 2월  3월 4월 5월  6월  7월  8월  9월  10월  11월  12월 
 80 92  104  110  68  50  45  90  74  68  98   103


매출 데이터를 그래프의 좌표로 나타내기 위해 먼저 데이터의 최대값을 조사한 후 , 이 최대값을 기준으로 렌더링할 값의 좌표를 계산했습니다.

코드가 길어서 주석을 이용해 코드에 대해 설명하도록 하겠습니다.

//먼저 데이터를  준비합니다.
var uriage=[80,92,104,110,68,50,45,90,74,68,98,103];
drawChart(uriage);
//컨텍스트를 얻고은 후 배경을 렌더링 합니다.
var gradient=context.createLinearGradient(0,0,0,300);
gradient.addColorStop(0, "#e0e0e0");  //시작 지점의 인수를 0으로 지정해 제일 위에 회색을 띄고
gradient.addColorStop(1, "#ffffff");        //아래로 갈수록 흰색이 나오게 그라데이션 했습니다..
context.fillStyle=gradient;
context.fillRect(0,0,a_canvas.width,a_canvas.height);
//좌표
var grid_cols=data.length+1;   //데이터의 수에 따라 col 달라집니다.
var grid_rows=4;                   //grid_row 값을 4로 지정하고 보조선 렌더링 위해 for문을 사용해 고정시킵니다.
var cell_width=a_canvas.width/grid_cols;
var cell_height=a_canvas.height/grid_rows;
//배경의 보조선 렌더링
context.beginPath();
for (var row=0; row<=grid_rows; row++){     // 데이터 수가 달라져도 row수는 4로 고정이 되겠죠.
     var y = row*cell_height;
     context.moveTo(0,y);
     context.lineTo(a_canvas.width,y);
}
for (var col=0; col<=grid_cols; col++){         // 데이터 수가 달라지면 col 수 도 달라집니다.
     var x = col*cell_width;
     context.moveTo(x, 0);
     context.lineTo(x, a_canvas.height);
}
context.lineWidth=1;
context.strokeStyle="#c0c0c0";                   // 보조선의 색을 지정
context.stroke();
//데이터의 최대값을 먼저 조사합니다.
var max_v=0;                                                 //max_v에는 좌표의 최대값이 저장되어 있습니다.
for(var i=0; i<data.length; i++){
if (data[i]>max_v) max_v = data[i];
}
//최대값이 그래프를 벗어나지 않도록 값을 가산합니다.
max_v=max_v*1.1;                       
//데이터 플롯용 좌표
var points=[];
for(var i=0; i<data.length; i++){
var v=data[i];
var px=cell_width*(i+1);
var py=a_canvas.height-a_canvas.height*(v/max_v);     
points.push({"x":px, "y":py}); 
/**그래픽 좌표는 화면의 가장 위가 0, 아래로 내려갈수록 값이 커집니다.
구한 좌표(px,py)를 배열 변수 points에 추가합니다.
좌표를 배열 변수에 저장해 두는 이유는, **/                                   
}                                                                        
//선 그래프를 렌더링
context.beginPath();                                                    //먼저 각 좌표들을 선으로 연결한 후,
context.moveTo(points[0].x, points[0].y);
for(var i=1; i<points.length; i++){
context.lineTo(points[i].x, points[i].y);
}
context.lineWidth=2;
context.strokeStyle="Yellow";  //선은 노란색으로 지정했습니다.
context.stroke();
//좌표 플롯
for(var i in points){                                                       //각 좌표에 원을 그리기 위해서입니다.
var p=points[i];
context.beginPath();
context.arc(p.x,p.y,6,0,2*Math.PI);
context.fillStyle="#ee0000";  //원(점)은 빨강입니다.
context.fill();
}



총 종합한 코드의 모습입니다.







데이터의 수에 따라 col의 수가 달라지는 것을 확인해보세요.
데이터 수가 달라져도 row수는 변화하지 않습니다.

저는 아래와 같이 데이터를 변경해 보았습니다.

 

 var uriage=[1,2,3,4,3,2,1];  var uriage=[10,2,7];