| 언어 | Java 17, JavaScript (ES6+) |
| 프레임워크 | Spring Boot 3.3.3, React 18.3.1 |
| DB | MySQL 8.x |
| 빌드 도구 | Gradle 7.x |
대리님 왈
"차트는 기본이에요"
라는 말을 듣고 국내에서 주로 사용한다는 차트를 몇개 조사해봤다.
Chart.js: 오래된 라이브러리로, 학습곡선이 낮고 React 프로젝트에서도 사용 가능.
Highcharts: 유료지만 고급 기능이 많아 데이터 시각화에 신경 쓰는 대기업 프로젝트에서 사용.
D3.js: 완전한 커스터마이징이 가능해 데이터를 복잡하게 시각화할 때 사용.
ECharts: 알리바바가 개발한 차트 라이브러리로, 데이터 분석 프로젝트에서 사용 증가.
내가 진행중인 프로젝트에서는 React 기반의 SI 프로젝트, 스타트업 대시보드 개발에 자주 사용된다는
Recharts를 사용했다.
React 전용 라이브러리 중 하나인 ' Recharts' 는 차트를 컴포넌트 단위로 구성하고 JSX 문법을 사용해 차트를 구성하므로 React 를 사용하는 나에게 매우 익숙했다. 그리고 무엇보다 무료로 사용이 가능하다는 점이 큰 장점이라고 생각한다.
<Recharts 공식 문서>
위 사이트에 들어가보면 매우 다양한 차트가 있고 우측에 기본 소스를 제공한다. 나는 SimpleBarChart를 사용했다.
<기초 사용법>
function SomeDashboardChartM({selfChart: {chartParam}}) {
const colorList = ["#색상1", "#색상2", "#색상3"];
const [dataList, setDataList] = useState([]);
useEffect(() => {
getChartDataList();
}, [chartParam]);
const convertChartParam = (standardDate) => {
const toDate = new Date(standardDate);
const fromDate = new Date(toDate);
fromDate.setDate(1);
const getLastDayOfMonth = (year, month) => new Date(year, month + 1, 0).getDate();
const LastDayOfPrevMonths = (date) => {
const currentYear = date.getFullYear();
const currentMonth = date.getMonth();
return {
lastDayOneMonthsAgo: getLastDayOfMonth(currentYear, currentMonth - 1),
lastDayTwoMonthsAgo: getLastDayOfMonth(currentYear, currentMonth - 2)
};
};
const adjustDate = (year, month, standardDay, lastDayOfMonth) => {
const adjustedDay = standardDay > lastDayOfMonth ? lastDayOfMonth : standardDay;
return new Date(year, month, adjustedDay);
};
const { lastDayOneMonthsAgo, lastDayTwoMonthsAgo } = LastDayOfPrevMonths(toDate);
const standardDay = toDate.getDate();
return {
fromDate3: setDate(new Date(toDate.getFullYear(), toDate.getMonth() - 2, 1), 'yyyy-mm-dd'),
toDate3: setDate(
adjustDate(
toDate.getFullYear()
,toDate.getMonth() - 2
,standardDay
,lastDayTwoMonthsAgo
)
,'yyyy-mm-dd'
),
fromDate2: setDate(new Date(toDate.getFullYear(), toDate.getMonth() - 1, 1), 'yyyy-mm-dd'),
toDate2: setDate(
adjustDate(
toDate.getFullYear()
,toDate.getMonth() - 1
,standardDay
,lastDayOneMonthsAgo
)
,'yyyy-mm-dd'
),
fromDate1: setDate(new Date(toDate.getFullYear(), toDate.getMonth(), 1), 'yyyy-mm-dd'),
toDate1: setDate(
toDate
,'yyyy-mm-dd'
),
};
};
const getChartDataList = async () => {
if (!isEmptyObj(chartParam)) {
const convertedParam = convertChartParam(chartParam.standardDate);
let result = await getAxios('/API호출url', convertedParam);
if (!result.success) {
return Alert(result.message);
}
setDataList([...result.items]);
}
}
...
위 소스는 내가 작성한 차트 컴포넌트의 날짜 파라미터 계산 로직의 일부다.
개략적인 설명을 하자면,
우선 요구사항은
기준일자의 달의 첫일부터의 기준일자까지의 데이터를 가져오고
동일한 일자의 전달, 전전달의 데이터를 가져와야 한다.
예를들어 기준일자를 8월 23일로 선택했다면 가져와야 하는 데이터는
8월 1일 ~ 8월 23일
7월 1일 ~ 7월 23일
6월 1일 ~ 6월 23일
이렇게 총 3개의 기간에서 상품별 데이터를 조회하여 하나의 차트에 쏴줘야 하는 것이다.
여기서 문제가 발생했다.
convertChartParam 함수는 기준일자를 요구사항에 맞춰 바꿔주는 함수이다. 그런데 예를들어 3월 31일이 기준일자라면 전달과 전전달의 31일을 가져와야 하는데 2월은 31일이 존재하지 않는다. JavaScript의 Date 객체는 초과된 값을 자동으로 조정해주기 때문에 2월 31일 대신 29 + 2 이니까 초과된 2일분이 다음달로 넘어가서 3월 2일까지의 데이터를 가져오게 된다.
이 문제점을 해결하기 위해 getLastDayOfMonth는 특정 월의 마지막 날짜를 계산한다. 다음 달의 첫째 날에서 하루를 빼는 방식으로 계산한다.
Date 객체가 초과된 값을 자동으로 조정해주는 특성을 역으로 이용하여 day = 1이면 1일 day = 2이면 2일을 의미 하기 때문에 day = 0으로 설정하면 -1일이 되어 전달의 마지막 날을 가져왔다. 그리고 2월은 28일, 윤년에는 29일로 해마다 다르기 때문에 year을 함께 받아서 연도도 고려하여 계산했다.
adjustDate는 기준일자가 해당 달의 마지막 날을 초과하는 경우 그 달의 마지막 일자를 기준일자 대신 사용하도록 하는 함수이다.
결과적으로
fromDate3~toDate3
fromDate2~toDate2
fromDate1~toDate1
이 기간을 파라미터로 서버에서 데이터를 불러온다.
P.S.
열심히 짰지만 결과적으로 이 소스는 사용되지 못했다.
해당 화면에서 필요한 차트는 연도별, 월별, 일별 이렇게 총 3개의 차트로 데이터를 가져올 필요가 있었는데
내 코드는 중복로직이 많아서 주요 함수는 공통모듈로 빼고 연도별, 월별, 일별에 맞게 데이터를 가져오도록 props를 받아 type: "dd"이면 일별 데이터를, type: "mm"이면 월별 데이터를, type: "yyyy"이면 연도별 데이터를 가져오도록 설정하고 차트 컴포넌트를 단 한개로 통일했다.
그래도 내 소스를 기반으로 공통모듈을 수정했으니 의미없는 작업은 아니었다고 생각한다.
'React' 카테고리의 다른 글
| [React] useReducer, memo, useMemo (0) | 2025.11.20 |
|---|---|
| [React] axios / fetch / Express의 app.get() 역할 구분 (0) | 2025.11.18 |
| React를 사용할 때 알면 좋은 훅 정리 (1) | 2025.09.01 |
| 리액트 - 데이터 의존성과 렌더링 타이밍을 고려한 비동기 함수의 호출 순서 (2) | 2024.12.13 |
| 리액트 - 그리드 라이브러리 기초사용법 예제 [@mui/x-data-grid-premium] (1) | 2024.12.12 |