Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- peerdependencies
- 스코프
- 새 코드 받아오기
- mixin pattern
- Babel과 Webpack
- js pattern
- 모던 자바스크립트 Deep Dive
- 제너레이터와 async/await
- middleware pattern
- DOM
- pr review
- 브라우저의 렌더링 과정
- 올림픽 통계 서비스 최적화
- const
- 블로그 서비스 최적화
- 학습내용정리
- 커리어
- version management
- 이미지 갤러리 최적화
- package management
- 프로그래머스
- 프론트엔드 성능 최적화 가이드
- js pattern
- 진행기록
- 자바스크립트
- 딥다이브
- unique identifiers
- 자바스크립트 패턴
- 이벤트
- 자바스크립트 딥다이브
Archives
- Today
- Total
Dev Blog
Completed Map_20210430_Day3 본문
[ADD]Make Covid19 Map function
- Utilize Leaflet Service for making Map
- Circles for Covid19 / Recovered / Deaths
- Detect location of country and zoom-in
- Click Effects on infoboxes by CSS
맵 구현
1) useEffect in App.js, 모든 국가의 바이러스 관련 데이터를 fetch 해온다
await fetch("https://disease.sh/v3/covid-19/countries")
2) setMapCountries 의 상태로 데이터 저장
3) 상태값 mapCenter, mapZoom, mapCountries, casesType 을 Map 컴포넌트에 전달
App.js
import React, { useState, useEffect } from 'react'
import './App.css';
import {
MenuItem,
FormControl,
Select,
Card,
CardContent
} from "@material-ui/core"
import InfoBox from './Infobox'
import Map from './Map'
import Table from './Table'
import LineGraph from './LineGraph'
import { sortData, prettyPrintStat } from './util'
import 'leaflet/dist/leaflet.css'
function App() {
...생략...
const [mapCenter, setMapCenter] = useState({ lat: 37, lng: 127.5});
const [mapZoom, setMapZoom] = useState(3);
const [mapCountries, setMapCountries] = useState([]);
const [casesType, setCasesType] = useState("cases");
...생략...
useEffect(() => {
const getCountriesData = async () => {
await fetch("https://disease.sh/v3/covid-19/countries")
.then(res => res.json())
.then((data) =>{
const countries = data.map((country)=> (
{
name:country.country,
value: country.countryInfo.iso2
}
))
// console.log(data)
const sortedData = sortData(data);
setTableData(sortedData);
setMapCountries(data);
setContries(countries);
// console.log(countries)
})
}
getCountriesData();
}, [])
...생략...
return (
<div className="app">
<div className="app__left">
...생략...
<Map countries={mapCountries} casesType={casesType} center={mapCenter} zoom={mapZoom}/>
</div>
...생략...
</div>
);
}
export default App;
4) react-leaflet 라이브러리의 해당 엘리먼트에 각 상태(mapCenter, mapZoom, mapCountries, casesType)를 전달
<MapContainer>
<ChangeView center={center} zoom={zoom}/>
<TileLayer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
/>
{showDataOnMap(countries, casesType)}
</MapContainer>
Map.js
import React from 'react';
import { MapContainer, TileLayer, Marker, Popup, useMap } from 'react-leaflet';
import './Map.css';
import { showDataOnMap } from './util';
function Map({countries, casesType, center, zoom}) {
function ChangeView({ center, zoom }) {
const map = useMap();
map.setView(center, zoom);
return null;
}
// console.log(countries.country)
// console.log(casesType)
// console.log(typeof casesType)
return (
<div className="map">
<MapContainer>
<ChangeView center={center} zoom={zoom}/>
<TileLayer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
/>
{showDataOnMap(countries, casesType)}
</MapContainer>
</div>
)
}
export default Map
5) showDataOnMap 컴포넌트에서 data 와 casesType 을 받아,
a. Circle 엘리먼트의 center(국가의 위도와 경도)를 추출 및 반영
b. casesTypeColors 를 이용하여 casesType 에 따라 radius(반경) 산출, pathOptions 에서 다른 색 적용
c. Popup 엘리먼트에 국기 이미지, cases, recovered, deaths 수를 반영
6) 렌더링
util.js - showDataOnMap
import React from 'react';
import { Circle, Popup } from 'react-leaflet';
import numeral from 'numeral';
const casesTypeColors = {
cases: {
hex: "#CC1034",
rgb: "rgb(204, 16, 52)",
half_op: "rgba(204, 16, 52, 0.5)",
multiplier: 400,
},
recovered: {
hex: "#7DD71D",
rgb: "rgb(125, 215, 29)",
half_op: "rgba(125, 215, 29, 0.5)",
multiplier: 500,
},
deaths: {
hex: "#fb4443",
rgb: "rgb(251, 68, 67)",
half_op: "rgba(251, 68, 67, 0.5)",
multiplier: 1000,
},
};
...생략...
//Draw circles on the map with interative tooltip
export const showDataOnMap = (data, casesType) =>(
data.map(country => (
<Circle
center={[country.countryInfo.lat, country.countryInfo.long]}
fillOpacity={0.4}
pathOptions={{
color:casesTypeColors[casesType].hex,
fillColor: casesTypeColors[casesType].hex
}}
radius={
Math.sqrt(country[casesType]) * casesTypeColors[casesType].multiplier
}
>
<Popup style={{display:"flex", backgroundColor:"gray"}}>
<div className="info-container">
<div className="info-flag">
<img src={`${country.countryInfo.flag}`} alt=""/>
</div>
<div className="info-confirmed">Cases: {numeral(country.cases).format("0,0")}</div>
<div className="info-recovered">Recovered: {numeral(country.recovered).format("0,0")}</div>
<div className="info-deaths">Deaths: {numeral(country.deaths).format("0,0")}</div>
<div></div>
</div>
</Popup>
</Circle>
))
)
추가 진행 예정
- 코드 로직 리뷰 및 적용 라이브러리 사용법 정리
- CSS refactoring
도움 받은 사이트
- React leaflet center attribute does not change when the center state changes
- leafletjs.com/react-leaflet.js.org/docs/start-installation
- install leaflet: github.com/PaulLeCam/react-leaflet/issues/491
'Projects > Covid19 Tracker' 카테고리의 다른 글
Category/Data table/Basic Map_20210429_Day2 (0) | 2021.04.30 |
---|---|
Initial Set up & Covid19 API_20210428 _Day1 (0) | 2021.04.29 |
Comments