주먀
5. piechart 그리기 본문
* eclips js -> javaScript 에서 열때 경로 *
C:\eGovFrame-4.0.0\workspace.edu\SpringMVC02\src\main\webapp\resources
* 비동기통신 문법 *
$.ajax({
1. 어디로 요청을 보낼건지
url : 'controller url mapping',
2. 보내줄 데이터
data : 보내주고 데이터(객체),
3. 받아올 데이터 타입
dataType : 'json',
4. 성공했을 때 함수
success : function(res){
},
5. 실패했을 때 함수
error : function(){
})
* 복습 *
페이지를 되돌려주는 메소드가 아니라 결과값을 화면에 출력해주는 메소드
@ResponseBody -> retrun
Spring 내부적으로 결과값 반환 라이브러리 ---> jackson-databind
조회한 column명 != 객체 필드명
--> <resultMap type = "객체의 풀네임" id = "변수명">
<result column = "colum명" property = "필드명 "/>
<result column = colum명" property = "필드명 "/>
</resultMap>
--> <select resultMap = "test"> </select>
* 파이차트 그리기 실습 *
- 10대 ~ 60대이상 --> 평균 시청률 --> 소수점 셋째자리
- 프로그램명이 뮤직뱅크인 데이터의 10대 ~ 60대 이상까지의 평균 시청률을 조회 --> 파이차트 그리기
1. SQL 구문 작성 --> work bench에서 잘 실행되는 지 체크
SELECT
PROGRAM_NM,
ROUND(AVG(N10S_RT), 3) AS N10S_RT,
ROUND(AVG(N20S_RT), 3) AS N20S_RT,
ROUND(AVG(N30S_RT), 3) AS N30S_RT,
ROUND(AVG(N40S_RT), 3) AS N40S_RT,
ROUND(AVG(N50S_RT), 3) AS N50S_RT,
ROUND(AVG(N60S_ABOVE_RT), 3) AS N60S_ABOVE_RT
FROM COM.BROADCAST
WHERE PROGRAM_NM = '뮤직뱅크';
2. pie 차트를 그려주고 있는 js 코드를 찾아주기
( canvas 태그이면 js로 한다. / 그리는건 하단에 script태그 확인한다. )
7. js로 돌아와서 pie 차트 들어갈 데이터 제작 후
8. 차트 그리기
// 페이지가 로드 완료되면 비동기 통신 시작하도록 코드 작성
$(function () { // document.ready() --> jquery로 표현한 것
$.ajax({
url: 'getAgeData',
dataType: 'json',
success: function (res) {
console.log(res);
// daat 생성하기
let my_labels = ['10대', '20대', '30대', '40대', '50대', '60대'];
// label 생성하기
let my_data = [];
my_data.push(res.n10s_rt);
my_data.push(res.n20s_rt);
my_data.push(res.n30s_rt);
my_data.push(res.n40s_rt);
my_data.push(res.n50s_rt);
my_data.push(res.n60s_above_rt);
// makePieChart 사용하기
makePieChart(my_labels, my_data);
},
error: function () {
console.log('실패ㅠ')
}
})
});
// Set new default font family and font color to mimic Bootstrap's default styling
Chart.defaults.global.defaultFontFamily = 'Nunito', '-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif';
Chart.defaults.global.defaultFontColor = '#858796';
function makePieChart(my_labels, my_data) {
// Pie Chart Example
var ctx = document.getElementById("myPieChart");
var myPieChart = new Chart(ctx, {
type: 'doughnut',
data: {
// labels DB에서 조회한 값 변경
labels: my_data,
datasets: [{
// data에 DB에서 조회한 값 가져오기
data: my_data,
labels: [55, 30, 15],
backgroundColor: ['#4e73df', '#1cc88a', '#36b9cc', '#4e73df', '#1cc88a', '#36b9cc'],
hoverBackgroundColor: ['#2e59d9', '#17a673', '#2c9faf'],
hoverBorderColor: "rgba(234, 236, 244, 1)",
}],
},
options: {
maintainAspectRatio: false,
tooltips: {
backgroundColor: "rgb(255,255,255)",
bodyFontColor: "#858796",
borderColor: '#dddfeb',
borderWidth: 1,
xPadding: 15,
yPadding: 15,
displayColors: false,
caretPadding: 10,
//data: my_data,
},
legend: {
display: false
},
cutoutPercentage: 80,
},
});
}
3. js파일 수정 --> 비동기통신 데이터 조회 요청을 보내게끔 작성
3-1. 객체 가져올때 소문자로 가져오기
3-2. 함수 블록화 시킬때 함수명 겹치치 않게하기 ( makePieChart )
3-3. 함수명 순서 동일하게 주기 ( my_labels, my_data )
4. 요청을 처리하는 url mapping 잡아주기 ( 컨트롤러 )
5. mapper 들을 사용해서 DB에서 데이터 조회하기
6. 결과값 반환
BroadCastController.java
package kr.smhrd.controller;
import java.util.ArrayList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import kr.smhrd.entity.BroadCast;
import kr.smhrd.mapper.BroadCastMapper;
@Controller // 1) 클래스파일이 Controller(POJO)임을 알려주기
public class BroadCastController {
// Mapper 인터페이스 사용할 수 잇게끔 연결
@Autowired
private BroadCastMapper mapper;
@RequestMapping("/") // 2) url mapping을 "/"로 들어왔을 떄 잡아주기
public String index(Model model) {
// db에서 데이터 조회하기
BroadCast vo = mapper.getRating();
model.addAttribute("vo", vo);
return "index";
// 3) /로 들어왔을 때 index.jsp 페이지를 forward방식으로 되돌려주기
}
// 월별 데이터 조회할 수 있는 url
@GetMapping("/getMonthData")
public @ResponseBody ArrayList<BroadCast> getMonthData() {
// @ResponseBody --> 비동기 통신으로 요청이 들어왔을 때
// --> 반환하는 결과값이 페이지 이름이 아니라,
// --> 웹 화면에 출력해야하는 결과값임을 나타내는 annotation
// ajax(비동기) 요청이 들어왔을 때, 결과값을 반환하려면 웹페이지 화면에 출력!
System.out.println("요청이 들어오니?");
// 1. db에서 월별 전체시청률 평균 조회해오기
ArrayList<BroadCast> result = mapper.getMonthData();
// 2. 조회한 결과값을 return 반환 시켜주기
return result;
// 만약에 객체, ArrayList 복잡한 형태를 화면에 출력하려면???
// --> jsp/servlet --> Gson 라이브러리 사용
// --> spring framework --> jackson-databind 라이브러리 사용(자동으로 결과값을 convert)
}
// 연령대별 데이터 조회
@RequestMapping("/getAgeData")
public @ResponseBody BroadCast getAgeData() {
BroadCast result = mapper.getAgeData();
System.out.println("들어오니?");
return result;
}
}
Mapper
package kr.smhrd.mapper;
import java.util.ArrayList;
import kr.smhrd.entity.BroadCast;
// @Mapper ---> 생략가능
public interface BroadCastMapper {
// 남/여/전체 시청률 평균을 조회하는 기능
// 조회한 결과 행이 하나이기 때문에 BroadCast로 받아오기!
// session.selectOne();
public BroadCast getRating();
public ArrayList<BroadCast> getMonthData();
public BroadCast getAgeData();
}
XML
- from : 앞에 com은 삭제해도 된다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="kr.smhrd.mapper.BroadCastMapper">
<select id="getRating" resultType="kr.smhrd.entity.BroadCast">
SELECT
PROGRAM_NM,
ROUND( AVG (
MALE_RT ) , 3 ) AS MALE_RT,
ROUND ( AVG( FEMALE_RT ) , 3 ) AS
FEMALE_RT,
ROUND ( AVG( WTCHNG_RT ) , 3 ) AS WTCHNG_RT
FROM
COM.BROADCAST
WHERE PROGRAM_NM = '뮤직뱅크';
</select>
<!-- DB에서 조회해 온 결과값의 column과 객체의 필드명이 서로 달랐을 때 사용할 수 있는 resultMap -->
<!-- id : resultMap의 이름(변수명) 정하는 attribute type : 내가 표현하고 싶은 객체(자료형) -->
<resultMap type="kr.smhrd.entity.BroadCast" id="monthData">
<!-- colunm : 조회해온 column 명칭 / property : 객체의 필드명 -->
<result column="DE" property="brdcst_de" />
<result column="RT" property="wtchng_rt" />
</resultMap>
<!-- 2) 월별 시청률 평균 조회하기 -->
<select id="getMonthData" resultMap="monthData">
SELECT MONTH(BRDCST_DE) AS
DE,
ROUND(AVG(WTCHNG_RT),3) AS RT
FROM BROADCAST
WHERE PROGRAM_NM = '뮤직뱅크'
GROUP BY DE
</select>
<!-- 3) 연령대별 시청률 평균 조회하기 -->
<select id="getAgeData" resultType="kr.smhrd.entity.BroadCast">
SELECT
PROGRAM_NM,
ROUND(AVG(N10S_RT), 3) AS N10S_RT,
ROUND(AVG(N20S_RT), 3) AS N20S_RT,
ROUND(AVG(N30S_RT), 3) AS N30S_RT,
ROUND(AVG(N40S_RT), 3) AS N40S_RT,
ROUND(AVG(N50S_RT), 3) AS N50S_RT,
ROUND(AVG(N60S_ABOVE_RT), 3) AS N60S_ABOVE_RT
FROM BROADCAST
WHERE PROGRAM_NM = '뮤직뱅크';
</select>
</mapper>
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<title>Dashboard</title>
<!-- Custom fonts for this template-->
<link href="resources/vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
<link href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i"
rel="stylesheet">
<!-- Custom styles for this template-->
<link href="resources/css/sb-admin-2.min.css" rel="stylesheet">
</head>
<body id="page-top">
<!-- Page Wrapper -->
<div id="wrapper">
<!-- Sidebar -->
<ul class="navbar-nav bg-gradient-primary sidebar sidebar-dark accordion" id="accordionSidebar">
<!-- Sidebar - Brand -->
<a class="sidebar-brand d-flex align-items-center justify-content-center" href="index.html">
<div class="sidebar-brand-icon rotate-n-15">
<i class="fas fa-laugh-wink"></i>
</div>
<div class="sidebar-brand-text mx-3">SB Admin <sup>2</sup></div>
</a>
<!-- Divider -->
<hr class="sidebar-divider">
<!-- Heading -->
<div class="sidebar-heading">
Page
</div>
<!-- Nav Item - Charts -->
<li class="nav-item">
<a class="nav-link" href="register">
<i class="fas fa-fw fa-clipboard-list"></i>
<span>출연진 관리</span></a>
</li>
<!-- Divider -->
<hr class="sidebar-divider d-none d-md-block">
<!-- Sidebar Toggler (Sidebar) -->
<div class="text-center d-none d-md-inline">
<button class="rounded-circle border-0" id="sidebarToggle"></button>
</div>
</ul>
<!-- End of Sidebar -->
<!-- Content Wrapper -->
<div id="content-wrapper" class="d-flex flex-column">
<!-- Main Content -->
<div id="content">
<!-- Topbar -->
<nav class="navbar navbar-expand navbar-light bg-white topbar mb-4 static-top shadow">
<!-- Sidebar Toggle (Topbar) -->
<button id="sidebarToggleTop" class="btn btn-link d-md-none rounded-circle mr-3">
<i class="fa fa-bars"></i>
</button>
<!-- Topbar Search -->
<form
class="d-none d-sm-inline-block form-inline mr-auto ml-md-3 my-2 my-md-0 mw-100 navbar-search">
<div class="input-group">
<input type="text" class="form-control bg-light border-0 small" placeholder="Search for..."
aria-label="Search" aria-describedby="basic-addon2">
<div class="input-group-append">
<button class="btn btn-primary" type="button">
<i class="fas fa-search fa-sm"></i>
</button>
</div>
</div>
</form>
</nav>
<!-- End of Topbar -->
<!-- Begin Page Content -->
<div class="container-fluid">
<!-- Page Heading -->
<div class="d-sm-flex align-items-center justify-content-between mb-4">
<h1 class="h3 mb-0 text-gray-800">Dashboard</h1>
</div>
<!-- Content Row -->
<div class="row">
<!-- Earnings (Monthly) Card Example -->
<div class="col-xl-3 col-md-6 mb-4">
<div class="card border-left-primary shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-primary text-uppercase mb-1">
${vo.program_nm} 남성 시청율 평균
</div>
<div class="row no-gutters align-items-center">
<div class="col-auto">
<div class="h5 mb-0 mr-3 font-weight-bold text-gray-800">${vo.male_rt}%</div>
</div>
<div class="col">
<div class="progress progress-sm mr-2">
<div class="progress-bar bg-primary" role="progressbar"
style="width:${vo.male_rt}%" aria-valuenow="${vo.male_rt}" aria-valuemin="0"
aria-valuemax="100"></div>
</div>
</div>
</div>
</div>
<div class="col-auto">
<i class="fas fa-clipboard-list fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6 mb-4">
<div class="card border-left-danger shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-danger text-uppercase mb-1">
${vo.program_nm} 여성 시청률 평균
</div>
<div class="row no-gutters align-items-center">
<div class="col-auto">
<div class="h5 mb-0 mr-3 font-weight-bold text-gray-800">${vo.female_rt}%</div>
</div>
<div class="col">
<div class="progress progress-sm mr-2">
<div class="progress-bar bg-danger" role="progressbar"
style="width: ${vo.female_rt}%" aria-valuenow="${vo.female_rt}" aria-valuemin="0"
aria-valuemax="100"></div>
</div>
</div>
</div>
</div>
<div class="col-auto">
<i class="fas fa-clipboard-list fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6 mb-4">
<div class="card border-left-info shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-info text-uppercase mb-1">
${vo.program_nm} 전체 시청률 평균
</div>
<div class="row no-gutters align-items-center">
<div class="col-auto">
<div class="h5 mb-0 mr-3 font-weight-bold text-gray-800">${vo.wtchng_rt}%</div>
</div>
<div class="col">
<div class="progress progress-sm mr-2">
<div class="progress-bar bg-info" role="progressbar"
style="width: ${vo.wtchng_rt}%" aria-valuenow="${vo.wtchng_rt}" aria-valuemin="0"
aria-valuemax="100"></div>
</div>
</div>
</div>
</div>
<div class="col-auto">
<i class="fas fa-clipboard-list fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Content Row -->
<div class="row">
<!-- Area Chart -->
<div class="col-xl-8 col-lg-7">
<div class="card shadow mb-4">
<!-- Card Header - Dropdown -->
<div
class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
<h6 class="m-0 font-weight-bold text-primary">${vo.program_nm} 월별 시청률 </h6>
</div>
<!-- Card Body -->
<div class="card-body">
<div class="chart-area">
<canvas id="myAreaChart"></canvas>
<!-- js파일은 head태그 안쪽(변수, 태그), body 끝나는 태그 위쪽에 로드(새로운태그, css속성변경할때) -->
</div>
</div>
</div>
</div>
<!-- Pie Chart -->
<div class="col-xl-4 col-lg-5">
<div class="card shadow mb-4">
<!-- Card Header - Dropdown -->
<div
class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
<h6 class="m-0 font-weight-bold text-primary">${vo.program_nm} 연령대별 시청률 </h6>
</div>
<!-- Card Body -->
<div class="card-body">
<div class="chart-pie pt-4 pb-2">
<canvas id="myPieChart"></canvas>
</div>
<div class="mt-4 text-center small">
<span class="mr-2">
<i class="fas fa-circle text-primary"></i> 10대
</span>
<span class="mr-2">
<i class="fas fa-circle text-success"></i> 20대
</span>
<span class="mr-2">
<i class="fas fa-circle text-info"></i> 30대
</span>
<span class="mr-2">
<i class="fas fa-circle text-info"></i> 40대
</span>
<span class="mr-2">
<i class="fas fa-circle text-info"></i> 50대
</span>
<span class="mr-2">
<i class="fas fa-circle text-info"></i> 60대이상
</span>
</div>
</div>
</div>
</div>
</div>
<!-- Content Row -->
<div class="row">
<!-- Content Column -->
<div class="col-lg-6 mb-4">
<!-- Project Card Example -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">출연진 TOP5</h6>
</div>
<div class="card-body">
<h4 class="small font-weight-bold">
NMIXX <span class="float-right">20%</span>
</h4>
<div class="progress mb-4">
<div class="progress-bar bg-danger" role="progressbar" style="width: 20%"
aria-valuenow="20" aria-valuemin="0" aria-valuemax="100"></div>
</div>
<h4 class="small font-weight-bold">
스테이씨 <span class="float-right">40%</span>
</h4>
<div class="progress mb-4">
<div class="progress-bar bg-warning" role="progressbar" style="width: 40%"
aria-valuenow="40" aria-valuemin="0" aria-valuemax="100"></div>
</div>
<h4 class="small font-weight-bold">
르세라핌 <span class="float-right">60%</span>
</h4>
<div class="progress mb-4">
<div class="progress-bar" role="progressbar" style="width: 60%"
aria-valuenow="60" aria-valuemin="0" aria-valuemax="100"></div>
</div>
<h4 class="small font-weight-bold">
뉴진스<span class="float-right">80%</span>
</h4>
<div class="progress mb-4">
<div class="progress-bar bg-info" role="progressbar" style="width: 80%"
aria-valuenow="80" aria-valuemin="0" aria-valuemax="100"></div>
</div>
<h4 class="small font-weight-bold">
아이브<span class="float-right">100%</span>
</h4>
<div class="progress">
<div class="progress-bar bg-success" role="progressbar" style="width: 100%"
aria-valuenow="100" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- /.container-fluid -->
</div>
<!-- End of Main Content -->
<!-- Footer -->
<footer class="sticky-footer bg-white">
<div class="container my-auto">
<div class="copyright text-center my-auto">
<span>Copyright © Your Website 2023</span>
</div>
</div>
</footer>
<!-- End of Footer -->
</div>
<!-- End of Content Wrapper -->
</div>
<!-- End of Page Wrapper -->
<!-- Scroll to Top Button-->
<a class="scroll-to-top rounded" href="#page-top">
<i class="fas fa-angle-up"></i>
</a>
<!-- Bootstrap core JavaScript-->
<script src="resources/vendor/jquery/jquery.min.js"></script>
<script src="resources/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
<!-- Core plugin JavaScript-->
<script src="resources/vendor/jquery-easing/jquery.easing.min.js"></script>
<!-- Custom scripts for all pages-->
<script src="resources/js/sb-admin-2.min.js"></script>
<!-- Page level plugins -->
<script src="resources/vendor/chart.js/Chart.min.js"></script>
<!-- Page level custom scripts -->
<script src="resources/js/demo/chart-area-demo.js"></script>
<script src="resources/js/demo/chart-pie-demo.js"></script>
</body>
</html>
'학원 > Spring' 카테고리의 다른 글
7. 검색했을때 데이터 들어가기 (0) | 2023.06.13 |
---|---|
6. REST 가 무엇인지? / 출연진 Top5 조회 (0) | 2023.06.09 |
4. 차트 그리기 ( 전체 조회하기 ) (0) | 2023.06.07 |
3. 게시판 조회하기 (0) | 2023.06.05 |
2. 게시글 전체조회하기 / 게시글 추가하기 ( Controller , DAO , DTO ) (0) | 2023.05.31 |