Spring

[Spring/Ajax] Chart.js로 차트 만들기 2

코북 2021. 11. 2. 18:29

 안녕하세요 코북입니다. 지난번 https://cobook.tistory.com/36 에서 Chart.js를 이용해 차트 만들기를 해봤었습니다. 그때는 DB에 넣은 값을 단순하게 보여주는 것이 끝이었다면 오늘은 DB에 있는 값들을 연산하여 차트로 만들어봤습니다. 작업 진행 순서는 다음과 같습니다.

 

  1. VO
  2. Mapper.xml
  3. Mapper Interface
  4. Controller
  5. JavaScript

1. VO

 사용할 변수에 맞춰 VO를 작성해줍니다.

package city.turtle.vo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class GraphVO {
	
	private int pos_seq;
	private String pos_type;
	private String pos_time;
	private int pos_count;
	private String mb_id;
	private String pos_time2;

}

2. Mapper.xml

 이 쿼리를 만든 목적은 1주일간 기록된 pos_count 데이터를 더하기 위함입니다. sum() 함수를 사용해 pos_count를 모두 더해 주었습니다. 바뀐 컬럼 명은 as pos_sum으로 재설정해 주었습니다. 사용자의 ID와 자세 유형에 따라 값을 받아오기 때문에 mb_id와 pos_type을 조건으로 하고 pos_time은 현재를 기준으로 7일 씩 가져옵니다. 최초로 가져오는 조건은 다음과 같습니다. 

between DATE_SUB(NOW(), INTERVAL 7 DAY) and DATE_SUB(NOW(), INTERVAL 0 DAY)

이제 여기서 7, 0이 14,7로 바뀌면 2주차 데이터를 가져올 수 있습니다. 마찬가지로 21,14로 바뀌면 3주차 데이터를 가져올 수 있게 됩니다. 반복되는 걸 보면 이제 감이 오실겁니다. order by pos_time으로 최근 시간(큰 수)을 나중에 가져오도록 설정했습니다.

<select id="countSum" resultType="int">
  select sum(pos_count) as pos_sum 
  from POSTURE 
  where mb_id=#{vo.mb_id} and pos_type=#{vo.pos_type}
  and pos_time between DATE_SUB(NOW(), INTERVAL #{num1}+7 DAY) and DATE_SUB(NOW(), INTERVAL #{num1} DAY) 
  order by pos_time;
</select>

3. Mapper Interface

 xml과 잘 연결될 수 있도록 변수들에 @Param을 설정해줍니다. 쿼리의 결괏값은 숫자이므로 리턴타입은 int로 하였습니다.

package city.turtle.service;

import java.util.List;
import org.apache.ibatis.annotations.Param;
import city.turtle.vo.GraphVO;

public interface GraphService {
	
	// 거북목, 눈깜빡임 카운트
	public List<GraphVO> countTurtle(GraphVO vo) throws Exception;
	
	// 주간 카운트
	public int countSum(@Param("vo")GraphVO vo, @Param("num1")int num1) throws Exception;

4. Controller

 Controller의 리턴 타입은 mapper를 실행해 받은 int 타입의 값을 리스트로 담을 것이기 때문에 List<Integer>로 설정했습니다. 사용자에게 받은 ID값과 post_type을 mapper에 넘겨줘야하기 때문에 변수는 GraphVO로 하였습니다. 1주 단위로 총 4주간의 데이터가 필요하기 때문에 쿼리에 들어가는 날짜(숫자)가 7씩 더해지는 것이 반복돼야 합니다. for문을 통해 리스트에 값을 반복적으로 넣어주면 될 것 같습니다. i는 0에서 시작해서 7씩 더해집니다. i는 21까지만 증가해야하기 때문에 22보다 작으면 반복문을 멈추도록 하겠습니다. 이제 int 타입 데이터를 담을 수 있는 List 객체를 하나 생성해줍니다. 객체에 add() 메소드를 통해 값을 넣어줬습니다. i가 0부터 시작하기 때문에 처음 불러오는 값이 가장 큰(최근) 값입니다. 저는 add(0, 값)으로 설정하여 이후로 불러오는 값들을 앞 자리에 위치 시켰습니다. 차트를 보여줄 때 왼쪽에 가장 오래된 값(작은 수)이 출력될 수 있도록 하기 위해서 입니다.

package city.turtle.web;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import city.turtle.service.GraphService;
import city.turtle.vo.GraphVO;

@Controller
public class GraphController {
	
  @Autowired
  private GraphService mapper;
    
  @RequestMapping("/countSum.do")
      public @ResponseBody List<Integer> countSum(GraphVO vo) throws Exception{  
      List<Integer> sumSum = new ArrayList<>();  
      for(int i =0; i <22;i+=7) {
          sumSum.add(0, mapper.countSum(vo, i));
      }  
      return sumSum;
  }		
}

5. JavaScript

 페이지가 로드될 때 getSumGraph 함수가 시작될 수 있도록 설정해줬습니다. getSumGraph함수가 실행되면 ajax통신이 실행됩니다. countSum.do에 요청을 보내면콜백 함수를 통해 json방식의 데이터를 받습니다. 미리 만들어둔 sumList 리스트에 받아온 데이터 값을 넣어줬습니다. data.data에 받아온 값을 넣어주면 차트가 그려집니다.

      $(document).ready(function(){ 
    		getGraph();  		
    		getSumGraph();
    	});      
        
      // 거북목 주간 합 그래프
      function getSumGraph(){
    	  let sumList = [];
    	  
    	  $.ajax({
    		  url: "${cpath}/countSum.do",
    		  type : "get",
    		  data : {mb_id:"${signIn.mb_id}", pos_type:"거북목"},
    		  dataType : "json",
    		  success: function(data){
/*     			  console.log(data);
    			  console.log(data[0]);
    			  console.log(data[1]); */
    			  for (let i =0; i<data.length; i++){
    				  sumList.push(data[i]);
    			  }
    			  /* console.log(sumList); */
    			  
    		      new Chart(document.getElementById("bar-chart"), {
    		    	    type: 'bar',
    		    	    data: {
    		    	      labels: ["4주 전","3주 전","2주 전","1주 전"],
    		    	      datasets: [
    		    	        {
    		    	          label: "월간 거북목",
                              backgroundColor: [
                                  //색상
                                  'rgba(255, 99, 132, 0.4)',
                                  'rgba(54, 162, 235, 0.4)', // 파란색
                                  /* 'rgba(255, 206, 86, 0.4)', */ // 노란색
                                  'rgba(255, 159, 64, 0.4)', // 주황색
                                  'rgba(153, 102, 255, 0.4)',
                                  'rgba(75, 192, 192, 0.4)' // 초록색
                              ],
                              borderColor: [
                                  //경계선 색상
                                  'rgba(255, 99, 132, 1)',
                                  'rgba(54, 162, 235, 1)', // 파란색
                                  /* 'rgba(255, 206, 86, 1)', */ // 노란색
                                  'rgba(255, 159, 64, 1)', // 주황색
                                  'rgba(153, 102, 255, 1)',
                                  'rgba(75, 192, 192, 1)' // 초록색
                              ],
                              borderWidth: 1, //경계선 굵기
    		    	          data: sumList
    		    	        }
    		    	      ]
    		    	    },
    		    	    options: {
    		    	      legend: { display: false },
    		    	      title: {
    		    	        display: true,
    		    	        text: '월간 거북목'
    		    	      }
    		    	    }
    		    	});
    		  },
    		  error:function(){
    			  alert("실패");
    		  } 			  
    	  }) // ajax
      } // getSumGraph

구현 화면

 구현 화면입니다. 

 

 

사용 기술

JavaScript, SpringMVC, MySQL

배운 점

 @Param을 통해서 Interface와 xml 사이에서 여러개의 변수들을 mapping시킬 수 있었습니다. add() 메소드를 사용하여 ArrayList에 값을 넣을 때 인덱스 설정을 할 수 있었습니다. 반복되는 코드들의 공통점을 찾아 반복문을 만들어 볼 수 있었습니다. 

 

 

 

본 글은 아래 링크의 내용을 참고하여 학습한 내용을 나름대로 정리한 글임을 밝힙니다.

ArrayList

https://coding-factory.tistory.com/551