상세 컨텐츠

본문 제목

[ React.js ] 코로나19, API, 차트 출력하기 - 예제

FrontEnd/React.js

by SangHoonE 2021. 9. 8. 23:36

본문

반응형

안녕하세요 상훈입니다.

리액트 - 차트를 이용해 코로나19의 현황을 간단하게 알아보는 예제를 출력하겠습니다.

결과화면

Contents.js

import React, {useState, useEffect} from 'react'
import { Bar, Doughnut, Line } from "react-chartjs-2"
import axios from 'axios'


const Contents = () => {

    const [confirmedData, setConfirmedData] = useState({})
    const [quarantinedData, setQuarantinedData] = useState({})
    const [comparedData, setComparedData] = useState({})




    useEffect(() => {
        const fetchEvents = async () => {
            const res = await axios.get("https://api.covid19api.com/total/dayone/country/kr")
            console.log(res)
            makeData(res.data)

        }
        const makeData = (items)=>{
            const arr = items.reduce((acc, cur) => {
                const currentDate = new Date(cur.Date)
                const year = currentDate.getFullYear()
                const month = currentDate.getMonth()
                const date = currentDate.getDate()
                const confirmed = cur.Confirmed
                const active = cur.Active
                const death = cur.Death
                const recovered = cur.Recovered

                const findItem = acc.find(a=> a.year === year && a.month === month)

                if(!findItem){
                    acc.push({ year, month, date, confirmed, active, death, recovered })
                }
                if(findItem && findItem.date < date){
                    findItem.active = active
                    findItem.death = death
                    findItem.date = date
                    findItem.year = year
                    findItem.month = month
                    findItem.recovered = recovered
                    findItem.confirmed = confirmed

                }
                return acc;

            }, [])


            const labels = arr.map(a => `${a.month+1}월`)
            setConfirmedData({
                labels,
                datasets: [
                    { 
                        label: "국내 누적 확진자", 
                        backgroundColor: "salmon",
                        fill: true,
                        data: arr.map(a => a.confirmed)
                    },
                ]
            })

            setQuarantinedData({
                labels,
                datasets: [
                    { 
                        label: "월별 격리자 현황", 
                        borderColor: "salmon",
                        fill: false,
                        data: arr.map(a => a.active)
                    },
                ]
            })

            const last = arr[arr.length -1 ]
            setComparedData({
                labels: ["확진자","격리해제","사망"],
                datasets: [
                    { 
                        label: "누적 확진, 해제, 사망 비율", 
                        backgroundColor: ["#ff3d67", "#059bff", "#ffc233"],
                        borderColor: ["#ff3d67", "#059bff", "#ffc233"],
                        fill: false,
                        data: [last.confirmed, last.recovered, last.death]
                    },
                ]
            })
        }
        fetchEvents()
    }, [])

    return (
        <section>
            <h2>국내 코로나 현황</h2>
            <div className="contents">
                <div>
                    <Bar data={confirmedData} options={
                        {title: { display : true, text: "누적 확진자 추이", fontSize: 16 } },
                        {legend: {display : true, position: "bottom"} }
                    } />
                </div>
                <div>
                    <Line data={quarantinedData} options={
                        {title: { display : true, text: "월별 격리자 현황", fontSize: 16 } },
                        {legend: {display : true, position: "bottom"} }
                    } />
                </div>
                <div>
                    <Doughnut data={comparedData} options={
                        {title: { display : true, text: `누적 확진, 해제, 사망 (${new Date().getMonth() + 1 })`, fontSize: 16 } },
                        {legend: {display : true, position: "bottom"} }
                    } />
                </div>
            </div>
        </section>
    )
}

export default Contents

 

 

App.css

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

.header {
  background-color: #3b5998;
  display: flex;
  justify-content: space-between;
  padding: 1rem 2rem;
  align-items: center;
}

.header h1{
  color:azure;
}

.header select {
  height: 30px;
  width: 140px;
  border-radius: 5px;
  border: none;
}

section {
  padding: 1rem;
}

.contents {
  width: 60%;
  text-align:center;
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-gap : 2rem;
}

 

원형차트는 아무래도 확진자 대비 나머지 비율이 너무 작아서 안보이는 건지,,,, 아니면 제가 api 적용을 잘못한건지 헷갈립니다... ㅠㅠ

나중에 확인 해야할 것 같아요. 그럼 이만ㅌㅌ

 

 

강의 참고

React.js로 웹앱 만들기

 

리액트와 가까워지기.
(어렵당)

 

관련글 더보기

댓글 영역