Udemy - React완벽가이드
차트 추가하기
Hanachoi
2023. 3. 9. 13:35
- 지출내용을 bar chart로 보여주는 부분을 만들어보자.
- Chart 컴포넌트들을 별도의 파일로 분리해서 만들어준다.
- 이제 큰 Chart안에 작은 Chart bar 들을 넣어서 차트를 만들 것이다. Chart 컴포넌트 안에는 간단히 12개월치 개별 바를 넣어서 랜더링도 가능하다. <ChartBar />를 12개 만들어 주는 것
- 하지만 데이터를 동적으로 만들어서 차트를 위해 활용되는 데이터 포인트를 props로 받을 수 있도록 해보자.
- props.datapoints를 map으로 돌려주면 배열을 반환하게 될 것이다.
- 각각의 datapoint를 받아서 <ChartBar />컴포넌트로 매핑을 해준다. 우리가 가지고 있는 datapoints만큼 <ChartBar />컴포넌트를 만들 수 있다.
- 물론 여기서 ChartBar로 몇몇 데이터를 전달해서 어떻게 렌더링할 지 조절할 수 있다. 컴포넌트를 만드는건 우리니까 미래에 무슨 데이터를 추출해서 쓸 지 정할 수 있다.
- datapoint는 value값이 필요할 것. value를 넣어주면 모든 datapoints들은 속성으로 value를 가질 것이다.
- 이 value값은 전체 차트의 최대값을 기준으로 표시된다. 그래서 속성으로 maxValue도 전달해준다.
- maxValue 값은 주어진 차트에서 차트 바에 대해 동일한 고유값이기 때문이다. 그래서 우리는 최대값을 뽑아내야되지만 지금은 일단 null로 값을 채워준다.
- key값도 추가해야 한다. 이 key가 아이템 목록을 효과적으로 랜더링 할 수 있도록 리액트를 돕기 때문이다. 모든 dataPoints는 고유 id를 갖거나 또는 label을 활용할 수도 있다. label은 유니크한 값을 가져야하고 모든 차트의 바는 각각의 고유한 레이블을 가진다. 이걸 고유 식별자로 사용할 수 있다.
# 동적스타일 추가하기
- CharBar 컴포넌트에 bar들을 디자인하기 위해 className을 붙여준다.
- Char-bar__label에는 <Chart>컴포넌트에서 props로 <ChartBar>컴포넌트에 전달하는 label 을 받아와서 출력해 줄 것이다.
- chart-bar__fill <div>에는 bar가 사용량에 따라서 채워지는 디자인을 하기 위해서 만든 부분이다. <Chart>컴포넌트에서 <ChartBar>에 value값으로 넣어준 부분이 maxValue와 연관되어서 사용량이 나타나게 될 것이다. maxValue가 100이고 그냥 value가 50이라면 50%만큼 채웠다고 표시해주는 것이다.
- 채워지는 부분을 표시하기 위해 변수 barFillHeight를 만들어 초기값을 0%로 설정해주고 조건문을 달아 값을 설정해주자.
- Math.round는 소수점은 버리고 가장 가까운 정수를 반환해준다.
- 다음으로 char-bar__fill에 대한 CSS 스타일로 높이를 설정해줘야 한다. 우리는 요소의 스타일을 동적으로 설정할 것이다. 그래서 <div>부분에 style 속성을 바로 추가해준다.
- 리액트에서 style을 넣을때는 html과 조금 다르게 작동한다. 이 안에 설정되는 값은 동적이어야 한다. 높이를 채우는 값을 가지고 와야되기 때문이다.
- style을 쓸때는 중괄호 {} 를 두개씩 겹쳐준다. 밖에 있는건 JSX 문법용이고 안에있는건 자바스크립트 객체 용이다. {{}} 자바스크립트 객체를 value로 사용하고 key이름은 css프로퍼티 이름을 사용해야 하고 value는 그대로 value를 사용하면 된다.
- 여기의 경우는 height: barFillHeight로 설정해서 바로 스타일을 적용할수도 있다.
- 아니면 직접적으로 css를 적용시켜도 된다. backgroundColor 카멜케이스 혹은 'background-color'처럼 하이픈(-)과 ''따옴표를 같이쓰면 된다.
#마무리 및 다음단계
- ExpenseChart 컴포넌트를 하나 만든다.
- 아까 Chart 컴포넌트에서 우리가 만들었던 dataPoints를 정의해줘야 한다.
- ExpenseChart에서 datapoint가 필요하기때문에 ExpenseChart에서 설정해준다.
- dataPoints를 다루기 위해서 chartDataPoints라는 변수를 만들어주는데, 이 변수는 배열이고 안에 객체를 여러개 가지게 될 것이다. Chart에서 map으로 datapoints를 돌릴때 lable과 value를 가지고 있따. 우리가 만드는 객체들은 label과 value값을 가진다.
- 달별로 값을 넣어준다. 일단 value 값은 0으로 지정해둔다. 나중에 필터링 된 비용을 가지고 와서 선택한 연도에 대해 모든 비용을 검토한 다음 각 달의 비용을 합산하도록 만들어준다.
- 사용된 값에따라 value가 정해지게 하기 위해서 filtered expense를 props로 가져온다. filteredExpenses는 현재 <Expense>컴포넌트에 있다.
- for문을 사용해서 props에서 얻는 모든 비용을 반복 실행 해준다. 모든 비용을 살펴보고 해당 비용의 달을 가져와서 비용금액에 따라 적절한 dataPoints의 값을 업데이트 한다.
- 반복문 안에서 expenseMonth를 얻을 수 있다.
- date.getMonth 메소드는 원래 1월이 0부터 시작한다. 어차피 0부터 시작하니까 chartDatePoints 배열의 인덱스처럼 사용이 가능하다. chartDatePoints[expenseMonth]로 인덱스를 0 으로 쳐준다
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getMonth
- 그리고 expense.amount를 사용해 특정 달의 값을 증가시켜준다. 그런 다음 모든 비용을 검토해서 각 달의 모든 비용을 합산한다.
- 이 for문이 끝나고 나면 chartDataPoints의 배열에서 value값은 더이상 0이 아니게 될 것이다. 이제 <Chart>컴포넌트에 datapoints props를 설정해준다.
- 이제 다시 <Chart>컴포넌트로 돌아가 maxValue의 값을 수정해줘야 한다. 일단 전체 달을 다 살펴보고 그 중에 가장 비용이 큰 달을 찾아줘야한다. 그래야 원하는대로 %로 값을 넣어줄수 있기 때문.
- <Chart>컴포넌트 안에 totalMaximum이라는 변수를 하나 만들고 Math.max를 넣어준다. 우리는 이걸 통해서 최대 값을 뽑아 낼 것이다. 하지만 얘는 인자로 숫자들이 들어가줘야한다.
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max
- 숫자만 받기때문에 또 다른 배열을 하나 만들어줘서 넣어주면 된다.
- dataPoints 객체를 숫자로 변환해주는 코드인 것이다. 숫자는 datapoint.value에 저장된다.
- 이제 이렇게 만든 dataPointValues를 totalMaximum변수에 넣어준다.
- dataPointValues는 아직 배열이기 때문에 그 값을 다 가져오기 위해서 스프레드 연산자를 사용해서 배열의 모든 요소를 가져온다.
- <Expenses>컴포넌트에 <ExpenseChart>컴포넌트를 전달해준다. 여기에서 props를 전달해주는 것도 잊지말자!