[ JS / Java ] 데이터베이스 자료를 가져와 차트로 보여주기

2024. 6. 11. 16:08[ Self-Study ]

환경 : Visual Studio Code, Spring Tools Suite4

 

 

 

- Chart.js 사이트에서 가져온 코드 

     Chart.js : https://www.chartjs.org/docs/latest/

<div>
  <canvas id="myChart"></canvas>
</div>

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

<script>
  const ctx = document.getElementById('myChart');

  new Chart(ctx, {
    type: 'bar',
    data: {
      labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
      datasets: [{
        label: '# of Votes',
        data: [12, 19, 3, 5, 2, 3],
        borderWidth: 1
      }]
    },
    options: {
      scales: {
        y: {
          beginAtZero: true
        }
      }
    }
  });
</script>

[ 차트 출력 코드 구현 해보기 ] 

출력 결과

[ 주요 코드 ]

    <!-- ChartJS cdn -->
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    
    <script type="text/javascript">
        $(function(){
          const ctx = document.querySelector(".custom-chart");
          //const ctx = $(".custom-chart");//jQuery
      
          //new Chart(캔버스태그, 차트옵션객체);
          new Chart(ctx, {
            type: 'bar', //차트 유형(bar, line, doughnut, pie, radar, scatter, bubble)
            data: {//차트에 표시될 정보
              labels: ['전기', '물', '불', '바람'], //항목명
              datasets: [
                {
                  label: '포켓몬스터 수', //범례
                  data: [5, 6, 2, 4], //실제 값
                  borderWidth: 3,
                  backgroundColor:["#d6303133", "#fdcb6e33", "#ffeaa733", "#00b89433", "#74b9ff33", "#0984e333", "#a29bfe33"],
                  borderColor:["#d63031", "#fdcb6e", "#ffeaa7", "#00b894", "#74b9ff", "#0984e3", "#a29bfe"],
                }
              ]
            },
            options: {
              scales: {
                y: {
                  beginAtZero: true//0을 차트의 시작점으로 할 것인가?
                }
              }
            }
          });
        });
    </script>
    <!-- ChartJS cdn -->
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

     (+) 사용할 라이브러리 주소 삽입

const ctx = document.querySelector(".custom-chart");
//const ctx = $(".custom-chart");//jQuery

     (+) custom-chart 클래스를 선택하여 ctx 변수에 삽입

     (+) const로 선언된 변수는 상수로 취급되어 값이 한 번 할당되면 변경할 수 없다

//new Chart(캔버스태그, 차트옵션객체);
new Chart(ctx, {
     type: 'bar', //차트 유형(bar, line, doughnut, pie, radar, scatter, bubble)
     data: {//차트에 표시될 정보
     labels: ['전기', '물', '불', '바람'], //항목명
     datasets: [
        {
           label: '포켓몬스터 수', //범례
           data: [5, 6, 2, 4], //실제 값

     (+) new Chart(캔버스 태그, 차트옵션객체);

     (+) 차트에 대한 설정하기 

options: {
    scales: {
         y: {
          beginAtZero: true//0을 차트의 시작점으로 할 것인가?
         }
    }
}

     (+) 차트의 시작점을 beginAtZero로 0부터 시작하도록 설정

 

</head>
<body>
    <div class="container w-500">
        <div class="cell center">
          <h1>Chart JS</h1>
        </div>
        <div class="cell">
          <!-- 차트 표시 영역 -->
          <canvas class="custom-chart"></canvas>
        </div>
    </div>
</body>
<!-- 차트 표시 영역 -->
<canvas class="custom-chart"></canvas>

     (+) canvas 태그에 클래스를 주어 차트가 캔버스 태그에 출력되도록 한다

 


[ 코드 순서 변경 및 DB에 저장되어 있는 정보를 불러와 차트로 보여주기 ]

출력결과

    - StatRestController.java

//통계데이터를 클라이언트에게 전송하는 컨트롤러
@CrossOrigin //CORS허용(교차출처 자원공유)//비동기 통신 시 남의 집 허락을 위해
@RestController
@RequestMapping("/rest/stat")
public class StatRestController {
	
	@Autowired
	private PocketmonDao pocketmonDao;
	
	@RequestMapping("/pocketmon")
	public List<StatVO> pocketmon() {
		return pocketmonDao.statByType();
	}
}

     (+) StatVO의 값을 리스트로 반환하도록 Dao의 statByType() 메소드를 출력하는 코드

 

   - StatVO.java

//VO(Value Object)
// - 테이블과 똑같이 생긴 DTO와는 달리 자유롭게 변형된 형태로 사용하기 위한 클래스
// - 생성 방식과 형태는 DTO와 동일
// - 조회하려면 Mapper가 필요
public class StatVO {
	private String title;
	private int count;

	public StatVO() {
		super();
	}
	
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public int getCount() {
		return count;
	}
	public void setCount(int count) {
		this.count = count;
	}
}

 

 

    - html : 서버에서 실제 데이터를 불러보자

  <script type="text/javascript">
    $(function () {
      //목표 : 서버에서 실제 데이터를 불러와서 그에 따른 차트를 구현
      $.ajax({
        url :"http://localhost:8080/rest/stat/pocketmon",
        method: "get",
        success: function(response) {
          console.log(response);
          //차트에 들어갈 수 있도록 데이터 구조 변경
          //- JS의 배열은 자동 증가하며 추가명령은 .push()이다
          var labelList = [];
          var dataList = [];

          for (var i = 0; i < response.length; i++) {
            labelList.push(response[i].title);
            dataList.push(response[i].count);
          }

          //완성된 labelList와 dataList를 이용하여 차트 생성하는 구문
          const ctx = document.querySelector(".custom-chart");
          //const ctx = $(".custom-chart");//jQuery

          //new Chart(캔버스태그, 차트옵션객체);
          new Chart(ctx, {
            type: 'bar', //차트 유형(bar, line, doughnut, pie, radar, scatter, bubble)
            data: {//차트에 표시될 정보
              labels: labelList, //항목명
              datasets: [
                {
                  label: '포켓몬스터 수', //범례
                  data: dataList, //실제 값
                  borderWidth: 3,
                  backgroundColor: ["#a5b1c233", "#d1d8e033", "#4b658433", "#778ca333"],
                  borderColor: ["#a5b1c2", "#d1d8e0", "#4b6584", "#778ca3"]
                }
              ]
            },
            options: {
              //데이터 범례(라벨)을 표시되지 않도록 하는 속성
              plugins: {
                legend:{
                  display:false,//라벨 미표시
                }
              }
            }
          });
        }

      });


    });
  </script>
url :"http://localhost:8080/rest/stat/pocketmon", //접속할 주소
method: "get", //방법(get/post 둘 다 상관 없음)
success: function(response) {
    console.log(response);
    //차트에 들어갈 수 있도록 데이터 구조 변경
    //- JS의 배열은 자동 증가하며 추가명령은 .push()이다
    var labelList = [];
    var dataList = [];
    
    for (var i = 0; i < response.length; i++) {
       labelList.push(response[i].title);
       dataList.push(response[i].count);
    }

     (+) 주석 참고

//완성된 labelList와 dataList를 이용하여 차트 생성하는 구문
const ctx = document.querySelector(".custom-chart");

     (+) 주석 참고

options: {
   //데이터 범례(라벨)을 표시되지 않도록 하는 속성
   plugins: {
       legend:{
          display:false,//라벨 미표시
       }
   }
}

     (+) 라벨을 보이지 않도록 가리는 옵션 추가

 


(추가) 여러개의 차트를 한 번에 출력하기 위해 반복문을 jquery에서 실행

  <script type="text/javascript">
    $(function () {
      //- 캔버스의 개수만큼 진행
      //- jquery의 each 함수를 이용하여 반복 실행
      $(".custom-chart").each(function () {
        //this == 현재 회차의 canvas
        var canvas = this;
        var type = $(this).data("type");//data-type 속성을 읽는다

        //비동기 통신 후 차트 생성 코드
        $.ajax({
          url: "http://localhost:8080/rest/stat/"+ type,
          method: "get",
          success: function (response) {
            var labelList = [];
            var dataList = [];

            for (var i = 0; i < response.length; i++) {
              labelList.push(response[i].title);
              dataList.push(response[i].count);
            }
        });
      });
    });
  </script>

     (+) 접속 주소만 다르므로, 주소 부분만 data-set으로 설정해주고,

          나머지는 반복하여 출력하도록 실행 (백엔드도 StatVO를 일치시켜줘서 가능)

//- 캔버스의 개수만큼 진행
//- jquery의 each 함수를 이용하여 반복 실행
$(".custom-chart").each(function () {
   //this == 현재 회차의 canvas
   var canvas = this;
   var type = $(this).data("type");//data-type 속성을 읽는다

     (+) custom-chart 클래스를 반복하도록 each() 함수를 사용

     (+) 현재 this는 현재 회차의 canvas

     (+) data-set을 준 값을 type 변수에 삽입

 


 

[ (추가에 대한) 전체 코드 ]

<!DOCTYPE html>
<html lang="ko">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Javascript 예제</title>

  <!-- 구글 폰트 -->
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@100..900&display=swap" rel="stylesheet">

  <!-- 내가 구현할 스타일 -->
  <link rel="stylesheet" type="text/css" href="../css/commons.css">
  <link rel="stylesheet" type="text/css" href="../css/test.css">

  <!-- font awesome 아이콘 CDN -->
  <link rel="stylesheet" type="text/css"
    href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">

  <style>

  </style>

  <!-- jquery cdn -->
  <script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script>

  <!-- ChartJS cdn -->
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
  <!-- 내가 만든 스크립트 추가(jQuery를 사용했으니 jQuery CDN 아래 작성) -->
  <script src="commons.js"></script>

  <!-- javascript를 의도적으로 head 자리에 배치해서 가장 먼저 실행되도록 구현 -->
  <script type="text/javascript">
    $(function () {
      //목표 : 서버에서 실제 데이터를 불러와서 그에 따른 차트를 구현
      //- 캔버스의 개수만큼 진행
      //- jquery의 each 함수를 이용하여 반복 실행
      $(".custom-chart").each(function () {
        //this == 현재 회차의 canvas
        var canvas = this;
        var type = $(this).data("type");//data-type 속성을 읽는다

        //비동기 통신 후 차트 생성 코드
        $.ajax({
          url: "http://localhost:8080/rest/stat/"+ type,
          method: "get",
          success: function (response) {
            var labelList = [];
            var dataList = [];

            for (var i = 0; i < response.length; i++) {
              labelList.push(response[i].title);
              dataList.push(response[i].count);
            }


            new Chart(canvas, {
              type: 'bar', //차트 유형(bar, line, doughnut, pie, radar, scatter, bubble)
              data: {//차트에 표시될 정보
                labels: labelList, //항목명
                datasets: [
                  {
                    data: dataList, //실제 값
                    borderWidth: 3,
                    backgroundColor: ["#a5b1c233", "#d1d8e033", "#4b658433", "#778ca333"],
                    borderColor: ["#a5b1c2", "#d1d8e0", "#4b6584", "#778ca3"]
                  }
                ]
              },
              options: {
                //데이터 범례(라벨)을 표시되지 않도록 하는 속성
                plugins: {
                  legend: {
                    display: false,//라벨 미표시
                  }
                },
              }
            });
          }

        });

      });


    });
  </script>
</head>

<body>


  <div class="container w-800">
    <div class="cell center">
      <h1>모든차트를 한방에</h1>
    </div>
    <div class="cell flex-cell">
      <div class="w-50 center p-20">
        <h3>포켓몬스터 현황</h3>
        <canvas class="custom-chart" data-type="pocketmon"></canvas>
      </div>
      <div class="w-50 center p-20">
        <h3>사원 현황</h3>
        <canvas class="custom-chart" data-type="emp"></canvas>
      </div>

    </div>
    <div class="cell flex-cell">
      <div class="w-50 center p-20">
        <h3>메뉴 현황</h3>
        <canvas class="custom-chart" data-type="menu"></canvas>
      </div>
      <div class="w-50 center p-20">
        <h3>회원 현황</h3>
        <canvas class="custom-chart" data-type="member"></canvas>
      </div>

    </div>
  </div>



</body>

</html>

 

 

개인 공부 기록용입니다:)

 

 

728x90