ํฐ์คํ ๋ฆฌ ๋ทฐ
[TIL] 2022/01/13 Thu - react ์ฐจํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ recharts ์ฌ์ฉํด๋ณด๊ธฐ
zubetcha 2022. 1. 13. 23:00
Today I Learned
๐ ์ฐจํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฌ์ฉํด๋ณด๊ธฐ
์ง๋ ์ฃผ์ ์์๋ ํ๋ก์ ํธ ์ค๊ฐ๋ฐํ ํ ๊ธฐ๋ฅ์ ์ถ๊ฐํ๊ฒ ๋์๋๋ฐ,
๊ธฐ์กด์ ์์๋ ๋ฐ ์ฌ์ ํ์ด์ง๋ฅผ ๊ฐํํ๋ ์ชฝ์ผ๋ก ๊ฒฐ์ ์ด ๋ผ์ ๋ด๊ฐ ์์น ๊ด๋ จ ํญ ํ๋ฉด์ ๋ด๋นํ๊ฒ ๋์๋ค.
์ฌ์ค ์ฐจํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฌ์ฉํด๋ณด๊ณ ์ถ์ด์ ๋ด๊ฐ ํ๊ณ ์ถ๋ค๊ณ ๋จผ์ ์๊ธฐํ๋ค. ใ ใ
๋ฆฌ์กํธ์์ ์ฌ์ฉํ ์ ์๋ ์ฐจํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์์๋ณด๋ ์ค nivo๋ฅผ ์๊ฒ ๋์๋๋ฐ
์ฒ์์๋ nivo๊ฐ ์ปค์คํ ์ ๋ํ์์ด๋ผ๋ ํ๊ธฐ๊ฐ ๋ง์ด ๋ณด์ฌ์ ์ฌ์ฉํด๋ณด๋ ค ํ๋ค.
๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ค์นํ๊ณ ์ ์ฉํด๋ณด๋๋ฐ,
์คํ๋ ค ์ปค์คํ ํ ์ ์๋ ๋ฒ์๊ฐ ๋๋ฌด ๋ฐฉ๋ํ๋ค๋ณด๋ ์ด์ฌ์์ ์ ์ฅ์์๋ ์ด ์ฅ์ ์ ์ ํ์ฉํ๊ธฐ ์ด๋ ค์ ๋ค.
ํ๋๋ถํฐ ์ด๊น์ง ๋ชจ๋ ์ปค์คํ ํ๋ ค๋ฉด ๊ทธ ํ๋๋ถํฐ ์ด๊น์ง์ ์์ฑ๋ค์ ์ ์๊ณ ์์ด์ผ ํ๋๋ฐ
๋์๊ฒ๋ ์์ง ์ต์ํ์ง ์์ ์์ฑ๋ค์ด ๋ง์์ ๋ฌด์์, ์ผ๋ง๋ ์ปค์คํ ํ๋ฉด ์ข์์ง ์ฝ์ฌ๋ฆฌ ์ ํ๊ธฐ ์ด๋ ค์ ๋ค.
๊ทธ๋์ UI๊ฐ ๊น๋ํ๋ฉด์๋ ์ฌ์ฉ๋ฒ์ด ๊ฐ๋จํ๊ณ , ์ ๋นํ ์ปค์คํ ํ ์ ์๋ ๋ค๋ฅธ ์ฐจํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฐพ๋ ์ค
recharts๋ฅผ ๋ฐ๊ฒฌํ๊ณ ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก ๋ณ๊ฒฝํ๊ธฐ๋ก ํ๋ค.
์๋ฐ์คํฌ๋ฆฝํธ์์๋ chart.js๊ฐ ์ ๋ช ํ๊ธด ํ์ง๋ง ๋ฆฌ์กํธ์์๋ react-chartjs๊ฐ ๋ฐ๋ก ์์ด์
npm ํธ๋ ๋์์ react-chartjs์ recharts๋ฅผ ๋น๊ตํด๋ณด์๋ค.
recharts ๋ฅผ ์ฌ์ฉํ๊ธฐ๋ก ๊ฒฐ์ ํ ์ด์ ๋,
1) ์ฐ์ Stars ์๊ฐ ๊ฐ์ฅ ๋ง์์ ๋ ํผ๋ฐ์ค๋ฅผ ์ฐพ๊ธฐ ์ฌ์ธ ๊ฒ ๊ฐ์๊ณ ,
2) ์ ๋ฐ์ดํธ ์ผ์๊ฐ ๊ฐ์ฅ ์ต๊ทผ์ด๋ฉฐ,
3) ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์๊ธด ์๊ธฐ๋ ๋น์ทํ์ง๋ง ์ด์ ์๊ฐ ๋ง์ ์ ์ด ๋ง์์ ๋ค์๋ค!
๊ทธ๋ฆฌ๊ณ ๋ฌด์๋ณด๋ค ๊ณต์ ๋ฌธ์์ Examples๋ API ์ ๋ฆฌ๊ฐ ๊ต์ฅํ ์ ๋์ด ์์ด์
์ด์ฌ์๊ฐ ์ปค์คํ ํ๊ธฐ์๋ ํฐ ์ด๋ ค์์ด ์์ ๊ฒ ๊ฐ์๊ณ ์ค์ ๋ก๋ ๊ทธ๋ฌ๋ค.
๋๋ ์ต๋ํ ์ฌํํ๊ฒ ๋ง๋ค๊ณ ์ถ์ด์ ์์ฑ๋ค์ ๋ง์ด ๋์ด๋ด๊ณ ์ฌ์ฉํ๋ค.
๋ผ์ธ ์ฐจํธ ์ปดํฌ๋ํธ
/* DictChart.js */
/* ์ฌ์ฉํ ์์ฑ๋ค์ import ํ๋ค. */
import { ResponsiveContainer, LineChart, Line, XAxis, CartesianGrid, Tooltip } from 'recharts'
const DictChart = ({ chartData }) => {
return (
<>
<ResponsiveContainer maxWidth={400} maxHeight={240}>
<LineChart
/* ์ฐจํธ๋ก ๊ทธ๋ฆด ๋ฐ์ดํฐ ์ฃผ์
*/
data={data}
margin={{
top: 10,
right: 0,
left: 0,
bottom: 0,
}}
>
<CartesianGrid stroke="#e5e5e5" strokeDasharray="3 3" />
<XAxis dataKey="name" fontSize="12px" fontWeight="500" padding={{ left: 10, right: 10 }} />
<Tooltip content={<CustomTooltip />} />
<Line type="linear" isAnimationActive={true} animationDuration={1500} dataKey="cnt" stroke="#6698FC" strokeWidth={2} activeDot={{ r: 8 }} />
</LineChart>
</ResponsiveContainer>
</>
)
}
export default DictChart
์ฐจํธ์ ์ฌ์ฉํ ๋ฐ์ดํฐ
/* ๋ผ์ธ ์ฐจํธ์ ์ฌ์ฉํ ๋ฐ์ดํฐ */
/* ์ถํ ์๋ฒ์์ ๋ฐ์์ค๋ ๋ฐ์ดํฐ๋ก ์์ ํ ์์ ! */
const data = [
{
name: 'ํ ',
cnt: 10,
},
{
name: '์ผ',
cnt: 19,
},
{
name: '์',
cnt: 10,
},
{
name: 'ํ',
cnt: 34,
},
{
name: '์',
cnt: 10,
},
{
name: '๋ชฉ',
cnt: 8,
},
{
name: '์ค๋',
cnt: 22,
},
]
ํดํ ์ปค์คํ ํ๊ธฐ
/* customedTooltip */
const CustomTooltip = ({ active, payload, label }) => {
if (active && payload && payload.length) {
return (
<Container>
<p className="label">{`${label} : ${payload[0].value}`}</p>
</Container>
)
}
return null
}
/* styled-components */
const Container = styled.div`
width: fit-content;
height: 36px;
padding: 8px;
background-color: #fff;
opacity: 0.85;
border: 1px solid ${({ theme }) => theme.colors.line};
border-radius: 5px;
display: flex;
align-items: center;
justify-content: center;
.label {
font-size: ${({ theme }) => theme.fontSizes.base};
}
`
Line์ ์ ์ฉํ ์์ฑ
type : ๋ผ์ธ ๋์์ธ, String / ์ง์ ์ "linear", ๊ณก์ ์ "monotones"
isAnimationAcitve : ์ ๋๋ฉ์ด์ ํ์ฑํ, Boolean / default false
animationDuration : ์ ๋๋ฉ์ด์ ์งํ ์๊ฐ, Number / ๋จ์๋ ๋ฐ๋ฆฌ์ธ์ปจ๋
stroke : ๋ผ์ธ ์ปฌ๋ฌ, String
strokeWidth : ๋ผ์ธ ๊ตต๊ธฐ, Number
activeDot : ๋ง์ฐ์ค ์ค๋ฒ ์ ํ๋ํ Dot ํฌ๊ธฐ
LineChart์๋ maxWidth, maxHeight ์์ฑ์ ์ฌ์ฉํ ์ ์๊ณ width, height ๋ % ๋จ์๋ก ์ฌ์ฉํ ์ ์๋ค.
๋ฌด์กฐ๊ฑด ๊ณ ์ ๋ pixel ๋จ์์ด๋ค.
์ฒ์์๋ ResponsiveContainer๋ฅผ ์ ๊ณตํ๋ ์ค ๋ชจ๋ฅด๊ณ ๋ฐ์ํ์ผ๋ก ์ด๋ป๊ฒ ๋ง๋ค์ง ๊ณ ๋ฏผํ๋๋ฐ
๊ตฌ๊ธ๋ง ํด๋ณด๋ ๋ฐ์ํ ์ปจํ ์ด๋๋ฅผ ๋ฐ๋ก ์ง์ํ๊ณ ์์ด์ import ํ
ResponsiveContainer ํ๊ทธ์ maxWidth์ maxHeight๋ฅผ ์ค์ ํ๋๋ ํ๋ฉด์ด ์ค์ด๋ค์์ ๋ ๊ฐ์ด ์ ์ค์ด๋ ๋ค!
๊ธฐ๋ณธ์ผ๋ก ์ ๊ณต๋๋ ํดํ๋ ๋ง์์ ์ ๋ค์๋๋ฐ
๊ณต์ ๋ฌธ์๋ฅผ ์ฐพ์๋ณด๋ ์ปค์คํ ํ๋ ๋ฐฉ๋ฒ์ ๋ํด์ ์ ๋์ ์์ด์ ์ฐพ์๋ณด๊ณ ์ ์ฉํ๋ค.
์ญ์ ๋ญ๊ฐ ์ ์ ๋ ๋๋ ๊ณต์ ๋ฌธ์๋ฅผ ์ฐพ์๋ณด๋ ๊ฒ ๋ต์ธ ๊ฒ ๊ฐ๋ค!