2 minute read

파이널 프로젝트에서 구현했던 일별 거래액 변화 그래프

하단에 쓰여있는 날짜가 label이 되고, 값들이 data가 된다. Alt text

backend

나는 차트를 많이 그릴 계획이었어서, 따로 dto를 만들기로 했다. 다른 차트를 그릴 때도 쓸 수 있다.

@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class LabelDataDto {
	
	private String label;
	private long data;

}

쿼리

오늘을 기준으로 15일 동안의 일간 거래량을 나타내주는 쿼리이다. 참고로 이런 방식으로 쿼리를 짜면, 데이터가 없는 날짜에는 0으로 나타낼 수 있어서 그래프를 그리기 좋다. 이것을 응용하면 월별통계, 연별 통계도 가능하다.

 <!-- List<LabelDataDto> getTransactionAmountPerDay();-->
  <select id="getTransactionAmountPerDay" resultType="com.hoge.dto.LabelDataDto">
		SELECT SUBSTR(B.TODAY,-4) AS label, NVL(a.TRANSACTION_AMOUNT, 0) as data
		FROM (SELECT TO_CHAR(TRANSACTION_DATE, 'YYYYMMDD') AS TRANSACTION_DATE,
		SUM(TRANSACTION_AMOUNT) AS TRANSACTION_AMOUNT
		FROM TB_FINAL_TRANSACTIONS
        where TRANSACTION_TYPE=1
		GROUP BY TO_CHAR(TRANSACTION_DATE, 'YYYYMMDD')) A
		, (SELECT
		TO_CHAR (FIRST_DAY + LEVEL -1, 'YYYYMMDD') TODAY
		FROM (SELECT TRUNC(SYSDATE - 15) FIRST_DAY FROM DUAL)
		CONNECT BY FIRST_DAY + LEVEL - 1 &lt;= TRUNC(SYSDATE)
		) B
		WHERE B.TODAY = A.TRANSACTION_DATE(+)
		ORDER BY B.TODAY;
  </select>

컨트롤러

컨트롤러에서 이렇게 데이터를 보내준다.

@GetMapping("/admin-transaction-graph")						
	public @ResponseBody List<LabelDataDto> getAdminTransactionGraph() {
		List<LabelDataDto> result = statisticsService.getTransactionAmountPerDay();
		logger.info("결과값:" + result);
		return result;
	}

프론트단

스크립트를 추가해준다

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.bundle.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js"></script>


  <article class="section-wrap">
      <h1 class="section__title">일별 거래금액</h1>
      <canvas id="transactionAmountChart" width="1400" height="200"></canvas>
  </article>

컨트롤러에 데이터 요청

function getTransactionAmountChart() {
	let dateList = [];
	let transactionList = [];
	
	$.ajax({
		url:"admin-transaction-graph",
		type:"get",
		dataType:"json",
		success:function(data) {
			console.log(data);
			for (let  i = 0; i<data.length; i++) {
				dateList.push(data[i].label);
				transactionList.push(data[i].data);
			}
			
			new Chart(document.getElementById('transactionAmountChart'), {
				 type: 'line',
				 data: {
					 labels: dateList,
					 datasets: [{
						 data: transactionList,
						 label: "거래량",
						 backgroundColor: [
							],
						 borderColor: [ 
								'rgba(255, 99, 132, 1)',
								'rgba(54, 162, 235, 1)',
								'rgba(255, 206, 86, 1)',
								'rgba(153, 102, 255, 1)',
								'rgba(255, 159, 64, 1)',
								'rgba(153, 102, 255, 1)',
								'rgba(54, 162, 235, 1)',
								'rgba(255, 99, 132, 1)',
								'rgba(255, 206, 86, 1)',
								'rgba(153, 102, 255, 1)',
								'rgba(255, 159, 64, 1)',
								'rgba(153, 102, 255, 1)',
								'rgba(54, 162, 235, 1)',
								'rgba(255, 99, 132, 1)',
								'rgba(255, 206, 86, 1)',
								'rgba(153, 102, 255, 1)',
								'rgba(255, 159, 64, 1)',
								'rgba(153, 102, 255, 1)',
								'rgba(54, 162, 235, 1)',
								'rgba(255, 99, 132, 1)',
								'rgba(255, 206, 86, 1)',
								'rgba(153, 102, 255, 1)',
								'rgba(255, 159, 64, 1)',
								'rgba(153, 102, 255, 1)'
							],
						 borderWidth: 2
					 }]
				 },
				 options: {
						responsive: false,
						animation: {
							onComplete: function () {
								var chartInstance = this.chart,
									ctx = chartInstance.ctx;
								ctx.font = Chart.helpers.fontString(16, Chart.defaults.global.defaultFontStyle, Chart.defaults.global.defaultFontFamily);
								ctx.fillStyle = 'black';
								ctx.textAlign = 'center';
								ctx.textBaseline = 'bottom';

                                //데이타 위에 나타나는 수치를 커스터마이징했다.
								this.data.datasets.forEach(function (dataset, i) {
									var meta = chartInstance.controller.getDatasetMeta(i);
									meta.data.forEach(function (bar, index) {
										var data = numberWithCommas(dataset.data[index])+"";							
										ctx.fillText(data, bar._model.x, bar._model.y - 5);
									});
								});
							}
						},
						scales: {
							yAxes: [{
								ticks: {
									beginAtZero: true,
									fontSize : 14,
									max : 20000000
								}
							}]
						},
						 legend: {
						      display: false
						   }
					}
			});
		},
		error:function(){
			alert("실패");
		}
		
		
	})//ajax
}//그래프 가져오기

numberwithcommas는 5,000,000원과 같이 콤마를 넣어주는 함수로, 데이터 수치를 포매팅 하기 위해 사용하였다.

<script type="text/javascript">
function numberWithCommas(x) {
    return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}

getTransactionAmountChart();

이렇게 하면 그래프가 예쁘게 그려진다. 다른 그래프를 그리고 싶을 때도 마이바티스의 쿼리만 바꾸면 쉽게 그릴수 있다.


광고


Comments