Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
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 31
Tags
more
Archives
Today
Total
관리 메뉴

게으른 완벽주의자의 개발자 도전기

[chart] ApexChart.js를 활용하여 차트 만들기 (쿼리 데이터 넣기) 본문

Spring Boot

[chart] ApexChart.js를 활용하여 차트 만들기 (쿼리 데이터 넣기)

머리방울 2022. 12. 4. 21:55

ApexCharts.js - Open Source JavaScript Charts for your website

ApexCharts.js - Open Source JavaScript Charts for your website

ApexCharts is a a free and open-source modern charting library that helps developers to create beautiful and interactive visualizations for web pages.

apexcharts.com

1. Exploer Demos에 들어가서 원하는 디자인의 차트를 선택한다.

2. 원하는 차트 선택한 후 아래의 태그를 복사하여 js파일에 붙여 넣기

3. 차트 그리기 위한 태그 추가하기

html에 아래의 순서대로 태그를 추가한다!( 제이쿼리 실행 후 차트 태그가 실행되도록 순서 중요)

<!--제이쿼리 태그 추가 -->	
<script src="https://code.jquery.com/jquery-latest.min.js"></script>	
<!--차트 생성을 위한 태그 추가 -->	
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>

4. id 추가하여 차트 영역 지정

<div class="col-6">
    <div id="approvalKPI" style="max-width: 650px; margin: 35px auto;"></div>
</div>
<div class="col-6">
    <div id="probationChart" style="max-width: 650px; margin: 35px auto;"></div>
</div>

4. mapper에 chart 데이터를 위한 쿼리추가

나는 현재부터 7일전까지의 데이터 추출을 위하여 union all을 활용하여 데이터를 가져왔다.

<select id="showProbationChart" resultMap="probationCnt">
	SELECT COUNT(PROB_NO) AS PROB_NO_CNT
	      , COUNT(PROB_DATE) AS PROB_DATE_CNT
	      , TO_CHAR(SYSDATE - 7, 'YY.MM.DD') AS DAY   
	FROM ACADEMIC_PROBATION
	WHERE TO_CHAR(PROB_DATE, 'YYYYMMDD') = TO_CHAR(SYSDATE-7, 'YYYYMMDD')
	UNION ALL
	SELECT COUNT(PROB_NO) AS PROB_NO_CNT 
	      , COUNT(PROB_DATE) AS PROB_DATE_CNT
	      , TO_CHAR(SYSDATE - 6, 'YY.MM.DD') AS DAY  
	FROM ACADEMIC_PROBATION
	WHERE TO_CHAR(PROB_DATE, 'YYYYMMDD') = TO_CHAR(SYSDATE-6, 'YYYYMMDD')
	UNION ALL
	SELECT COUNT(PROB_NO) AS PROB_NO_CNT 
	      , COUNT(PROB_DATE) AS PROB_DATE_CNT
	      , TO_CHAR(SYSDATE - 5, 'YY.MM.DD') AS DAY    
	FROM ACADEMIC_PROBATION
	WHERE TO_CHAR(PROB_DATE, 'YYYYMMDD') = TO_CHAR(SYSDATE-5, 'YYYYMMDD')
	UNION ALL
	SELECT COUNT(PROB_NO) AS PROB_NO_CNT 
	      , COUNT(PROB_DATE) AS PROB_DATE_CNT
	      , TO_CHAR(SYSDATE - 4, 'YY.MM.DD') AS DAY    
	FROM ACADEMIC_PROBATION
	WHERE TO_CHAR(PROB_DATE, 'YYYYMMDD') = TO_CHAR(SYSDATE-4, 'YYYYMMDD')
	UNION ALL
	SELECT COUNT(PROB_NO) AS PROB_NO_CNT 
	      , COUNT(PROB_DATE) AS PROB_DATE_CNT
	      , TO_CHAR(SYSDATE - 3, 'YY.MM.DD') AS DAY    
	FROM ACADEMIC_PROBATION
	WHERE TO_CHAR(PROB_DATE, 'YYYYMMDD') = TO_CHAR(SYSDATE-3, 'YYYYMMDD')
	UNION ALL
	SELECT COUNT(PROB_NO) AS PROB_NO_CNT 
	      , COUNT(PROB_DATE) AS PROB_DATE_CNT
	      , TO_CHAR(SYSDATE - 2, 'YY.MM.DD') AS DAY   
	FROM ACADEMIC_PROBATION
	WHERE TO_CHAR(PROB_DATE, 'YYYYMMDD') = TO_CHAR(SYSDATE-2, 'YYYYMMDD')
	UNION ALL
	SELECT COUNT(PROB_NO) AS PROB_NO_CNT 
	      , COUNT(PROB_DATE) AS PROB_DATE_CNT
	      , TO_CHAR(SYSDATE - 1, 'YY.MM.DD') AS DAY   
	FROM ACADEMIC_PROBATION
	WHERE TO_CHAR(PROB_DATE, 'YYYYMMDD') = TO_CHAR(SYSDATE-1, 'YYYYMMDD')
	UNION ALL
	SELECT COUNT(PROB_NO) AS PROB_NO_CNT 
	      , COUNT(PROB_DATE) AS PROB_DATE_CNT
	      , TO_CHAR(SYSDATE, 'YY.MM.DD') AS DAY   
	FROM ACADEMIC_PROBATION
	WHERE TO_CHAR(PROB_DATE, 'YYYYMMDD') = TO_CHAR(SYSDATE, 'YYYYMMDD')
</select>
<select id="showStuOutChart" resultMap="stuOutCnt">
	SELECT COUNT(STU_OUT_NO) AS STU_OUT_CNT
	      , COUNT(STU_OUT_DATE) AS STU_OUT_DATE_CNT
	      , TO_CHAR(SYSDATE - 7, 'YY.MM.DD') AS DAY   
	FROM STU_OUT
	WHERE TO_CHAR(STU_OUT_DATE, 'YYYYMMDD') = TO_CHAR(SYSDATE-7, 'YYYYMMDD')
	UNION ALL
	SELECT COUNT(STU_OUT_NO) AS STU_OUT_CNT 
	      , COUNT(STU_OUT_DATE) AS STU_OUT_DATE_CNT
	      , TO_CHAR(SYSDATE - 6, 'YY.MM.DD') AS DAY  
	FROM STU_OUT
	WHERE TO_CHAR(STU_OUT_DATE, 'YYYYMMDD') = TO_CHAR(SYSDATE-6, 'YYYYMMDD')
	UNION ALL
	SELECT COUNT(STU_OUT_NO) AS STU_OUT_CNT 
	      , COUNT(STU_OUT_DATE) AS STU_OUT_DATE_CNT
	      , TO_CHAR(SYSDATE - 5, 'YY.MM.DD') AS DAY    
	FROM STU_OUT
	WHERE TO_CHAR(STU_OUT_DATE, 'YYYYMMDD') = TO_CHAR(SYSDATE-5, 'YYYYMMDD')
	UNION ALL
	SELECT COUNT(STU_OUT_NO) AS STU_OUT_CNT 
	      , COUNT(STU_OUT_DATE) AS STU_OUT_DATE_CNT
	      , TO_CHAR(SYSDATE - 4, 'YY.MM.DD') AS DAY    
	FROM STU_OUT
	WHERE TO_CHAR(STU_OUT_DATE, 'YYYYMMDD') = TO_CHAR(SYSDATE-4, 'YYYYMMDD')
	UNION ALL
	SELECT COUNT(STU_OUT_NO) AS STU_OUT_CNT 
	      , COUNT(STU_OUT_DATE) AS STU_OUT_DATE_CNT
	      , TO_CHAR(SYSDATE - 3, 'YY.MM.DD') AS DAY    
	FROM STU_OUT
	WHERE TO_CHAR(STU_OUT_DATE, 'YYYYMMDD') = TO_CHAR(SYSDATE-3, 'YYYYMMDD')
	UNION ALL
	SELECT COUNT(STU_OUT_NO) AS STU_OUT_CNT 
	      , COUNT(STU_OUT_DATE) AS STU_OUT_DATE_CNT
	      , TO_CHAR(SYSDATE - 2, 'YY.MM.DD') AS DAY   
	FROM STU_OUT
	WHERE TO_CHAR(STU_OUT_DATE, 'YYYYMMDD') = TO_CHAR(SYSDATE-2, 'YYYYMMDD')
	UNION ALL
	SELECT COUNT(STU_OUT_NO) AS STU_OUT_CNT 
	      , COUNT(STU_OUT_DATE) AS STU_OUT_DATE_CNT
	      , TO_CHAR(SYSDATE - 1, 'YY.MM.DD') AS DAY   
	FROM STU_OUT
	WHERE TO_CHAR(STU_OUT_DATE, 'YYYYMMDD') = TO_CHAR(SYSDATE-1, 'YYYYMMDD')
	UNION ALL
	SELECT COUNT(STU_OUT_NO) AS STU_OUT_CNT 
	      , COUNT(STU_OUT_DATE) AS STU_OUT_DATE_CNT
	      , TO_CHAR(SYSDATE, 'YY.MM.DD') AS DAY   
	FROM STU_OUT
	WHERE TO_CHAR(STU_OUT_DATE, 'YYYYMMDD') = TO_CHAR(SYSDATE, 'YYYYMMDD')

</select>

차트에서 사용하기 위해 VO를 새로 생성해주었고, resultMap도 추가해주었다.

<resultMap type="kh.study.NF.emp.vo.ProbationChartVO" id="probationCnt">
	<result column="PROB_NO_CNT" property="probNoCnt"/>
	<result column="PROB_DATE_CNT" property="probDateCnt"/>
	<result column="DAY" property="day"/>
</resultMap>

<resultMap type="kh.study.NF.emp.vo.StuOutChartVO" id="stuOutCnt">
	<result column="STU_OUT_CNT" property="stuOutCnt"/>
	<result column="STU_OUT_DATE_CNT" property="stuOutDateCnt"/>
	<result column="DAY" property="day"/>
</resultMap>

5. Ajax를 활용하여 데이터 보내기

@ResponseBody
@PostMapping("/showProbationStuOutChartAjax")
public Map<String,Object> showProbationStuOutChartAjax(){

  //차트에 넣을 데이터 조회하여 가져오기
  List<ProbationChartVO> probationData = empService.showProbationChart();
  List<StuOutChartVO> stuOutData = empService.showStuOutChart();

  //Map 데이터 담을 통 만들기
  Map<String,Object> probationStuOutChartMap = new HashMap<>();

  //쿼리 데이터를 필요한 형태로 가공해서 담을 통 만들기
  //학사경고 데이터
  List<Integer> probNoList = new ArrayList<>();
  List<Integer> probDateList = new ArrayList<>();
  List<String> dateList1 = new ArrayList<>();
  //제적 데이터
  List<Integer> stuOutNoList = new ArrayList<>();
  List<Integer> stuOutDateList = new ArrayList<>();
  List<String> dateList2 = new ArrayList<>();

  //학사경고 데이터를 List에 담아준다.
  for(ProbationChartVO e : probationData) {
      probNoList.add(e.getProbNoCnt());
      probDateList.add(e.getProbDateCnt());
      dateList1.add(e.getDay());
  }

  //제적 데이터를 List에 담아준다.
  for(StuOutChartVO e : stuOutData) {
      stuOutNoList.add(e.getStuOutCnt());
      stuOutDateList.add(e.getStuOutDateCnt());
      dateList2.add(e.getDay());
  }

  //List에 담은 데이터를 map에 저장한다
  probationStuOutChartMap.put("probNoList", probNoList);
  probationStuOutChartMap.put("probDateList", probDateList);
  probationStuOutChartMap.put("dateList1", dateList1);
  probationStuOutChartMap.put("stuOutNoList", stuOutNoList);
  probationStuOutChartMap.put("stuOutDateList", stuOutDateList);
  probationStuOutChartMap.put("dateList2", dateList2);

  //ajax return에 map데이터 보내기
  return probationStuOutChartMap;
}

6. JS에 ajax 데이터 가져오는 함수와 실제 차트 그리는 함수를 만든다.

//학사경고와 제적 차트 그리기 위한 데이터 가져오는 ajax 함수
function drawProbationChartAjax(){
	
	$.ajax({
		url: '/emp/showProbationStuOutChartAjax', //요청경로
		type: 'post',
		data: {}, //필요한 데이터
		success: function(probationStuOutChartMap) {
			//console.log(probationStuOutChartMap);
            //실제 차트 그려줄 함수 실행(매개변수로 controller에서 return 받은 값 넣기
			drawProbationChart(probationStuOutChartMap);
		},
		error: function() {
			alert('실패');
		}
	})	
};

//실제 차트 그리기 위한 함수
function drawProbationChart(probationStuOutChartMap){
	 var options = {
          series: [{
            name: '학사경고',
          data: probationStuOutChartMap.probNoList //map데이터 삽입
        }, {
          name: '제적',
          data: probationStuOutChartMap.stuOutNoList //map데이터 삽입
        }],
          chart: {
          type: 'bar',
          height: 420  //높이 지정
        },
        plotOptions: {
          bar: {
            horizontal: false, //막대그래프 세울것인지(false) 눕힐것인지(true)
            dataLabels: {
              position: 'top',
            },
          }
        },
        dataLabels: {
          enabled: true,
          offsetX: -6,
          style: {
            fontSize: '12px',
            colors: ['#fff']
          }
        },
        stroke: {
          show: true,
          width: 1,
          colors: ['#fff']
        },
   		  title: {
        text: '2022년 2학기 학사경고 및 제적 건수',
        align: 'left',
		offsetX: 50,
        style: {
	         fontSize: '20px',
        }
        },
         colors: ['#90ee7e','#69d2e7'   //차트 색상 변경하기 위하여 추가함
        ], 
        tooltip: {
          shared: true,
          intersect: false
        },
        xaxis: {
          categories: probationStuOutChartMap.dateList1, //map에서 날짜데이터 삽입
        },yaxis: [{
			/*title: {			//y축 왼쪽 제목
				text: '학사경고',
				style: {
	            	fontSize: '18px',
          		}
			},*/}, {
			opposite: true,
			/*title: {		//y축 오른쪽 제목
				text: '제적',
				style: {
	            	fontSize: '18px',
          		}
			}*/
		}]
	 };

    var chart = new ApexCharts(document.querySelector("#probationChart"), options);
    chart.render();

7. 차트가 html화면이 열리면 실행될 수 있도록 JS파일 상단에 아래와 같이 추가한다.

drawProbationChartAjax();

8. 차트 실행화면