[JavaScript] AJAX 를 활용한 차트

Posted by 신희준 on January 18, 2018


2018 - 01 - 18 (목)


AJAX 를 활용하여 유동적으로 차트 변환


처음에 대시보드를 구성할 때 페이지 전환시 한번에 데이터를 받아왔다.. 이러한 경우에 방대한 데이터를 가져오기에 페이지 로드에 큰 부하가 생기기 마련이다. 이러던 중 AJAX로 차트데이터를 각각 가져와 보았다. 결과적으로 AJAX를 통해 데이터를 가져오는 방식이 컨트롤러를 더 많이 호출하기는 하지만 훨씬 속도가 빨랐다.

결국 이전에 작업한 대시보드를 갈아엎게 되었다..


  • 매출추이를 보여주는 차트

document ready 시에 ajax 요청을 보내 차트의 데이터를 채워줄 것이다 [차트는 Amchart 를 활용하였다.]


  • 매출 관련 대시보드로 아래 사진과 같은 차트로 시각화 해보았다. Post Sample Image

  • 4개의 차트중에 좌측 상단의 꺽은선 그래프의 소스코드이다. AJAX 를 활용하여 데이터를 받아와 차트로 시각화 해준다.

<head>
  <script src="https://www.amcharts.com/lib/3/amcharts.js"></script>
  <script src="https://www.amcharts.com/lib/3/serial.js"></script>
  <script src="https://www.amcharts.com/lib/3/pie.js"></script>
  <link rel="stylesheet" href="https://www.amcharts.com/lib/3/plugins/export/export.css" type="text/css" media="all" />
  <script src="https://www.amcharts.com/lib/3/themes/light.js"></script>  
<style>
#chartOutput{
width		: 100%;
	height		: 465px;
	font-size	: 16px;
	font-weight : bold;
}
</style>
</head>
<body>
<div id = "chartOutput" style = "margin-top : 20px"></div>
</body>                  


<script>


$(document).ready(function(){
  $.ajax({

		type : "POST",
	    url: "/admin/chartOutput",
	    success: function(data) {
			console.log(data)
			var chart = AmCharts.makeChart("chartOutput", {
			    "type": "serial",
			    "theme": "light",
			    "marginRight": 40,
			    "marginLeft": 40,
			    "autoMarginOffset": 20,
			    "mouseWheelZoomEnabled":true,
			    "valueAxes": [{
			        "id": "v1",
			        "axisAlpha": 0,
			        "position": "left",
			        "ignoreAxisWidth":true
			    }],
			    "balloon": {
			        "borderThickness": 1,
			        "shadowAlpha": 0
			    },
			    "graphs": [{
			        "id": "g1",
			        "balloon":{
			          "drop":true,
			          "adjustBorderColor":false,
			          "color":"#ffffff"
			        },
			        "bullet": "round",
			        "bulletBorderAlpha": 1,
			        "bulletColor": "#FFFFFF",
			        "bulletSize": 5,
			        "hideBulletsCount": 50,
			        "lineThickness": 2,
			        "title": "red line",
			        "useLineColorForBulletBorder": true,
			        "valueField": "output",
			        "balloonText": "<span style='font-size:18px;'>[[value]]</span>"
			    }],
			    "chartScrollbar": {
			        "graph": "g1",
			        "oppositeAxis":false,
			        "offset":30,
			        "scrollbarHeight": 80,
			        "backgroundAlpha": 0,
			        "selectedBackgroundAlpha": 0.1,
			        "selectedBackgroundColor": "#888888",
			        "graphFillAlpha": 0,
			        "graphLineAlpha": 0.5,
			        "selectedGraphFillAlpha": 0,
			        "selectedGraphLineAlpha": 1,
			        "autoGridCount":true,
			        "color":"#AAAAAA"
			    },
			    "chartCursor": {
			        "pan": true,
			        "valueLineEnabled": true,
			        "valueLineBalloonEnabled": true,
			        "cursorAlpha":1,
			        "cursorColor":"#258cbb",
			        "limitToGraph":"g1",
			        "valueLineAlpha":0.2,
			        "valueZoomable":true
			    },
			    "valueScrollbar":{
			      "oppositeAxis":false,
			      "offset":50,
			      "scrollbarHeight":10
			    },
			    "categoryField": "date",
			    "categoryAxis": {
			        "parseDates": true,
			        "dashLength": 1,
			        "minorGridEnabled": true
			    },
			    "export": {
			        "enabled": true
			    },
			    "dataProvider": data
			});

			chart.addListener("rendered", zoomChart);

			zoomChart();

			function zoomChart() {
			    chart.zoomToIndexes(chart.dataProvider.length - 40, chart.dataProvider.length - 1);
			}
	    }
	})

})
})
</script>
  • 컨트롤러
@RequestMapping(value = "/chartOutput", method = RequestMethod.POST)
@ResponseBody
public List chartOutput()throws Exception {
  List<JsonObj> chartOutput = adminService.chartOutput();
  ArrayList response = new ArrayList();
  for(int i =0; i < chartOutput.size(); i ++) {
    HashMap<String , Object> map = new HashMap<String, Object>();
    map.put("date", chartOutput.get(i).getRegYear()+"-"+chartOutput.get(i).getRegMonth()+"-"+chartOutput.get(i).getRegDay());
    map.put("output", chartOutput.get(i).getCommission());
    response.add(map);
    System.out.println(map);
    System.out.println(response);
  }
  System.out.println(response);
  return response;

}
  • Mapper

<select id = "chartOutput" resultType = "JsonObj">

select year(enroll_regTime) as regYear, month(enroll_regTime) as regMonth,
day(enroll_regTime) as regDay, sum(class_price) div 3/100 as commission
FROM ENROLL left outer join CLASS on class_id = CLASS_class_id
group by day(enroll_regTime);

</select>

이외에도 이번 대시보드 작업을 통해 여러가지 차트 및 데이터 시각화과정을 거쳤다. 느낀점은 데이터베이스 SQL 의 중요성을 느끼게 되었고 DB에 좀 더 많은 공부시간을 투자해야 함을 느꼈다.