JSP

부트캠프57일 (차트 ,DB연동, 차트를 model2에 사용 ,

동곤일상 2025. 4. 23. 17:51
반응형

 

1)차트작성

1-1) 프로젝트 생성

1-2)기본

1-3) bar와 line

1-4)파이그래프 , 도넛그래프

 

2)DB연동

2-1) 게시물(board)에서 게시글 작성자별 건수;

2-2) 날짜별로 게시물 갯수

 

3) model2에 그래프 적용시켜보기

3-1) 작성자별 게시물수 (pie) 

3-2) 날짜별 게시물수(bar)


 

1) 차트작성

 

https://www.chartjs.org/

 

Chart.js

Simple yet flexible JavaScript charting library for the modern web

www.chartjs.org

(차트에관한정보들이있음)

 

 

 

 

해당사이트에 접속해  getStarted 클릭

밑줄친부분의 script부분을 잘 가지고있자!!!!!

<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

 

 

1-1) 프로젝트생성

 

다음이름과같이 DynamicWebProject를 만들어줘!!

 

1-2) 기본

(아까 복사해놓은 스크립트 활용)

/chartStudy/src/main/webapp/bar1.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>간단한막대그래프작성</title>
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<div><canvas id=myChart></canvas></div>
<script type="text/javascript">
const ctx = document.querySelector("#myChart"); //canvas객체
new Chart(ctx,{
	type:"bar",//막대그래프
	data:{
		labels:["Red","blue","Yellow","Green","Purple","Orange"],
		datasets:[{
			label : "# of votes1",
			data:[12,19,3,5,2,3], //막대그래프의 y축값(높이)라고 봐주면댐
			borderWidth : 1,
			backgroundColor :["Red","blue","Yellow","Green","Purple","Orange"]
		},
		{
			label : "# of votes2",
			data:[5,9,1,10,15,3],
			borderWidth : 1,
			backgroundColor :["Red","blue","Yellow","Green","Purple","Orange"]
		}]
	},
	options:{
		scales:{y:{beginAtZero : true}},
		plugins: {
	        legend: {
	            position: "right" // 범례 위치를 오른쪽으로 설정
	        }
	    }
	},
	
})

</script>


</body>
</html>


1-3) bar 와 line

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>막대,선 그래프 함께표현</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
<div style="width:75%">
<canvas id="canvas"></canvas>
</div>
<script type="text/javascript">
	let months=
		["1월","2월","3월","4월","5월","6월","7월","8월","9월","10월","11월","12월"];
	let chartData={
	 labels : months,
	 datasets:[
		 {
			type:'line',
			label:'영업부',
			borderColor : '#FF0000',//선의색상
			borderWidth : 3,//두꼐
			fill : true,
			data:[10,15,25,55,0,-25,-40,56,78,12,50,25]
		 },
		 {
			type:'bar',//막대그래프
			label:'총무부',
			backgroundColor : '#A565FF',
			borderColor : 'black', //테두리색상
			borderWidth : 2,
			data:[10,15,25,55,0,-25,-40,56,78,12,50,25]
		},
		{
			type:'bar',//막대그래프
			label:'총무부',
			backgroundColor : '#00FF00',
			borderColor : 'red', //테두리색상
			borderWidth : 2,
			data:[10,15,25,55,0,-25,-40,56,78,12,50,25]
		}
	 ]}
	window.onload = function(){
		let ctx = document.getElementById("canvas");
		new Chart(ctx,{
			type:'bar',
			data : chartData,
			options : {
				responsive : true,
				title:{display:true, text:'막대그래프와 선그래프'}
			},
			legend : {display : true},
		})

	}
	
</script>

</body>
</html>

 


1-4)파이그래프  , 도넛그래프

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>파이(도넛)그래프</title>
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<div style="width:75%">
<canvas id="canvas"></canvas>
</div>
<script type="text/javascript">
let months=
	["1월","2월","3월","4월","5월","6월","7월","8월","9월","10월","11월","12월"];
let getData = function(){
	return Math.round(Math.random()*100)
}
let config={
	type : "pie", //doughnut
	data :{
		datasets:[
		{
			data:[
				getData(),getData(),getData(),getData(),
				getData(),getData(),getData(),getData(),
				getData(),getData(),getData(),getData(),
			],
			backgroundColor:['red','orange','yellow','green','blue',
				'#FFEEFE','#123456','#12FFFF','#FFFF56',
				'#FFFF00','#FF00FF','#EEEEEE'],
			label:"파이(도넛)그래프"
		}],
		labels : months
	},
	options: {
        responsive: true,
        plugins: {
            legend: {
                position: 'right' // 범례 위치를 오른쪽으로 설정
            },
            title: {
                display: true,
                text: '파이(도넛)그래프연습'
            }
        },
        animation: {
            animateScale: true,
            animateRotate: true
        }
    }
}
window.onload = function(){
	let ctx = document.querySelector("#canvas");
	new Chart(ctx,config);
}
</script>
</body>
</html>

 

type : pie

 

type : doughnut


2)DB연동

라이브러리 가져옴

 

2-1) 게시물(board)에서 게시글 작성자별 건수;

 

/chartStudy/src/main/webapp/db/barline.jsp

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

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시글 작성자별 건수 그래프</title>
</head>
<body>
<sql:setDataSource var="conn" driver="org.mariadb.jdbc.Driver"
	url="jdbc:mariadb://localhost:3306/gdjdb"
	user="gduser" password="1234"/>
<sql:query var="rs" dataSource="${conn}" >
select writer,count(*) cnt from board
group by writer
order by count(*) desc
</sql:query>
<div style="width:75%"><canvas id="canvas"></canvas></div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script type="text/javascript">
let randomColorFactor = function(){
	return Math.round(Math.random()*255)//0~255사이의 정수
}
let randomColor = function(opacity){
//rgba(100,100,50,1) : rgba(red,green,blue,투명도)
//투명도 : 0~1사이의값,  0:투명 1:불투명
	return "rgba("+ randomColorFactor()+","
		+ randomColorFactor() + ","+randomColorFactor()+","
		+(opacity || ".3")+")";
}

let chartData = {
	labels:  
[<c:forEach items="${rs.rows}" var="m">"${m.writer}",</c:forEach>],
	datasets :[
		{
			type:'line',
			borderWidth : 2,
			borderColor : [<c:forEach items="${rs.rows}" var="m">randomColor(1),</c:forEach>],
			label :'건수',
			fill : false,
			data: 
				[<c:forEach items="${rs.rows}" var="m">"${m.cnt}",</c:forEach>],
		},
		{
			type:'bar',
			borderWidth : 2,
			backgroundColor : [<c:forEach items="${rs.rows}" var="m">randomColor(1),</c:forEach>],
			label :'건수',
			data: 
				[<c:forEach items="${rs.rows}" var="m">"${m.cnt}",</c:forEach>],

		}]
}
window.onload = function(){
	let ctx = document.querySelector("#canvas");
	new Chart(ctx,{
		type:'bar',
		data : chartData,
		options:{
		responsive : true,
			plugins:{
				legend:{
					display:false,
				},
				
				title:{
					display:true,
					text:"작성자별 게시판 등록건수"
				},
			},
				scales:{
					x:{
						display:true,
						title:{
						display:true,
						text:"게시물작성자"
						},
						},
					y:{
						display:true,
						beginAtZero:true,
						title:{
						display:true,
						text:"게시물작성 건수"
						},
					}
						
				}
			
		}//option
	})//chart
}
</script>

</body>
</html>

옛날방식

<script type="text/javascript"

src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>

으로 작성하는 방법 ↓   

window.onload = function() {
	let ctx = document.querySelector("#canvas");
	new Chart(ctx,{
			type : 'bar',
			data : charData,
			options : {
				responsive : true,
				title : {display : true, text :"작성자별 게시판 등록 건수"},
				legend : {display : false},
				scales : {
					y : {beginAtZero :true},
					xAxes : [
						{display : true,
						scaleLabel : {
							display : true,
							labelString : "게시물작성자"}
						}],
					yAxes : [{
						display : true,
						scaleLabel : {
							display : true,
							labelString : "게시물 작성 건수"
						}
					
					}]
				}
			}
	})
}

 

 


PIE타입으로 바꿔서

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>   
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>   
   <%--pie그래프로 게시글 작성자별 건수 출력하기 --%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>PIE</title>
</head>
<body>
<sql:setDataSource var="conn" driver="org.mariadb.jdbc.Driver"
	url="jdbc:mariadb://localhost:3306/gdjdb"
	user="gduser" password="1234"/>
<sql:query var="rs" dataSource="${conn}">
select writer,count(*) cnt from board
group by writer
order by count(*) desc
</sql:query>
<div style="width:75%"><canvas id="canvas"></canvas></div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script type="text/javascript">
let randomColorFactor = function(){
	return Math.round(Math.random()*255)//0~255사이의 정수
}
let randomColor = function(opacity){
		return "rgba("+ randomColorFactor()+","
			+ randomColorFactor() + ","+randomColorFactor()+","
			+(opacity || ".3")+")";
}

let chartData = {
		labels:  
	[<c:forEach items="${rs.rows}" var="m">"${m.writer}",</c:forEach>],
		datasets :[
			{
				type:'pie',
				borderWidth : 2,
				backgroundColor : [<c:forEach items="${rs.rows}" var="m">randomColor(1),</c:forEach>],
				label :'건수',
				fill : false,
				data: 
					[<c:forEach items="${rs.rows}" var="m">"${m.cnt}",</c:forEach>],
			}]
		
		
	}
	
window.onload = function(){
	let ctx = document.querySelector("#canvas");
	new Chart(ctx,{
		type:'pie',
		data : chartData,
		options:{
		responsive : true,
			plugins:{
				legend:{
					display:true,
					position:'right'
				},
				
				title:{
					display:true,
					text:"작성자별 게시판 등록건수",
					position:'bottom',
					color:'purple',
					font:{
						size:30
					}
				},
			},
			
		}//option
	})//chart
}

	


</script>

</body>
</html>

 

 


2-2) 날짜별로 게시물 갯수

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>    
<%--
	날짜별로 등록된 게시물건수를 막대 , 선그래프로출력하기
 --%>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>날짜별 게시물건수</title>
</head>
<body>
<sql:setDataSource var="conn" driver="org.mariadb.jdbc.Driver"
	url="jdbc:mariadb://localhost:3306/gdjdb"
	user="gduser" password="1234"/>
<sql:query var="rs" dataSource="${conn}" >
select SUBSTR(regdate,1,10) 'date' ,count(*) cnt from board
group by SUBSTR(regdate,1,10) 
order by SUBSTR(regdate,1,10) asc;
</sql:query>
<div style="width:75%"><canvas id="canvas"></canvas></div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script type="text/javascript">
let randomColorFactor = function(){
	return Math.round(Math.random()*255)//0~255사이의 정수
}
let randomColor = function(opacity){
//rgba(100,100,50,1) : rgba(red,green,blue,투명도)
//투명도 : 0~1사이의값,  0:투명 1:불투명
	return "rgba("+ randomColorFactor()+","
		+ randomColorFactor() + ","+randomColorFactor()+","
		+(opacity || ".3")+")";
}

let chartData = {
	labels:  
[<c:forEach items="${rs.rows}" var="m">"${m.date}",</c:forEach>],
	datasets :[
		{
			type:'line',
			borderWidth : 2,
			borderColor : [<c:forEach items="${rs.rows}" var="m">randomColor(1),</c:forEach>],
			label :'건수',
			fill : false,
			data: 
				[<c:forEach items="${rs.rows}" var="m">"${m.cnt}",</c:forEach>],
		},
		{
			type:'bar',
			borderWidth : 2,
			backgroundColor : [<c:forEach items="${rs.rows}" var="m">randomColor(1),</c:forEach>],
			label :'건수',
			data: 
				[<c:forEach items="${rs.rows}" var="m">"${m.cnt}",</c:forEach>],

		}]
}
window.onload = function(){
	let ctx = document.querySelector("#canvas");
	new Chart(ctx,{
		type:'bar',
		data : chartData,
		options:{
		responsive : true,
			plugins:{
				legend:{
					display:false,
				},
				
				title:{
					display:true,
					text:"날짜별 게시판 등록건수"
				},
			},//plugin
			
				scales:{
					x:{
						display:true,
						title:{
						display:true,
						text:"날짜"
						},
						},
					y:{
						display:true,
						beginAtZero:true,
						title:{
						display:true,
						text:"게시물작성 건수"
						},
					}
				}
			
		}//options
	})//chart
}

</script>

</body>
</html>

 


3) model2에 그래프 적용시켜보기

 

3-1)  작성자별 게시물수 (pie) 

 

변경한 layout.jsp

(크기의문제가있어서)

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

다음과 같이 CDN의 스크립트 버전을 낮췄다

코딩방법도 조금은달라짐 ( plugin을 사용하지않음)

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
<c:set var="path" value="${pageContext.request.contextPath }"></c:set>
<!DOCTYPE html>
<html>
<head>
<title><sitemesh:write property="title" /></title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet"
	href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css">
<script
	src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.slim.min.js"></script>
<script
	src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>
<script
	src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"></script>
<!-- include summernote css/js -->
<link
	href="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote.min.css"
	rel="stylesheet">
<script
	src="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote.min.js"></script>
<script type="text/javascript"
	src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>

<style>
.fakeimg {
	height: 200px;
	background: #aaa;
}

.footer {
	display: flex;
	flex-direction: column;
}

.footer_link {
	height: 15%;
	display: flex;
	align-items: center;
}

.footer_link a {
	text-decoration: none;
	color: black;
	font-weight: bold;
	margin: 15px;
}

.footer_company {
	height: 70%;
}

.footer_company>ul {
	list-style: "- ";
	padding-left: 15px;
}

.footer_copyright {
	height: 15%;
	text-align: center
}

.footer>div {
	border-top: 1px solid gray
}
</style>
<sitemesh:write property="head" />
<script
	src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
</head>
<body>
	<div class="jumbotron text-center" style="margin-bottom: 0">
		<h1>dongPage</h1>
		<p>남자의 페이지</p>
	</div>
	<nav class="navbar navbar-expand-sm bg-dark navbar-dark">
		<a class="navbar-brand" href="#">목록</a>
		<button class="navbar-toggler" type="button" data-toggle="collapse"
			data-target="#collapsibleNavbar">
			<span class="navbar-toggler-icon"></span>
		</button>
		<div class="collapse navbar-collapse" id="collapsibleNavbar">
			<ul class="navbar-nav">
				<li class="nav-item"><a class="nav-link"
					href="${path}/member/main">회원관리</a></li>
				<li class="nav-item"><a class="nav-link"
					href="${path}/board/list?boardid=1">공지사항</a></li>
				<li class="nav-item"><a class="nav-link"
					href="${path}/board/list?boardid=2">자유게시판</a></li>
				<c:if test="${sessionScope.login != null}">
					<li class="nav-item"><a class="nav-link" href="#">${sessionScope.login}님
							하이</a></li>
					<li class="nav-item"><a class="nav-link"
						href="${path}/member/logout">로그아웃</a></li>
				</c:if>
				<li class="nav-item"><a class="nav-link"
					href="javascript:history.go(-1)">뒤로가기</a></li>

			</ul>
		</div>
	</nav>
	<div class="container" style="margin-top: 30px">
		<div class="row">
			<div class="col-6" style="border: 1px solid #EEEEEE;">
				<%-- 작성자별 게시물 등록 건수 pie그래프 : 가장많이작성한작성자 5명만 --%>
				<canvas id="canvas1"></canvas>
			</div>
			<div class="col-6" style="border: 1px solid #EEEEEE;">
				<%-- 최근작성일자 기준 게시물 등록 건수 pie그래프 : 가장많이작성한작성자 5명만--%>
				<canvas id="canvas2" ></canvas>
			</div>
		</div>
		<sitemesh:write property="body" />
	</div>

	<footer class="footer">
		<div>
			<span id="si"> <select name="si" onchange="getText('si')">
					<option value="">시,도를 선택하세요</option>
			</select>
			</span> <span id="gu"> <select name="gu" onchange="getText('gu')">
					<option value="">구군 선택하세요</option>
			</select>
			</span> <span id="dong"> <select name="dong">
					<option value="">동리를 선택하세요</option>
			</select>
			</span>
		</div>
		<div class="footer_link">
			<a href="">이용약관</a> | <a href="">개인정보취급방침</a> | <a href="">인재채용</a> |
			<a href="">고객센터</a>
		</div>
		<div class="footer_company">
			<ul>
				<li>상호명 : DongCompany</li>
				<li>대표자 : 유동곤</li>
				<li>전화 : 010-86948525</li>
				<li>개인정보책임자 : 유동곤 /ddkk8525@gmail.com</li>
			</ul>
		</div>
		<div class="footer_copyright">Copyright ⓒ dong Company.
			Allrights reserved.</div>
	</footer>

	<script type="text/javascript">
	$(function(){	
		piegraph();
		bargraph();
		
		$.ajax({
			url : "${path}/ajax/select",
			success: function(data){
//data : ["서울특별시","경기도",.....]
				let arr = JSON.parse(data)
				$.each(arr,function(i,item){
			//item : 서울특별시
					$("select[name=si]").append(function(){
						return "<option>"+item+"</option>"	
					})
				})
			},
			error:function(e){
				alert("서버오류 : "+e.status)
			}
		})
	}) //여기까지의부분은 모든 시(name='si')를 AJAX를 통해 가져올거임
	
			
		function getText(type) { // 시 or 도를 선택하면 발생하는 함수
			const si = $("select[name=si]").val(); //클릭한 시의 vlaue
			const gu = $("select[name=gu]").val();//클릭한 구의 vlaue
			let url = "";
			let targetSelect;
			
			if (type === "si") {
				if (!si) return;
				url = "${path}/ajax/select?si="+si; //입력받은si의값을 파라미터로갖는 주소
				targetSelect = $("select[name=gu]"); //target을 gu에해당하는 select태그로설정
				// 시를 선택하면 기존 구, 동 초기화
		        $("select[name=gu]").html('<option value="">구군 선택하세요</option>');
		        $("select[name=dong]").html('<option value="">동리를 선택하세요</option>');
		        
			} else if (type === "gu") {
				if (!si || !gu) return;
				url = "${path}/ajax/select?si="+si+"&gu="+gu;
				targetSelect = $("select[name=dong]");
				// 구를 선택하면 기존  동 초기화		  
		        $("select[name=dong]").html('<option value="">동리를 선택하세요</option>');
			} else {
				return;
			}

			$.ajax({ //ajax에 요청을 보낼거임
				url: url, //위 type에의한  url 설정
				success: function(data) {
					const arr = JSON.parse(data); //성공시 JSON방식(배열)으로 데이터를가져옴
					$.each(arr, function(i, item) {
						//해당배열을 순회해서 나온값들을 모두 taget태그하위에 option으로넣는다
						targetSelect.append("<option>"+item+"</option>"	);
					});
				},
				error: function(e) {
					alert("서버 오류 : " + e.status);
				}
			});
		}
	
	
	function piegraph(){
		$.ajax("${path}/ajax/graph1",{
			success: function(data){
//data : [{"cnt":24,"writer":유동곤"},{"cnt":2,"writer":fff"},{"cnt":2,"writer":admin"},{"cnt":1,"writer":김창민"},{"cnt":1,"writer":김민지"}]
				pieGraphPrint(data);
			},
			error : function(e){
				alert("서버오류 : "+e.status)
			}
		})
	}
	
	function bargraph(){
		$.ajax("${path}/ajax/graph2",{
			success: function(data){
				bargraphPrint(data);
			},
			error : function(e){
				alert("서버오류 : "+e.status)
			}
		})
	}
	
	let randomColorFactor = function(){
		return Math.round(Math.random()*255)//0~255사이의 정수
	}
	
	let randomColor = function(opacity){
		//rgba(100,100,50,1) : rgba(red,green,blue,투명도)
		//투명도 : 0~1사이의값,  0:투명 1:불투명
			return "rgba("+ randomColorFactor()+","
				+ randomColorFactor() + ","+randomColorFactor()+","
				+(opacity || ".3")+")";
		}
	
	
	function pieGraphPrint(data){
		let rows = JSON.parse(data); //json형식으로데이터를받아
		let writers = [] //작성자목록
		let datas=[] //게시물 갯수
		let color=[] // 랜덤한Color를 넣어둘곳
		
		$.each(rows,function(i,item){//모든데이터를 순회

		//item : {"cnt":3,"writer":"홍길동"}
			writers[i] = item.writer; // "홍길동"
			datas[i] = item.cnt; //3
			color[i] = randomColor(1);
		})
		
		let config = {
			type:'pie',
			data : {
				datasets:[{
					data : datas,//cnt가있는배열
					backgroundColor : color
				}],
				labels : writers,
			},
			options : {
				responsive: true,//반응형차트생성
					legend : {position:"right"},//label을 우측에위치
					title : {
						display : true,
						text : '게시물 작성자별 등록건수(최대 5명)',
						position:'bottom'
					}
			}
		}
		let ctx = document.querySelector("#canvas1");
		new Chart(ctx,config)
	}
	
	
	
	function bargraphPrint(data){
		let rows = JSON.parse(data);
		let dates =[] //날짜
		let cnts=[] //게시물 갯수
		let color=[] // 랜덤한Color를 넣어둘곳
		console.log("rows : ",rows)

	
		
		$.each(rows,function(i,item){//모든데이터를 순회
			cnts[i] = item.cnt; //게시물개수
			dates[i] = item.date; //날짜(년월일)
			color[i] = randomColor(1);
		})

		let config = {
			type:'bar',
			data : {
				datasets:[{
					data : cnts,
					backgroundColor : color
				}],
				labels : dates,
			},
			options : {
				responsive: true,
					legend : { display: true,position:"right"},
				title : {
					display : true,
					text : '날짜별 등록건수(최대5일)',
					position:'bottom'
				},
			scales:{
				yAxes:[{
					ticks:{
						display : true,
						beginAtZero:true
					},
				}]
			}
				
			}
		}
		let ctx = document.querySelector("#canvas2");
		new Chart(ctx,config)
	}


	</script>

</body>
</html>

 

 

AjaxController에  graph1 매핑 추가 (구식방법과 jackson사용한방법 두개다있음)

	/*@RequestMapping("graph1") 구식방법
	public String graph1(HttpServletRequest request , 
			HttpServletResponse response) {
		BoardDao dao = new BoardDao();
		List<Map<String,Object>> list = dao.boardgraph1();
		StringBuilder sb = new StringBuilder("[");
		int i=0;
		for(Map<String,Object> m : list) {
			for(Map.Entry<String, Object> me : m.entrySet()) {
				if(me.getKey().equals("cnt")) {
					sb.append("{\"cnt\":"+me.getValue()+",");
				}
				if(me.getKey().equals("writer")) {
					sb.append("\"writer\":\""+me.getValue()+"\"}");
				}
				//하나의 map을 처리				
			}//2번for문종료
			i++;
			if(i<list.size()) {
				sb.append(",");
			} //각 map사이에 , 를 찍어줌
			
		}//1번for문 종료
		
		sb.append("]");//[{"cnt":xx,"writer":xx},{"cnt":x2,"writer":x2}]의형태
		request.setAttribute("json", sb.toString().trim());
		return "ajax/graph";
		
	}*/
	
	@RequestMapping("graph1")
	public String graph1(HttpServletRequest request , 
			HttpServletResponse response) {
		BoardDao dao = new BoardDao();
		List<Map<String,Object>> list = dao.boardgraph1();
		ObjectMapper objectMapper = new ObjectMapper();
		try {
			String json = objectMapper.writeValueAsString(list);
			request.setAttribute("json", json);
		}
		catch(Exception e) {
			e.printStackTrace();
		}
		
		
		return "ajax/graph";
		
	}

해당라이브러리 꼭 추가!!

jackson.zip
2.04MB

BoardDao에

boardgraph1 메서드추가

public List<Map<String, Object>> boardgraph1() {
		SqlSession session = MyBatisConnection.getConnection();
		List<Map<String, Object>> list = null;
		try {
			list = session.getMapper(cls).boardgraph1();
			return list;

		} catch (Exception e) {
			e.printStackTrace();
		}
		finally {
			MyBatisConnection.close(session);
		}
		return null;
	}

 

BoardMapper에 sql문 넣기

	@Select("select writer , count(*) cnt  from board"
			+ " group by writer order by cnt desc"
			+ " limit 0,5") //limit 0,5 : 0번째행부터 5개
	List<Map<String, Object>> boardgraph1();
	//Map<컬럼명,컬럼값> 형태를 List에 순서대로넣음
	// ex : {"writer":"길동" , "cnt":4}
	//		{"writer":"길순" , "cnt":2}

앞의번호가 set의 인덱스라고생각하면 되고

속성명: key

값 : value 로 생각

 

/webapp/view/ajax/graph.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
${json}

 

 

 


3-2) 날짜별 게시물수(bar)

layout.jsp (주요한 함수들만 남겨놈)

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
<c:set var="path" value="${pageContext.request.contextPath }"></c:set>
.......
<script type="text/javascript"
	src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>

...
	<div class="container" style="margin-top: 30px">
		<div class="row">
			<div class="col-6" style="border: 1px solid #EEEEEE;">
				<%-- 작성자별 게시물 등록 건수 pie그래프 : 가장많이작성한작성자 5명만 --%>
				<canvas id="canvas1"></canvas>
			</div>
			<div class="col-6" style="border: 1px solid #EEEEEE;">
				<%-- 최근작성일자 기준 게시물 등록 건수 pie그래프 : 가장많이작성한작성자 5명만--%>
				<canvas id="canvas2"></canvas>
			</div>
		</div>
		<sitemesh:write property="body" />
	</div>
....
	<script type="text/javascript">
	$(function(){	
		piegraph();
		bargraph();
		
		$.ajax({
			url : "${path}/ajax/select",
			success: function(data){
//data : ["서울특별시","경기도",.....]
				let arr = JSON.parse(data)
				$.each(arr,function(i,item){
			//item : 서울특별시
					$("select[name=si]").append(function(){
						return "<option>"+item+"</option>"	
					})
				})
			},
			error:function(e){
				alert("서버오류 : "+e.status)
			}
		})
	}) //여기까지의부분은 모든 시(name='si')를 AJAX를 통해 가져올거임
	
	
	function bargraph(){
		$.ajax("${path}/ajax/graph2",{
			success: function(data){
				bargraphPrint(data);
			},
			error : function(e){
				alert("서버오류 : "+e.status)
			}
		})
	}
	
	let randomColorFactor = function(){
		return Math.round(Math.random()*255)//0~255사이의 정수
	}
	
	let randomColor = function(opacity){
		//rgba(100,100,50,1) : rgba(red,green,blue,투명도)
		//투명도 : 0~1사이의값,  0:투명 1:불투명
			return "rgba("+ randomColorFactor()+","
				+ randomColorFactor() + ","+randomColorFactor()+","
				+(opacity || ".3")+")";
		}
	
	
	function bargraphPrint(data){
		let rows = JSON.parse(data);
		let dates = [] //작성자목록
		let cnts=[] //게시물 갯수
		let color=[] // 랜덤한Color를 넣어둘곳
		
		$.each(rows,function(i,item){//모든데이터를 순회
			dates[i] = item.date; //날짜(년월일)
			cnts[i] = item.cnt; //게시물개수
			color[i] = randomColor(1);
		})
		
		let config = {
			type:'bar',
			data : {
				labels : dates,
				datasets:[{
					data : cnts,
					backgroundColor : color
				}],
				
			},
			options : {
				responsive: true,
					legend : {position:"top"},
				title : {
					display : true,
					text : '날짜별 등록건수(최대5일)',
					position:'bottom'
				},
			scales:{
				yAxes:[{
					ticks:{
						beginAtZero:true
					},
				}]
			}
				
			}
		}
		let ctx = document.querySelector("#canvas2");
		new Chart(ctx,config)
	}
	</script>

</body>
</html>

 

 

AjaxController의 graph2 매핑부분

/*@RequestMapping("graph2") //구식의방법
	public String graph2(HttpServletRequest request , 
			HttpServletResponse response) {
		BoardDao dao = new BoardDao();
		List<Map<String,Object>> list = dao.boardgraph2();
		StringBuilder sb = new StringBuilder("[");
		int i=0;
		for(Map<String,Object> m : list) {
			for(Map.Entry<String, Object> me : m.entrySet()) {
				if(me.getKey().equals("date")) {
					sb.append("{\"date\":\""+me.getValue()+"\",");
				}
				
				if(me.getKey().equals("cnt")) {
					sb.append("\"cnt\":"+me.getValue()+"}");
				}
				
				
				//하나의 map을 처리
				
			}//2번for문종료
			i++;
			if(i<list.size()) {
				sb.append(",");
			} //각 map사이에 , 를 찍어줌
			
		}//1번for문 종료
		
		sb.append("]");//[{"cnt":xx,"writer":xx},{"cnt":x2,"writer":x2}]의형태
		request.setAttribute("json", sb.toString().trim());
		return "ajax/graph";
		 
	}*/
	
	@RequestMapping("graph2")
	public String graph3(HttpServletRequest request, HttpServletResponse response) {
		
		BoardDao dao = new BoardDao();
		List<Map<String, Object>> list = dao.boardgraph2();
		 ObjectMapper objectMapper = new ObjectMapper();
		
		try {
			/* 날짜 포맷 설정
			SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            objectMapper.setDateFormat(dateFormat);*/
        		   
			// List<Map<String, Object>>를 JSON 문자열로 변환
            String jsonStr = objectMapper.writeValueAsString(list);
            // 변환된 JSON 문자열 출력
            System.out.println(jsonStr);
            request.setAttribute("json", jsonStr);
		} catch (IOException e) {
            e.printStackTrace();
        }
		
		return"ajax/graph";
	}

jackson.zip
2.04MB

해당 jar파일(라이브러리)가 존재해야 가능함 

 

 

 


BoardDao의  boardgraph2 메서드

public List<Map<String, Object>> boardgraph2() {
		SqlSession session = MyBatisConnection.getConnection();
		List<Map<String, Object>> list = null;
		try {
			list = session.getMapper(cls).boardgraph2();
			return list;

		} catch (Exception e) {
			e.printStackTrace();
		}
		finally {
			MyBatisConnection.close(session);
		}
		return null;
	}

graph.jsp (요청을받으면 json 파라미터를 받아 layout.jsp쪽으로 응답할거임)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
${json}

BoardMapper의 boardgraph2 (방법1)

@Select("select SUBSTR(regdate,1,10) as 'date' , count(*) as cnt "
			+ " from board"
			+ " group by SUBSTR(regdate,1,10)"
			+ " order by SUBSTR(regdate,1,10) asc"
			+ " limit 0,5"
			)
	List<Map<String, Object>> boardgraph2();

(substr로바꿔준다면 dateType--> StringType으로바뀌면서 1번째문자부터 10개만꺼냄)

 

BoardMapper의 boardgraph2 (방법2)

	@Select("SELECT date_format(regdate,'%Y-%m-%d') as 'date' ,count(*) cnt FROM board "
			+ "	group by date_format(regdate,'%Y-%m-%d') "
			+ "	order by 1 desc"
			+ "	limit 0,7")
	List<Map<String, Object>> graph2();

date의형식을 아예바꾸지않고 format을 통해 바꿔줌