요즘은 다양한 차트 라이브러리들이 정말 많은 기능들을 제공해줘서 편리하게 사용할 수 있었습니다. 리액트와 D3를 이용하여 그래프를 생성할 때는 특별한 차이가 있습니다.
D3는 DOM을 직접 제어하고 React는 Virtual DOM으로 제어하기 때문에 리액트를 이용하여 D3를 사용하게 될 경우 사람마다 사용방법이 많이 갈린다고 합니다.
여기서 가장 일반적으로 사용되는 방법은 DOM은 React에게, 계산은 D3에게하게 두는 것입니다. SVG path 계산, scale, layouts, transformations 등의 선/도형등의 모양을 계산하는 것만 D3가 하게하고 나머지는 React에게 맡기게 되면 다음과 같은 장점을 얻게됩니다.
장점
- 가장 React-지향적
- 이미 있는 다른 React 코드와도 가장 잘 어울림 (React 개발자들이 제일 좋아하는 방법)
- SSR 가능, React Native 혹은 React VR로 넘길 수 도 있음
본격적으로 리액트와 D3를 사용하여 간단하게 코드를 짜보도록 하겠습니다.
# Contents
- line Graph
- line Curve
# line Graph
먼저 라이브러리를 설치하고, 사용법을 알아보도록 하겠습니다.
라이브러리를 아래 명령어를 통해 설치합니다.
npm install --save d3
먼저 예제코드를 보도록 하겠습니다.
import { select, line } from "d3";
import React, { useEffect, useRef, useState } from "react";
export default function MyLineGraph() {
const [data, setData] = useState([10, 20, 40, 30]);
const svgRef = useRef(null);
useEffect(() => {
const svg = select(svgRef.current);
const myLine = line()
.x((value, index) => index * 50)
.y((value) => 200 - value);
svg.selectAll("path")
.data([data])
.join((enter) => enter.append("path"))
.attr("d", (value) => myLine(value))
.attr("fill", "none")
.attr("stroke", "red");
}, [data]);
return (
<>
<svg ref={svgRef} xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 200 200" version="1.1"></svg>
</>
);
}
select 객체를 생성하여 Ref.current에 담은 svg 변수를 만들고, line 함수를 만들어 svg변수 안에 line 함수와 데이터, enter를 path로 등록하여 결과를 뿌려주었습니다. path의 속성과 예제는 아래와 같습니다.
PATH 의 속성은 다음과 같습니다.
- MoveTo: M, m
- LineTo: L, l, H, h, V, v
- Cubic Bézier Curve: C, c, S, s
- Quadratic Bézier Curve: Q, q, T, t
- Elliptical Arc Curve: A, a
- ClosePath: Z, z
Move
M : 현재 점을 좌표 x, y로 이동합니다.
m : 경로의 마지막 알려진 위치를 x축을 따라 dx만큼 이동하고 y축을 따라 dy만큼 이동하여 현재 점을 이동합니다.
Line : line, horizontal, vertical
L : 현재 점에서 x,y로 지정된 끝점까지 선을 그립니다.
l : 현재 지점에서 끝 지점까지 선을 그립니다.
H : 현재 지점에서 끝 지점까지 수평선을 그립니다.
h : 현재 지점에서 끝 지점까지 수평선을 그립니다.
V : 현재 지점에서 끝 지점까지 수직선을 그립니다.
v : 현재 지점에서 끝 지점까지 수직선을 그립니다.
좀 예시를 들어서 구체적으로 확인해봅시다.
<path d="M 10,10 l 80,80 v -80 h -40" stroke="blue" fill="none"></path>
10, 10 까지 이동(시작)
현재 좌표에서 80, 80만큼 이동 (웹 상에서는 반전되어 보인다)
현재 좌표에서 수직 -80만큼 이동
현재 좌표에서 수평 -40만큼 이동
# line Curve
라인을 그린 함수에 Curve 메소드와 CurveBasis를 임포트하여 넣어주면 간단하게 이용할 수 있습니다.
import { select, line, curveBasis } from "d3";
import React, { useEffect, useRef, useState } from "react";
export default function MyLineGraph() {
const [data, setData] = useState([10, 20, 40, 30]);
const svgRef = useRef(null);
useEffect(() => {
const svg = select(svgRef.current);
const myLine = line()
.x((value, index) => index * 50)
.y((value) => 200 - value)
.curve(curveBasis);
svg.selectAll("path")
.data([data])
.join((enter) => enter.append("path"))
.attr("d", (value) => myLine(value))
.attr("fill", "none")
.attr("stroke", "red");
}, [data]);
return (
<>
<svg ref={svgRef} xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 200 200" version="1.1"></svg>
</>
);
}
'오픈소스 > 노드' 카테고리의 다른 글
[Node] React 정리(27) - 슬라이더 라이브러리 - react-slick (0) | 2021.11.10 |
---|---|
[Node] React 정리(26) - Redirect (0) | 2021.11.03 |
[Node] React 정리(25) - redux-persist (0) | 2021.11.03 |
[Node] React 정리(24) - 리액트 라우터 (0) | 2021.10.27 |
[Node] React 정리(23) - 리덕스 미들웨어 [redux-thunk, redux-sega] (0) | 2021.10.27 |