개선된 코로나 현황 사이트 CoronaTracerMk2 - 7

원래 확진자 분포에 따라 지도에 원을 그려주는것 까지 저번 포스팅에서 마무리 하려고 했으나

이런 에러를 띄우며 먹통이 되어 하루종일 코드리뷰를 하며 에러를 해결하려고 했다.
그리고 마침내 에러가 해결되어 이번 포스팅을 작성한다.
일단 이 에러가 발생하기 전까지의 코드를 작성해보면 우리는 utill.js에 지도에 원을 그려주는 함수 showDataOnMap을 만들거다.
여기서도 react-leaflet에서 제공하는 라이브러리를 사용할 것이기에 해당 라이브러리를 import하고

export const showDataOnMap = (data, casesType = "cases") =>
  data.map((country) => (
    <Circle
      center={[country.countryInfo.lat, country.countryInfo.long]}
      fillOpacity={0.4}
      color={casesTypeColors[casesType].hex}
      fillcolor={casesTypeColors[casesType].hex}
      radius={
        Math.sqrt(country[casesType]) * casesTypeColors[casesType].multiplier
      }
    >
      <Popup>
        <h1>Pop</h1>
      </Popup>
    </Circle>
  ));

data와 casesType를 파라미터로 받고 data에 map메소드를 사용해 모든 country에 대해 중앙에 각 수치에 대해 가중치를 두어 지정한 색깔대로 원을 그려주는 코드이다.
그리고 Popup에는 수치들을 적어줄 예정이지만 지금은 간단하게 테스트용으로 h1태그만 넣었다.
여기서 끝이 아니고 색과 가중치를 지정해줘야 하는데

const casesTypeColors = {
  cases: {
    hex: "#CC1034",
    rgb: "rgb(204, 16, 52)",
    half_op: "rgba(204, 16, 52, 0.5)",
    multiplier: 800,
  },
  recovered: {
    hex: "#7dd71d",
    rgb: "rgb(125, 215, 29)",
    half_op: "rgba(125, 215, 29, 0.5)",
    multiplier: 1200,
  },
  deaths: {
    hex: "#fb4443",
    rgb: "rgb(251, 68, 67)",
    half_op: "rgba(251, 68, 67, 0.5)",
    multiplier: 2000,
  },
};

요렇게 지정해주면 된다. 이는 react-leaflet의 라이브러리 중 Circle의 사용방법이다.
이렇게 함수를 만들어주고 Map.js에서 실행해주자.

          attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
        />
        {showDataOnMap(countries, casesType)}
      </LeafletMap>
    </div>

사이에 방금 만든 함수를 넣고 실행해보면

앞서 언급한 요 에러가 나온다.
무엇이 문제일까 거의 반나절을 코드리뷰한 결과 1글자 차이의 오타가 원인임을 알아내었다.

        {/*Map*/}
        <Map countires={mapCountries} center={mapCenter} zoom={mapZoom} />
      </div>
      <Card className="app_right">

App.js의 Map부분인데 countries를 countires로 써 놓았다..
에러 메시지 자체는 정확한 것이 'countires'라는 것은 undefined인 상태가 맞기 때문
대부분의 오류는 휴먼에러일 가능성이 높기 때문에 글자 하나하나 잘 살펴보는것이 좋다.
해당 부분을 수정하고 다시 확인하면

잘 작동한다.
그런데 그 사이 확진자가 예상보다 훨씬 증가하여 온 지도가 원으로 덮여있다;; 가중치를 조절하여 해결하자 한 1/10정도로 조절하면 될 것 같다.
이제 이 원들을 클릭해보면

아까 Popup태그 내에 작성한 h1태그가 팝업된다.
이제 이 h1태그를 필요한 정보로 바꿔주자

      <Popup>
        <div
          style={{ backgroundImage: `url(${country.countryInfo.flag})` }}
        ></div>
        <div>{country.country}</div>
        <div>Cases: {country.cases}</div>
        <div>Recovered: {country.recovered}</div>
        <div>Deaths: {country.deaths}</div>
      </Popup>

이제 Circle을 클릭해보면

해당 국가의 데이터가 잘 보인다.
그런데 맨 첫번째 div태그는 해당 국가의 국기를 나타낼것 같은데 나오질 않는다.
스타일을 적용하지 않았기 때문인데 스타일을 적용하기 위해 div태그로 한번 더 감싸고 className을 붙여주자

      <Popup>
        <div className="info-container">
          <div
            className="info-flag"
            style={{ backgroundImage: `url(${country.countryInfo.flag})` }}
          ></div>
          <div className="info-name">{country.country}</div>
          <div className="info-comfirmed">Cases: {country.cases}</div>
          <div className="info-recovered">Recovered: {country.recovered}</div>
          <div className="info-deaths">Deaths: {country.deaths}</div>
        </div>
      </Popup>

이제 Map.css에 스타일을 적용해주면

.info-container {
  width: 150px;
}

.info-name {
  font-size: 16px;
  font-weight: bold;
  color: #555;
}

.info-comfirmed,
.info-recovered,
.info-deaths {
  font-size: 12px;
  margin-top: 3px;
}

.info-flag img {
  width: 100px;
  border-radius: 5px;
}

.info-flag {
  height: 100px;
  width: 100%;
  background-size: contain;
  background-repeat: no-repeat;
}


그럭저럭 만족할만한 팝업창이 완성되었다.
숫자가 좀 정리되어있지 않은게 만족스럽지 않으니 numeral이란 라이브러리를 이용해 정리하자
instll하고 import한 뒤

      <Popup>
        <div className="info-container">
          <div
            className="info-flag"
            style={{ backgroundImage: `url(${country.countryInfo.flag})` }}
          ></div>
          <div className="info-name">{country.country}</div>
          <div className="info-comfirmed">
            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>
      </Popup>

데이터들을 정리한 값으로 바꿔주면

훨씬 깔끔해졌다.

이제 필요한 것들은다 완성했으니 남은것은 위의 데이터를 정리한 것과 비슷한 스타일링들 뿐이다.

좋은 웹페이지 즐겨찾기