-
코로나19 백신 접종 현황 차트 페이지 만들기 - (4) charts 페이지 및 metricNode.js/예제 2021. 5. 29. 20:04
1. charts 페이지
<%- include('header') %> <%- include('hc') %> </head> <body> <div class="container"> <%- include('navbar') %> <div class="divrow"> <div class="compbox chartdiv1" id="metric"> <div class="metric-div"> <div class="metric-content"> <div class="metric-text" style="padding-top:50px;">Number of people vaccinated in the world</div> </div> <div class="metric-content num-value" id="pvValue"></div> </div> <div class="metric-div"> <div class="metric-content" style="height:20%"> <div class="metric-text">Number of people fully vaccinated in the world</div> </div> <div class="metric-content num-value" style="height:80%" id="pfvValue"></div> </div> </div> <div class="compbox chartdiv1" id="piechart"></div> <div class="compbox chartdiv1" id="column"></div> </div> <div class="divrow"> <div class="compbox chartdiv2" id="basicline"></div> <div class="compbox chartdiv2" id="heatmap"></div> </div> </div> <script src="js/metric.js"></script> <script src="js/piechart.js"></script> <script src="js/column.js"></script> <script src="js/basicline.js"></script> <script src="js/heatmap.js"></script> <script> drawMetricChart(); drawPieChart(); drawColumnChart(); drawLineChart(); drawHeatMap(); </script> </body> </html>
앞서 살펴본 charts.ejs 코드다. 공통 헤더(header.ejs)와 charts 페이지용 script(hc.ejs), navbar를 import하였다. 총 5개의 차트를 위한 영역을 만들어놓았고, 각 차트들은 각각의 script에서 작성된 함수가 호출되면서 그려진다.
charts.js
const express = require('express'); const router = express.Router(); const { getDataUsingSql, getDataQdsl } = require("./getdata"); router.get('/', async (req, res) => { res.render("charts"); }); router.post("/metric", async (req, res) => { }); router.post("/pie", async (req, res) => { }); router.post("/column", async (req, res) => { }); router.post("/heatmap", async (req, res) => { }); router.post("/line", async (req, res) => { }); module.exports = router;
앞서 작성한 getdata에 있는 getDataUsingSql, getDataQdsl 함수를 import하고, url '/'로 접속할 경우 charts.ejs를 렌더링할 수 있도록 라우터를 작성한다. 아래 post 라우터들은 개별 차트 데이터를 생성하기 위한 라우터들이다. 페이지 요청시 클라이언트 단에서 호출되는 함수를 통해 ajax post요청을 통해 서버로 요청을 전송하게 되고, 서버에서 조회된 데이터를 받아 다시 클라이언트 단에서 받은 데이터를 활용하여 차트를 생성한다.
2. metric 차트
elastic kibana 홈페이지에서는 metric을 다음과 같이 설명한다.
"A metric visualization displays a single number for each aggregation you select"
즉 count, sum, max, min 등 특정 집계 방식으로 생성된 집계 데이터 하나를 보여주는 차트이며, 주로 특정 주제로 만들어지는 페이지에서 가장 중요한 데이터 또는 대표적인 데이터 하나를 보여주는 차트로 사용된다.
키바나에서 메트릭 차트를 생성하면 위와 같은 형태로 만들어진다. 그래프가 그려지는 다른 차트들과는 달리 하나의 집계 데이터 숫자만 표시되며 타이틀 옵션을 체크할 경우 그에 대한 간략한 설명만 덧붙여진다.
메트릭 차트는 형태가 단순하기 때문에 여기에서는 별도 차트 라이브러리를 사용하지 않고 조회된 데이터를 직접 차트 영역에 띄워주기만 하였다.
예시에서 사용한 데이터는 전세계 백신 접종 인원 합계와 백신 접종 완료자 인원 합계 데이터다. 일별 측정되는 전체 접종자수는 누적 데이터이므로 가장 최근 데이터가 가장 큰 값을 갖는다. 집계 함수 중 max를 활용하여 현재까지의 값 중 가장 큰 데이터를 구한다.
router.post("/metric", async (req, res) => { const query1 = ` SELECT MAX(people_vaccinated) AS total FROM "country-vaccinations" WHERE people_vaccinated>0 GROUP BY country ORDER BY total DESC `; const query2 = ` SELECT MAX(people_fully_vaccinated) AS total FROM "country-vaccinations" WHERE people_fully_vaccinated>0 GROUP BY country ORDER BY total DESC `; try { const data1 = await getDataUsingSql(query1); const data2 = await getDataUsingSql(query2); const sum1 = data1.rows.map(el => el[0]).reduce((a, b) => a + b); const sum2 = data2.rows.map(el => el[0]).reduce((a, b) => a + b); res.json([sum1, sum2]); } catch (err) { console.error(err); } });
query1은 접종자수(1회라도 접종을 한 경우) 데이터에 대한 쿼리이고, query2는 접종 완료자수(제조사에 따라 2회 또는 3회를 접종해야 완전히 접종이 완료된다.) 데이터에 대한 쿼리다. 쿼리를 인자로 투입하여 getDataUsingSql 함수를 실행하면 columns와 rows 두 개의 값이 반환된다. columns는 칼럼명이 들어있는 1개의 배열값이고, 실제 결과값은 rows에 배열 형태로 저장이 된다.
적용된 쿼리는 국가별 백신 접종자수/완료자수를 조회하는 쿼리다. 현재 구하고자 하는 값은 전세계 백신 접종자/완료자수 합계이므로 쿼리를 통해 조회된 값을 모두 합하면 구하고자 하는 값을 구할 수 있다. map을 활용하여 배열에 들이있는 값을 가져와 reduce로 누적 합계를 구한다. 그리고 구한 값을 배열에 담아 클라이언트 단으로 보낸다.
3. metric.js
function drawMetricChart() { $.ajax({ url: "metric", type: "POST", dataType: "json", success: function (result) { const [pv, pfv] = result; document.getElementById("pvValue").innerText = addComma(pv); document.getElementById("pfvValue").innerText = addComma(pfv); }, error: function (request, status, error) { console.error(error); } }); }
metric.js는 charts.ejs에서 import된다. charts 메뉴 화면이 실행되면 drawMetricChart 함수가 호출이 되는데 이 함수는 실행되면서 ajax 요청을 한다. ajax 요청을 위에서 살펴본 백엔드 post router에서 받아 데이터를 elasticsearch에서 불러온 후 가공한 후 다시 json 형태로 ajax 요청 결과로 반환한다. 배열로 반환받은 2 개의 결과값을 구조분해 할당으로 각 변수에 받은 후 각각의 dom 위치에 값을 전달한다.
addComma 함수는 숫자 데이터에 콤마(,)를 추가해준다. js 디렉토리의 common.js에 있으며, header.ejs에서 import된다.
common.js
function addComma(num) { var regexp = /\B(?=(\d{3})+(?!\d))/g; return num.toString().replace(regexp, ','); }
'Node.js > 예제' 카테고리의 다른 글
코로나19 백신 접종 현황 차트 페이지 만들기 - (6) column chart (0) 2021.06.03 코로나19 백신 접종 현황 차트 페이지 만들기 - (5) highchart 라이브러리와 piechart (1) 2021.06.01 코로나19 백신 접종 현황 차트 페이지 만들기 - (3) node.js elasticsearch 모듈 설치와 사용 (0) 2021.05.29 코로나19 백신 접종 현황 차트 페이지 만들기 - (2) 소스 구조 및 view 코드 (0) 2021.05.29 코로나19 백신 접종 현황 차트 페이지 만들기 - (1) elasticsearch 세팅 및 데이터 업로드하기 (1) 2021.05.28