IT/development

[Chart.js] ํ†ต๊ณ„ ๋ฐ์ดํ„ฐ ์ฐจํŠธ ์ƒ์„ฑ (feat. ์•ˆ์ด์จ)

์•Œ ์ˆ˜ ์—†๋Š” ์‚ฌ์šฉ์ž 2024. 3. 1.

๋ชฉ์ฐจ

    DB์—์„œ ํ†ต๊ณ„  ์ฟผ๋ฆฌ ์‹คํ–‰ ํ›„ ๋ฐ์ดํ„ฐ๋ฅผ ํ™”๋ฉด๋‹จ์—์„œ ์ฐจํŠธ๋กœ ํ‘œ์‹œํ•˜๋Š” ๊ฐ„๋‹จํ•œ ์˜ˆ์ œ


    xml

    SELECT DATE_FORMAT(FRST_REG_DT, '%M') AS cond						/*์กฐ๊ฑด*/
    	 , COUNT(RVW_RSLT_CD) AS totalCnt 								/*์ „์ฒด*/		
    	 , COUNT(CASE WHEN RSLT_CD = '10' THEN 1 END) AS passedCnt 		/*์ฐฌ์„ฑ*/	
    	 , COUNT(CASE WHEN RSLT_CD = '20' THEN 1 END) AS rejectedCnt	/*๊ฑฐ์ ˆ*/
      FROM BOARD
     GROUP BY DATE_FORMAT(FRST_REG_DT, '%Y-%m')
     ORDER BY DATE_FORMAT(FRST_REG_DT, '%Y-%m')

    service

    public Map<String, Object> selectStatus(StatsSearchVO searchVO) {
    
        Map<String, Object> resultMap = new HashMap<>();
        //์›๋ณธ ๋ฐ์ดํ„ฐ
        List<StatsVO> statsList = new ArrayList<>();
        statsList = statsMapper.selectStatus(searchVO);
    
        String jsonData = "";
    
        if (statsList != null && statsList.size() > 0) {
            //json ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜
            jsonData = new Gson().toJson(statsList);
        }
        resultMap.put("resultList", statsList);
        resultMap.put("resultJsonData", jsonData);
    
        return resultMap;
    }

    controller

    @RestContorller, @ResponseBody.. ๋“ฑ ๋ฌด์Šจ ๋ฐฉ๋ฒ•์ด๋˜ json๋ฌธ์ž์—ด๋กœ ํ™”๋ฉด์œผ๋กœ ๋„˜๊ธฐ๋ฉด ๋œ๋‹ค.

    public ModelAndView selectStatus(ModelMap model, @ModelAttribute("searchVO")StatsSearchVO searchVO) {
    
        ModelAndView mav = new ModelAndView();
    
        mav.setViewName("jsonView");
        mav.addObject("resultMap", statsService.selectStatus(searchVO));
    
        return mav;
    }

    ํ™”๋ฉด๋‹จ

    ํ™”๋ฉด๋‹จ์—์„œ ํŽ˜์ด์ง€ ๋กœ๋“œ ํ›„ ์•„๋ž˜ ํ•จ์ˆ˜ ํ˜ธ์ถœ

    function initChart(jsonData) {
    	
    	// ๋ผ๋ฒจ, ๋ฐ์ดํ„ฐ(์ฐฌ์„ฑ, ๊ฑฐ์ ˆ)
    	var labels = [];
    	var passedCntList = [];
    	var rejectedCntList = [];
    
    	//์„œ๋ฒ„์—์„œ ๋ฐ›์€ jsonData๊ฐ€ ์žˆ์„ ๋•Œ๋งŒ
    	if (jsonData) {
    		var jData = JSON.parse(jsonData);
    
    		for (var i = 0; i < jData.length; i++) {
    			var data = jData[i];
    			labels.push(data.cond);
    			passedCntList.push(data.passedCnt);
    			rejectedCntList.push(data.rejectedCnt);
    		}
    	}
    
    	//์บ”๋ฒ„์Šค ์˜์—ญ
    	var ctx = document.getElementById('chart1').getContext('2d');
    	var config = {
    		type: 'bar',
    		data: {
    			labels: labels,
    			datasets: [{
    				label: '์ฐฌ์„ฑ',
    				backgroundColor: 'rgba(54, 162, 235, 0.5)',
    				borderWidth: 0,
    				data: passedCntList,
    			},
    				{
    					label: '๊ฑฐ์ ˆ',
    					backgroundColor: 'rgba(255, 99, 132, 0.5)',
    					borderWidth: 0,
    					data: rejectedCntList,
    				}]
    		},
    		options: {
    			scales: {
    				y: {
    					beginAtZero: true,
    					ticks: {
    						stepSize: 20 // y์ถ• ๊ฐ„๊ฒฉ์„ 20์œผ๋กœ ์„ค์ •
    					}
    				}
    			}
    		}
    	}
    
    	//๊ธฐ์กด ์ฐจํŠธ ํŒŒ๊ดด(์ด๊ฑฐ ์•ˆํ•˜๋ฉด chat.js์—์„œ ์—๋Ÿฌ ๋ฐœ์ƒ)
        //Uncaught Error: Canvas is already in use. Chart with ID '0' must be destroyed before the canvas with ID.... ์ด๋Ÿฐ..์—๋Ÿฌ
    	if (chart) {
    		chart.destroy();
    	}
    	//์บ”๋ฒ„์Šค ์‚ฌ์ด์ฆˆ ์ดˆ๊ธฐํ™”
    	var canvas = document.getElementById('chart1');
    	canvas.width = 600;
    	canvas.height = 200;
    	//์ฐจํŠธ ๊ฐ์ฒด ์ƒ์„ฑ
    	chart = new Chart(ctx, config);
    }

    ๊ฒฐ๊ณผ(์˜ˆ์‹œ)

    chat.js

    ๋Œ“๊ธ€