romworld

Spring 21 - 구글차트 구현하기 본문

Spring

Spring 21 - 구글차트 구현하기

inderrom 2023. 2. 10. 17:00

https://developers.google.com/chart?hl=ko 

 

Charts  |  Google Developers

브라우저 및 휴대기기용 양방향 차트

developers.google.com

 


JSON을 이용하여 구현해보자

 

 

JSON 사용을 위해  maven 바인딩

mvnrepository

  • json-simple 1.1.1

<pon.xml> 추가

<!-- https://mvnrepository.com/artifact/com.googlecode.json-simple/json-simple -->
		<dependency>
		    <groupId>com.googlecode.json-simple</groupId>
		    <artifactId>json-simple</artifactId>
		    <version>1.1.1</version>
		</dependency>

프로젝트 우클릭 - run as - maven build

 


<ChartController.java>

  • controller 패키지에 클래스 파일 생성
package kr.or.ddit.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@RequestMapping("/chart")
@Controller
public class ChartController {

	//요청URI : /chart/chartMain
	//요청방식 : get
	@GetMapping("/chartMain")
	public String chartMain() {
		return "chart/chartMain";
	}
}

 

 

 

<chartMain.jsp>

<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<p><a href="/chart/chart01" class="btn btn-primary">구글차트(JSON)</a></p>
<p><a href="/chart/chart01Multi">구글멀티차트(JSON)</a></p>
<p><a href="/chart/chart02">구글차트(오라클DBMS)</a></p>

 


webapp-resources-json 폴더 생성

 

<simpleData.json>

{
"cols":[
{"id":"","label":"상품명","pattern":"","type":"string"},
{"id":"","label":"금액","pattern":"","type":"number"}
],
"rows":[
{"c":[{"v":"귤"},{"v":35000}]},
{"c":[{"v":"딸기"},{"v":88000}]},
{"c":[{"v":"레몬"},{"v":16500}]},
{"c":[{"v":"오렌지"},{"v":20000}]},
{"c":[{"v":"키위"},{"v":30000}]},
{"c":[{"v":"포도"},{"v":15000}]}
]
}

 

<ChartMain.jsp>

<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<p><a href="/chart/chart01" class="btn btn-primary">구글차트(JSON)</a></p>
<p><a href="/chart/chart01Multi">구글멀티차트(JSON)</a></p>
<p><a href="/chart/chart02">구글차트(오라클DBMS)</a></p>

 

<ChartController.java>

package kr.or.ddit.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@RequestMapping("/chart")
@Controller
public class ChartController {

	//요청URI : /chart/chartMain
	//요청방식 : get
	@GetMapping("/chartMain")
	public String chartMain() {
		return "chart/chartMain";
	}
	
	//요청  URI : /chart/chart01
	@GetMapping("/chart01")
	public String chart01() {
		//forwarding
		return "chart/chart01";
	}
}

 

<chart01.jsp>

  • chart폴더에 생성
  • async:false 
  • false를 주는 이유는 json 데이터가 있어야지만 데이터를 뿌릴 수 있어서 데이터가 올 때까지 기다리는 것임
<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<link rel="stylesheet" href="/resources/css/bootstrap.min.css" />
<script type="text/javascript" src="/resources/js/jquery-3.6.0.js"></script>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
// 구글 차트 라이브러리를 로딩 (메모리에 올림)
google.load("visualization","1",{"packages":["corechart"]})

//로딩이 되었다면
google.setOnLoadCallback(drawChart);

//콜백함수
function drawChart(){
	let jsonData = 	$.ajax({
		url:"/resources/json/simpleData.json",
		dataType:"json",
		async:false
	}).responseText;
	
	console.log("jsonData : " + jsonData);
	
}
</script>
<div class="row">
	<div class="col-xl-8 col-lg-7">
		<div class="card shadow mb-4">
			<div class="card-header py-3">
				<h6 class="m-0 font-weight-bold text-primary">상품가격</h6>
			</div>
			<!-- 구글차트가 보여질 영역 -->
			<div id="chart-div"></div>
		</div>
	</div>
</div>

 

주소창에 밑에 url 입력하면

http://localhost/resources/json/simpleData.json

작성해둔 simpleData.json 파일이 실행됨

  • responseText로 보내고 콘솔 출력시
  • 잘 출력된당


차트를 가져와보자 - LineChart

<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<script type="text/javascript" src="/resources/js/jquery-3.6.0.js"></script>
<script type="text/javascript" 
src="https://www.gstatic.com/charts/loader.js"></script>

<script type="text/javascript">
//구글 차트 라이브러리를 로딩
google.load("visualization","1",{"packages":["corechart"]});

//불러오는 작업이 완료되어 로딩이 되었다면 drawChart() 함수를 호출하는 콜백이 일어남
google.setOnLoadCallback(drawChart);

//콜백함수
function drawChart(){
   //dataType : 응답데이터의 형식
   //contentType : 보내는데이터의 형식
   //sync : 동기 / async : 비동기
   let jsonData = $.ajax({
      url:"/resources/json/simpleData.json",
      dataType:"json",
      async:false
   }).responseText;
   
   console.log("jsonData : " + jsonData);
   //구글 차트용 데이터 테이블 생성
   let data = new google.visualization.DataTable(jsonData);
   
   //어떤 차트 모양으로 출력할지를 정해주자 => LineChart
   //LineChart , ColumnChart, PieChart
   let chart = new google.visualization.LineChart(
      document.getElementById("chart_div")      
   );
   
   //data 데이터를 chart 모양으로 출력해보자
   chart.draw(data,
      {
         title:"차트 예제",
         width:500,
         height:400
      }      
   );
}
</script>

<div class="row">
   <div class="col-xl-8 col-lg-7">
       <!-- Area Chart -->
       <div class="card shadow mb-4">
           <div class="card-header py-3">
               <h6 class="m-0 font-weight-bold text-primary">상품 가격</h6>
           </div>
         <!-- 구글 차트가 보여질 영역 -->
           <div id="chart_div"></div>
       </div>
   </div>
</div>


<simpleData2.json>

{
"cols":[
{"id":"","label":"Topping","pattern":"","type":"string"},
{"id":"","label":"Slices","pattern":"","type":"number"}
],
"rows":[
{"c":[{"v":"Mushrooms"},{"v":3}]},
{"c":[{"v":"Onions"},{"v":1}]},
{"c":[{"v":"Olives"},{"v":1}]},
{"c":[{"v":"Zucchini"},{"v":1}]},
{"c":[{"v":"Pepperoni"},{"v":2}]}
]
}

 

<chart01Multi.jsp>

<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<script type="text/javascript" src="/resources/js/jquery-3.6.0.js"></script>
<script type="text/javascript" 
src="https://www.gstatic.com/charts/loader.js"></script>

<script type="text/javascript">
//구글 차트 라이브러리를 로딩
google.load("visualization","1",{"packages":["corechart"]});

//불러오는 작업이 완료되어 로딩이 되었다면 drawChart() 함수를 호출하는 콜백이 일어남
//1) 첫번째 차트
google.setOnLoadCallback(drawChart);
//2) 두번재 차트
google.setOnLoadCallback(drawChart2);

//1) 콜백함수
function drawChart(){
	//dataType : 응답데이터의 형식
	//contentType : 보내는데이터의 형식
	//sync : 동기 / async : 비동기
	let jsonData = $.ajax({
		url:"/resources/json/simpleData.json",
		dataType:"json",
		async:false
	}).responseText;
	
	console.log("jsonData : " + jsonData);
	//구글 차트용 데이터 테이블 생성
	let data = new google.visualization.DataTable(jsonData);
	
	//어떤 차트 모양으로 출력할지를 정해주자 => LineChart
	//LineChart , ColumnChart, PieChart
	let chart = new google.visualization.LineChart(
		document.getElementById("chart_div")		
	);
	
	//data 데이터를 chart 모양으로 출력해보자
	chart.draw(data,
		{
			title:"차트 예제",
			width:500,
			height:400
		}		
	);
}

//2) 콜백함수
function drawChart2(){
	//dataType : 응답데이터의 형식
	//contentType : 보내는데이터의 형식
	//sync : 동기 / async : 비동기
	let jsonData = $.ajax({
		url:"/resources/json/simpleData2.json",
		dataType:"json",
		async:false
	}).responseText;
	
	console.log("jsonData : " + jsonData);
	//구글 차트용 데이터 테이블 생성
	let data = new google.visualization.DataTable(jsonData);
	
	//어떤 차트 모양으로 출력할지를 정해주자 => LineChart
	//LineChart , ColumnChart, PieChart
	let chart = new google.visualization.ColumnChart(
		document.getElementById("chart_div2")		
	);
	
	//data 데이터를 chart 모양으로 출력해보자
	chart.draw(data,
		{
			title:"차트 예제",
			width:500,
			height:400
		}		
	);
}
</script>

<div class="row">
   <div class="col-xl-8 col-lg-7">
       <!-- 1) Area Chart -->
       <div class="card shadow mb-4">
           <div class="card-header py-3">
               <h6 class="m-0 font-weight-bold text-primary">상품 가격</h6>
           </div>
			<!-- 구글 차트가 보여질 영역 -->
           <div id="chart_div"></div>
       </div>
       <!-- 2) Area Chart -->
       <div class="card shadow mb-4">
           <div class="card-header py-3">
               <h6 class="m-0 font-weight-bold text-primary">채소 가격</h6>
           </div>
			<!-- 구글 차트가 보여질 영역 -->
           <div id="chart_div2"></div>
       </div>
	</div>
</div>

 

<ChartController.java> 추가

/요청  URI : /chart/chart01Multi
	@GetMapping("/chart01Multi")
	public String chart01Multi() {
		//forwarding
		return "chart/chart01Multi";
	}

 

 


오라클에서

base_table 을 spring 계정에 생성해보자! (메모장에 백업해둠)

생성을 하고나면 기존에 있던  테이블이 spring계정에도

 

쿼리문 ( 상품별 판매금액의 합계가 천만원이 넘는 데이터)

--집계함수
--SUM : 합계
--AVG : 평균
--MAX : 최대값
--MIN : 최소값
--COUNT : 개수
--집계함수 이외의 컬럼들은 GROUP BY절에 기술해야함
--상품별 판매금액의 합계가 천만원이 넘은 데이터
SELECT P.PROD_NAME 
    , SUM(P.PROD_SALE * C.CART_QTY) MONEY
FROM PROD P, CART C
WHERE P.PROD_ID = C.CART_PROD
GROUP BY P.PROD_NAME
HAVING SUM(P.PROD_SALE * C.CART_QTY) >= 10000000;

 

 

<lprod_SQL.xml>

<!-- 상품별 판매금액의 합계가 천만원이 넘은 데이터 -->
	 <select id="cartMoney" resultType="hashMap">
	 	SELECT P.PROD_NAME prodName
		     , SUM(P.PROD_SALE * C.CART_QTY) money
		FROM   PROD P, CART C
		WHERE  P.PROD_ID = C.CART_PROD
		GROUP BY P.PROD_NAME
		HAVING SUM(P.PROD_SALE * C.CART_QTY) >= 10000000
	 </select>

 

 

<LprodDao.java>

//상품별 판매금액의 합꼐가 천만원이 넘는 데이터
	//<select id="cartMoney" resultType="hashMap">
	public List<Map<String, Object>> cartMoney(){
		return this.sqlSessionTemplate.selectList("lprod.cartMoney");
	}

 

<LprodService.java>

//상품별 판매금액의 합꼐가 천만원이 넘는 데이터
	public JSONObject cartMoney();

 

<LprodServiceImpl.java>

 

// 상품별 판매금액의 합계가 천만원이 넘는 데이터
	@Override
	public JSONObject cartMoney() {
		
		List<Map<String,Object>> list = this.lprodDao.cartMoney();
	      
	      System.out.println("list : " + list.get(0).toString());
	      
	      //sampleData.json 파일 참고
	      //0. 리턴할 json객체--------------------------
	      JSONObject data = new JSONObject();   //{}
	      
	      //1.cols 배열에 넣기 
	      //JSON 컬럼 객체---------------------------------------------
	      JSONObject col1 = new JSONObject();
	      JSONObject col2 = new JSONObject();
	      //JSON 배열 객체
	      JSONArray title = new JSONArray();
	      col1.put("label", "상품명");
	      col1.put("type", "string");
	      col2.put("label", "금액");
	      col2.put("type", "number");
	      //타이틀행에 컬럼 추가
	      title.add(col1);
	      title.add(col2);
	      
	      //json객체에 타이틀행 추가
	      data.put("cols", title);
	      //{"cols":[{"label":"상품명","type":"string"},{"label":"금액","type":"number"}]}
	      
	      //2.rows 배열에 넣기
	      JSONArray body = new JSONArray();   //rows
	      for(Map<String,Object> map : list) {
	         JSONObject prodName = new JSONObject();
	         prodName.put("v", map.get("PRODNAME"));   //상품명
	         
	         JSONObject money = new JSONObject();
	         money.put("v", map.get("MONEY"));   //금액
	         
	         JSONArray row = new JSONArray();
	         row.add(prodName);
	         row.add(money);
	         
	         JSONObject cell = new JSONObject();
	         cell.put("c", row);
	         body.add(cell);   //레코드 1개 추가
	      }
	      
	      data.put("rows", body);
	      
	      return data;
	}

json의 c.가 cell의 c다

 

<Chartcontroller.java>

  • @Autowired
  • LprodService 의존성 주입을 해준다.
// 요청 URI : /chart/chart02
	// 응답 데이터타입 : json
	@ResponseBody
	@GetMapping("/chart02")
	public JSONObject chart02() {
		return this.lprodService.cartMoney();
	}

 

재기동 시킨 후 실행 시

DB에 있는 데이터가 잘 들어간 걸 볼 수 있다.

 


원래 만들어놨던

<chart01.jsp> 에서

url 주소를

/chart/chart02  로 바꿈

주소창에 localhost/chart/chart01 입력

 

 


쿼리문

--회원별 구매회수 구하기
-- 10회 이상만 출력
SELECT MEM_ID || '(' || MEM_NAME || ')' MEMID
        , COUNT(CART_NO) CARTCNT
FROM MEMBER M, CART C
WHERE M.MEM_ID = C.CART_MEMBER
GROUP BY MEM_ID || '(' || MEM_NAME || ')'
HAVING COUNT(CART_NO) >= 10
ORDER BY 1;

 

<lprod_SQL.xml>

<!-- 회원별 구매회수 구하기 -->
	 <select id="memberMoney" resultType="hashMap">
		SELECT MEM_ID || '(' || MEM_NAME || ')' MEMID
		        , COUNT(CART_NO) CARTCNT
		FROM MEMBER M, CART C
		WHERE M.MEM_ID = C.CART_MEMBER
		GROUP BY MEM_ID || '(' || MEM_NAME || ')'
		HAVING COUNT(CART_NO) >= 10
		ORDER BY 1
	 </select>

 

<LprodDao.java>

/회원별 구매회수 구하기 
	// <select id="memberMoney" resultType="hashMap">
	public List<Map<String, Object>> memberMoney(){
		return this.sqlSessionTemplate.selectList("lprod.memberMoney");
	}

<LprodService.java>

//상품별 판매금액의 합계가 천만원이 넘은 데이터
	public JSONObject memberMoney();

<LprodServiceImpl.java>

//상품별 판매금액의 합계가 천만원이 넘은 데이터
		@Override
		public JSONObject memberMoney(){
			List<Map<String,Object>> list = this.lprodDao.memberMoney();
			
			System.out.println("list : " + list.get(0).toString());
			
			//sampleData.json 파일 참고
			//0. 리턴할 json객체--------------------------
			JSONObject data = new JSONObject();	//{}
			
			//1.cols 배열에 넣기 
			//JSON 컬럼 객체---------------------------------------------
			JSONObject col1 = new JSONObject();
			JSONObject col2 = new JSONObject();
			//JSON 배열 객체
			JSONArray title = new JSONArray();
			col1.put("label", "회원");
			col1.put("type", "string");
			col2.put("label", "구매회수");
			col2.put("type", "number");
			//타이틀행에 컬럼 추가
			title.add(col1);
			title.add(col2);
			
			//json객체에 타이틀행 추가
			data.put("cols", title);
			//{"cols":[{"label":"상품명","type":"string"},{"label":"금액","type":"number"}]}
			
			//2.rows 배열에 넣기
			JSONArray body = new JSONArray();	//rows
			for(Map<String,Object> map : list) {
				JSONObject prodName = new JSONObject();
				prodName.put("v", map.get("MEMID"));	//회원
				
				JSONObject money = new JSONObject();
				money.put("v", map.get("CARTCNT"));	//구매회수
				
				JSONArray row = new JSONArray();
				row.add(prodName);
				row.add(money);
				
				JSONObject cell = new JSONObject();
				cell.put("c", row);
				body.add(cell);	//레코드 1개 추가
			}
			
			data.put("rows", body);
			
			return data;
		}

 

<ChartController.java>

// 요청URI : /chart/memberMoney
	// 응답 데이터 타입 :json
	@ResponseBody
	@GetMapping("/memberMoney")
	public JSONObject memberMoney() {
		return this.lprodService.memberMoney();
	}

 

<chart01.jsp>에서 url과 tilte 바꾼후 테스트

  • url:"/chart/memberMoney"
  • title : "회원별 구매회수",
  • width:600

 

Comments