본문 바로가기

코드스테이츠 SEB FE 41기/Main-Project(MatP)

[react] 간단히 star rating chart 구현하기(feat. typeScript)

반응형

리액트로 간단히 별점 종합 차트를 만들어보자. 마치 배민처럼!

 

먼저 컴포넌트 구성을 해준다.

<RatingsChart>
      <div className="card">
            <table>
                 <tbody>
                      <tr>
                        <td className="rating-label">Excellent</td>
                        <td className="rating-bar">
                          <div className="bar-container">
                            <div
                              className="bar"
                              style={{ width: `${ratingsAvg(starCount[4])}%` }}
                            ></div>
                          </div>
                        </td>
                        <td className="rating-count">{starCount[4]}</td>
                      </tr>
                      <tr>
                        <td className="rating-label">Good</td>
                        <td className="rating-bar">
                          <div className="bar-container">
                            <div
                              className="bar"
                              style={{ width: `${ratingsAvg(starCount[3])}%` }}
                            ></div>
                          </div>
                        </td>
                        <td className="rating-count">{starCount[3]}</td>
                      </tr>
                      <tr>
                        <td className="rating-label">Average</td>
                        <td className="rating-bar">
                          <div className="bar-container">
                            <div
                              className="bar"
                              style={{ width: `${ratingsAvg(starCount[2])}%` }}
                            ></div>
                          </div>
                        </td>
                        <td className="rating-count">{starCount[2]}</td>
                      </tr>
                      <tr>
                        <td className="rating-label">Poor</td>
                        <td className="rating-bar">
                          <div className="bar-container">
                            <div
                              className="bar"
                              style={{ width: `${ratingsAvg(starCount[1])}%` }}
                            ></div>
                          </div>
                        </td>
                        <td className="rating-count">{starCount[1]}</td>
                      </tr>
                      <tr>
                        <td className="rating-label">Terrible</td>
                        <td className="rating-bar">
                          <div className="bar-container">
                            <div
                              className="bar"
                              style={{ width: `${ratingsAvg(starCount[0])}%` }}
                            ></div>
                          </div>
                        </td>
                        <td className="rating-count">{starCount[0]}</td>
                      </tr>
                 </tbody>
            </table>
     </div>
</RatingsChart>

CSS는 styled-component를 이용하여 작성해준다.

const RatingsChart = styled.div`
  .card {
    padding: 30px 30px 20px 30px;
  }

  .rating-label {
    font-weight: bold;
    font-size: 15px;
  }

  .rating-box {
    width: 130px;
    height: 130px;
    margin-right: auto;
    margin-left: auto;
    background-color: #fcc419;
    color: #fff;
  }

  .rating-label {
    font-weight: bold;
  }

  /* Rating bar width */
  .rating-bar {
    width: 300px;
    padding: 4px;
    border-radius: 5px;
  }

  /* The bar container */
  .bar-container {
    width: 100%;
    background-color: #f1f1f1;
    text-align: center;
    color: white;
    border-radius: 20px;
  }

  /* Individual bars */
  .bar {
    height: 13px;
    background-color: #fcc419;
    border-radius: 20px;
  }

  td {
    padding: 0px 0px 8px 0px;
  }

  .rating-count {
    font-size: 15px;
  }
`;

별점 매기기 기능과 마찬가지로 차트 바가 노란색으로 채워지도록 하는 컴포넌트의 width를 항목별로 계산하여 설정해주어야 한다.

 

그렇다면 계산을 해보자.

starCount 배열안의 각 요소는 0점부터 5점까지 별점을 매긴 유저 수를 나타낸다. 0번째 요소가 0점을 매긴 유저 수의 합, 4번째 요소가 5점을 매긴 유저 수의 합이 된다.

"starCount": [0, 0, 0, 1, 3]

percentage 계산을 위해 별점을 매긴 유저의 총합을 먼저 구해주자.

 // 평점 매긴 유저 수 총합
  const ratingsTotal = starCount.reduce(
    (acc: number, cur: number) => (acc += cur),
    0
  );

width 속성에 percentage 계산 값을 넣어 적용해주어야 하므로 inline styling을 사용해야한다.그에 따른 함수를 하나 만들어주자.

const ratingsAvg = (el: number) => (el / ratingsTotal) * 100;

이 함수는 아규먼트가 starCount 배열의 각 요소이며, 리턴값은 그 아규먼트 값을 percentage로 변환한 값이 된다.

<div className="bar-container">
    <div
       className="bar"
       style={{ width: `${ratingsAvg(starCount[4])}%` }}
    ></div>
</div>

 

결과는?!

노랑노랑한 예쁜 차트를 볼 수 있다!

 

참고한 블로그

https://bbbootstrap.com/snippets/rating-and-review-system-user-comment-section-41283119

 

Bootstrap 4 rating and review system with user comment section Example

Bootstrap 4 rating and review system with user comment section snippet for your project 📌📌. this snippet is created using HTML, CSS, Bootstrap 4, Javascript

bbbootstrap.com

 

반응형