๐ Deploy Link
๐ Server Link
๋งค๋์ ์ ๋ฐ ๊ณผ์ ๋ก ๊ทธ๋ํ๋ฅผ ์ด์ฉํ ๋ง์ผํ ๋ฐ์ดํฐ ์๊ฐํ ํ๋ก์ ํธ์ ๋๋ค.
- ์ ์ ๋ Figma ๋์์ธ๊ณผ ์ฝ๋ฉํธ์ ๋ฐ๋ฅธ ํ๋ฉด ๋ฐ ๊ธฐ๋ฅ ๊ตฌํ
- ์์์ ์ผ๋ก Fetch ํ์์ ๋ง๋ค์ด ๋ก๋ฉํ๋ฉด ์ง์
- ํ๋ฉด ์ด๋ ํ ๋ณต๊ท ์ ๋ง์ง๋ง ์ํ ์ ์ง
- ํ์ : ๋ฐ์์ฐฌ ์ ๊ฐ์ ์ด๋ค์ฌ ์ ์ ๋ฏธ ํ์ ์
- ๊ธฐ๊ฐ : 2022 / 05 / 22 ~ 2022 / 05 / 26
- react , typescript, scss
- react-query
- recoil (์ ์ญ ์ํ ๊ด๋ฆฌ)
- victory
- react-datepicker
- react-loading
- dayjs
-
repository clone
git clone https://github.com/wanted-pre-onboarding-FE-01/dashboard-app-1A.git
-
ํด๋น ํ๋ก์ ํธ ํด๋๋ก ์ด๋
cd dashboard-app-1A
-
ํ์ package๋ค ์ค์น
npm intall or yarn install
-
ํ๋ก์ ํธ ์คํ
npm start
- ๊ตฌํ์ฌํญ
- react-datepicker ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํ์ฉํ์ฌ ์ปค์คํ
- customHeader๋ฅผ ์ถ๊ฐํ์ฌ ํ์ฌ ์ ํํ(์์~๋) ๋ ์ง ํ์
- ์ ํํ ๋ ์ง ์ ์ฉ ์ recoil ์ ์ญ ์ํ๋ก ์ ์ฅ
2.1. ๊ด๊ณ ํํฉ
- ๊ตฌํ์ฌํญ
- ์ ํ๋ ๋ ์ง์ ํตํฉ ์ํ๋ฅผ ์ ๊ณต
- ์ ํ๋ ๋ ์ง์ ๋ฐ์ดํฐ์ ์ด์ ๋ ์ง์ ๋ฐ์ดํฐ๋ฅผ ํตํด ๋
ธ์ถ ๋ฐ์ดํฐ ๊ณ์ฐ
- ๋น๊ต๋ฅผ ํตํด ์ฆ๊ฐ์ฌ๋ถ๋ฅผ ํํ
- ๊ฐ์ ๋จ์์ ๋ฐ๋ฅธ Unit ๋ณํ
- ์๋ก ๋ฉ์ธ ๊ฐ์ด โ์ต'๋จ์ ์ผ ๋, ์ฆ๊ฐ ์ฌ๋ถ์ ๊ฐ ๋จ์๊ฐ โ๋ง'์ธ ๊ฒฝ์ฐ 0.1์ต ์ด๋ฐ ์์ผ๋ก ์นํ
- ์ด๋ ค์ ๋ ์
- ๊ฐ์ ๋จ์๋ฅผ ํต์ผ์ํค๊ธฐ ์ํ ์ ํธ ์์ฑ์ ์ํด ๊ณตํต์ ์ผ์ด์ค๋ฅผ ์ฐพ๊ธฐ๊ฐ ์ด๋ ค์ ์
- ์ ํ๋ ๋ ์ง์ ๋ฐ์ดํฐ๋ฅผ ๊ณ์ฐํ๋ ๋ถ๋ถ์ด ๋น๊ต์ ๊น๊ธํ์ง ๋ชปํจ
2.2. ํตํฉ ๊ด๊ณ ํํฉ ๊ทธ๋ํ
- ๋๋กญ ๋ค์ด
์ฃผ๊ฐ/์ผ๋ณ ๋ก ์ ํ๊ฐ๋ฅ
-
์ฃผ๊ฐ
-
์ ํ ๊ฐ๋ฅํ ๊ฒฝ์ฐ
7์ผ ์ดํ์ ๊ธฐ๊ฐ ์ ํ ์, ๊ธฐ๊ฐ์ ์ ํํ๋ ๋๋กญ๋ค์ด์ ๋นํ์ฑํ ์์ผ ์ฃผ๊ฐ ์ ํ ๋ถ๊ฐ
-
๊ตฌํ ๋ฐฉ๋ฒ
๋์ผ ์ฃผ์ฐจ์ ํ๊ท ์ ๊ตฌํ์ฌ ์ฃผ์ฐจ ๋ณ๋ก ๋ฐํ
-
์ ํํ ๋ ์ง๋ค์ด ํด๋นํ๋ ์์ ์ฃผ์ฐจ(n์ n์ฃผ)๋ฅผ ๊ตฌํจ
-
๋์ผํ ์ฃผ์ ํด๋นํ๋ ๋ ์ง๋ค์ ๊ฐฏ์๋ฅผ ๊ตฌํ๊ณ ๋ฐ์ดํฐ๋ ๋ชจ๋ ๋ํ ํ
ํด๋น ์ฃผ์ฐจ์ ๋ฐ์ดํฐ ์ดํฉ/ํด๋น ์ฃผ์ฐจ์ ๋ ์ง ์ด ๊ฐฏ์
๋ฅผ ๋ฐํํ์ฌ ์ฃผ์ฐจ๋ณ ํ๊ท ์ ๋ฐํ
-
-
-
์ผ๋ณ
์ ํํ ๊ธฐ๊ฐ์ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ์ผ๋ณ๋ก ๋ณด์ฌ์ฃผ๋ x์ถ์ ๊ธฐ๋ณธ์ ์ผ๋ก
tickCount
๊ฐ 7๋ก ์ค์ ๋์ด ์ค์ ์ฌ์ดํธ์ ๋์ผํ x์ถ์ ๊ฐฏ์ ์ถํ
์ ํ ์ ๋ฐํํ ๋ฐ์ดํฐ ๊ณ์ฐ
3๊ฐ์ง์ ๋๋กญ๋ค์ด์์ ์ต์ ์ ์ ํํ๋ฉด ํด๋น ์ต์ ์ ๋ํ์ฌ ๊ทธ๋ํ์ ๊ทธ๋ ค์ค ๋ฐ์ดํฐ ๊ฐ๊ณต
๋จ์ ๊ฐ (%, ์, ํ), ๊ทธ๋ํ์ ๋ณด์ฌ์ค ๋ฐ์ดํฐ ๋ฐฐ์ด, y์ถ ๊ฐ (y๊ฐ ์ค์ ์ต๋๊ฐ) ๋ฑ
const formatReturnData = (unitVal: string, integratedAdInfo: IDay[], btn: Btn, periodOption: PeriodOptions) => {
const formatedData =
periodOption === '์ผ๊ฐ' ? convertDailyData(integratedAdInfo, btn) : convertWeeklyData(integratedAdInfo, btn);
return {
unit: unitVal,
formatedData,
maxValue: formatedData && Math.max(...formatedData.map((obj: IFormatedData) => obj.y)),
};
};
export const convertData = (integratedAdInfo: IDay[], btnOption: PrimaryOptions, periodOption: PeriodOptions) => {
if (btnOption === 'ROAS') return formatReturnData('%', integratedAdInfo, 'roas', periodOption);
if (btnOption === '๊ด๊ณ ๋น') return formatReturnData('์', integratedAdInfo, 'cost', periodOption);
if (btnOption === 'ํด๋ฆญ ์') return formatReturnData('ํ', integratedAdInfo, 'click', periodOption);
if (btnOption === '๋
ธ์ถ ์') return formatReturnData('ํ', integratedAdInfo, 'imp', periodOption);
if (btnOption === '๋งค์ถ') return formatReturnData('์', integratedAdInfo, 'convValue', periodOption);
if (btnOption === '์ ํ ์') return formatReturnData('ํ', integratedAdInfo, ['cvr', 'click'], periodOption);
return undefined;
};
์ฒซ ๋ฒ์งธ ๋๋กญ๋ค์ด์์ ์ ํํ ์งํ๋ฅผ ๋๋ฒ์งธ ๋๋กญ๋ค์ด(์ต์ ๋)์์ ์ ํ ๋ถ๊ฐ
filter
๋ฅผ ํ์ฉํด์ ์ ์
2๊ฐ์ง ๋๋กญ๋ค์ด์ด ๋ชจ๋ ์ ํ๋ ๊ฒฝ์ฐ, ๊ทธ๋ํ ์ฐ์ธก์ y2 ๋๊ธ์ ์ ๊ณต
y2์ถ์ ํ ๋นํ VictoryAxis
์ VictoryLine
๋ฅผ key๋ก ์ฐ๊ฒฐํ์ฌ ์ถํ์ํด
- ๊ทธ๋ํ
์ซ์ ๋จ์ ๋ณํ
-
๊ฐ์ด 1๋ง ์ดํ์ผ ๊ฒฝ์ฐ
๋ฐ์ฌ๋ฆผ์ผ๋ก ์์์ ์ ๊ฑฐ ํ, ์ฒ ๋จ์๋ง๋ค ์ฝค๋ง(
,
) ํ์ฑ -
๊ฐ์ด 1๋ง~1์กฐ ์ผ ๊ฒฝ์ฐ
ํ๊ธ ๋จ์๋ก ๋ณํ (ex. 5๋ฐฑ๋ง์)
export const convertNumToUnit = (num: number) => {
if (num < 10000) {
return Math.round(num)
.toString()
.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
const transUnit = [
{ value: 1e12, symbol: '์กฐ' },
{ value: 1e11, symbol: '์ฒ์ต' },
{ value: 1e10, symbol: '๋ฐฑ์ต' },
{ value: 1e9, symbol: '์ญ์ต' },
{ value: 1e8, symbol: '์ต' },
{ value: 1e7, symbol: '์ฒ๋ง' },
{ value: 1e6, symbol: '๋ฐฑ๋ง' },
{ value: 1e5, symbol: '์ญ๋ง' },
{ value: 1e4, symbol: '๋ง' },
{ value: 1e3, symbol: '์ฒ' },
];
let i;
for (i = 0; i < transUnit.length; i += 1) {
if (num >= transUnit[i].value) {
return (num / transUnit[i].value).toFixed(1).replace(/\.?0+$/, '') + transUnit[i].symbol;
}
}
return num;
};
ํดํ ์ ๊ณต
๊ทธ๋ํ์ ์ ์ hoverํ๋ฉด ํดํ ํ์ธ ๊ฐ๋ฅ
3.1. ๋งค์ฒด ํํฉ ๊ทธ๋ํ
2022-05-25.11.28.19.mov
-
๊ตฌํ ์ฌํญ
service/fetchMediaChannelData
: ์ ํ๋ ๋ ์ง์ ํด๋นํ๋ ๋ฐ์ดํฐ api ํธ์ถutil/formatMediaChannelGraph
: ๋ฐํ๋ ๋ฐ์ดํฐ๋ฅผ ๊ทธ๋ํ ํ์์ ๋ง๊ฒ ๊ณ์ฐํ์ฌ ๋ฐํ- ์์์ 3์๋ฆฌ๋ฒ๋ฆผ
- ๊ฐ ํญ๋ชฉ ๋ณ ๊ฐ tooltip์ ํ์
- ๊ทธ๋ํ ๋ ๋๋ง ์ ์ ๋๋ฉ์ด์
-
์ด๋ ค์ ๋ ์
- y์ถ ํญ๋ชฉ๋ค์ ๋์ ๊ฐ์ ๊ตฌํ ํ ์ ์ฒด ๋ฐ์ดํฐ์ ํด๋นํ๋ ๋น์จ์ ๊ณ์ฐํ๋ ๊ฒ,
- ํดํ์๋ ๋น์จ์ด ์๋ ์ค์ ๋ฐ์ดํฐ ๊ฐ์ ๋ฃ๋ ๊ฒ์ด ๋ณต์กํ๋ค.
3.2. ๋งค์ฒด ํํฉ ํ ์ด๋ธ ์ฐจํธ
- ๊ตฌํ ์ฌํญ
util/formatMediaChannelTableData
๋ก๋ถํฐ ์ ๋ฌ๋ฐ์ ๋ฐ์ดํฐ๋ฅผ ๋ ๋๋ง- ๋ชจ๋ํฐ ํฌ๊ธฐ์ ๋ฐ๋ฅธ ํก์คํฌ๋กค ์ฝ์
2022-05-26.11.36.23.mov
- ๊ตฌํ ์ฌํญ
- react-query๋ฅผ ์ด์ฉํด ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์จ ํ, ํด๋น ๋ฐ์ดํฐ ๋ ๋๋ง.
- ๋ฐ์ ์จ ๋ฐ์ดํฐ๋ฅผ ๋๋กญ๋ค์ด์ ํด๋ฆญํ item ๊ฐ์ ๋ง๊ฒ ํํฐ๋ง.