라이브러리를 사용한 분들의 기록이 많이 없고, 각요소에 클래스명이 부여되지 않아서 커스텀하기가 까다로웠습니다.
시행착오를 겪고 있는 다른분들도 이 블로그를 보고 도움이 되었으면 좋겠습니다.
아래에 커스텀한 내용을 자세히 기록하였습니다.
// 그래프에 넣어줄 데이터 state값
const [tempData, setTempData] = useState([]);
const [humidityData, setHumidityData] = useState([]);
const [pressureData, setPressureData] = useState([]);
// 기온, 습도, 압력 그래프
// 원래는 데이터만 넘겨주면 되지만 커스텀하여 단위, 색, onClick 함수를 같이 넘겨줍니다.
<Graph data={tempData} unit={'Temperature (°C)'} color={'Lightcoral'} getTargetTime={getTargetTime} />
<Graph data={humidityData} unit={'Humidity (%)'} color={'Mediumaquamarine'} getTargetTime={getTargetTime} />
<Graph data={pressureData} unit={'Pressure (hPa)'} color={'Slateblue'} getTargetTime={getTargetTime} />
// 기존 라이브러리 코드
// 수정될 부분을 표시해두었습니다.
import { ResponsiveLine } from '@nivo/line'
const MyResponsiveLine = ({ data}) => (
<ResponsiveLine
// 여기에 colors, theme 속성이 추가됩니다.
data={data}
margin={{ top: 50, right: 110, bottom: 50, left: 60 }}
xScale={{ type: 'point' }}
yScale={{
type: 'linear',
min: 'auto',
max: 'auto',
stacked: true,
reverse: false
}}
// 여기에 curve 속성이 추가됩니다.
yFormat=" >-.2f"
axisTop={null}
axisRight={null}
axisBottom={{
orient: 'bottom',
tickSize: 5,
tickPadding: 5,
tickRotation: 0, // tickRotation 값이 바뀝니다.
legend: 'transportation', // legend 값이 바뀝니다.
legendOffset: 36,
legendPosition: 'middle'
}}
axisLeft={{
orient: 'left',
tickSize: 5,
tickPadding: 5,
tickRotation: 0,
legend: 'count', // legend 값이 바뀝니다.
legendOffset: -40,
legendPosition: 'middle'
}}
pointSize={10}
pointColor={{ theme: 'background' }}
pointBorderWidth={2}
pointBorderColor={{ from: 'serieColor' }}
pointLabelYOffset={-12}
useMesh={true}
legends={[ // legends 값이 바뀝니다.
{
anchor: 'bottom-right',
direction: 'column',
justify: false,
translateX: 100,
translateY: 0,
itemsSpacing: 0,
itemDirection: 'left-to-right',
itemWidth: 80,
itemHeight: 20,
itemOpacity: 0.75,
symbolSize: 12,
symbolShape: 'circle',
symbolBorderColor: 'rgba(0, 0, 0, .5)',
effects: [
{
on: 'hover',
style: {
itemBackground: 'rgba(0, 0, 0, .03)',
itemOpacity: 1
}
}
]
}
]}
// onClick 속성이 추가됩니다.
/>
)
// 커스텀한 코드
import styled from 'styled-components';
import { ResponsiveLine } from '@nivo/line';
const Graph = ({ data, unit, color, getTargetTime }) => {
return (
<GraphWrapper>
<ResponsiveLine
colors={color} // color를 props로 받아서 설정해줍니다.
theme={{ // theme에서 x, y축 글씨 색을 바꿔줍니다.
textColor: blue,
}}
data={data}
margin={{ top: 10, right: 10, bottom: 70, left: 70 }}
xScale={{ type: 'point' }}
yScale={{
type: 'linear',
min: 'auto',
max: 'auto',
stacked: true,
reverse: false,
}}
yFormat='>-.2f'
curve='catmullRom' // 선 종류를 설정해줍니다. (라이브러리 문서 참고)
axisTop={null}
axisRight={null}
axisBottom={{
orient: 'bottom',
tickSize: 5,
tickPadding: 5,
tickRotation: -90, // x축 텍스트를 회전시켜줍니다. (세로)
legend: 'Date', // x 축 단위를 표시합니다.
legendOffset: 60,
legendPosition: 'middle',
}}
axisLeft={{
orient: 'left',
tickSize: 5,
tickPadding: 5,
tickRotation: 0,
legend: unit, // y축 왼쪽에 표시될 단위입니다.
legendOffset: -55,
legendPosition: 'middle',
}}
pointSize={5}
pointColor={{ theme: 'background' }}
pointBorderWidth={2}
pointBorderColor={{ from: 'serieColor' }}
pointLabelYOffset={-12}
useMesh={true}
legends={[]} // 그래프 오른쪽의 포인트를 지워줍니다.
onClick={e => { // 클릭시 해당 x 값을 부모 컴포넌트에서 가져갑니다.
getTargetTime(e.data.x);
}}
/>
</GraphWrapper>
);
};
export default Graph;
// 그래프 라이브러리에 높이 값을 주지 않으면 그래프가 나타나지 않습니다.
// 높이값을 꼭 주세요!
const GraphWrapper = styled.div`
padding: 10px;
@media screen and (min-width: 1024px) {
height: 280px;
}
@media screen and (min-width: 768px) and (max-width: 1023px) {
height: 260px;
}
@media screen and (min-width: 480px) and (max-width: 767px) {
height: 240px;
}
@media screen and (max-width: 479px) {
height: 220px;
}
`;