d3.js 그래픽을 Facebook React 애플리케이션에 통합하기

d3.js 그래픽을 Facebook React 애플리케이션에 통합하는 올바른 방법이 있을까요? 네, react-art을 사용할 수 있지만 그것은 망가진 것 같습니다. 문제는 d3.js가 브라우저 DOM을 변경하는 것이 주 목적이므로, componentDidMount 메서드 내에서 직접 사용하는 것은 제대로 작동하지 않을 …

title_thumbnail(D3.js 그래픽을 React에 통합하기)

d3.js 그래픽을 Facebook React 애플리케이션에 통합하는 올바른 방법이 있을까요?

네, react-art을 사용할 수 있지만 그것은 망가진 것 같습니다. 문제는 d3.js가 브라우저 DOM을 변경하는 것이 주 목적이므로, componentDidMount 메서드 내에서 직접 사용하는 것은 제대로 작동하지 않을 수 있습니다. 왜냐하면 브라우저 DOM에 대한 변경은 React의 가상 DOM에 반영되지 않기 때문입니다. 아이디어가 있으신가요?

하나의 전용 컴포넌트를 빌드하여 React에서 업데이트하지 않게 하는 전략일 수 있습니다.

컴포넌트 라이프사이클 메서드인 shouldComponentUpdate()는 컴포넌트가 자체적으로 리렌더링이 필요한지를 결정할 수 있도록 하는 것을 목적으로 합니다. 항상 이 메서드에서 false를 반환하면, React는 자식 요소까지 들어가지 않습니다(물론 forceUpdate()를 호출하지 않는 한), 따라서 이는 React의 깊은 업데이트 시스템에 대한 일종의 방화벽 역할을 합니다.

shouldComponentUpdate() {
    return false;
}

첫 번째 렌더링 호출에서는 차트를 위한 컨테이너를 생성한 다음, componentDidMount() 메서드 내에서 D3로 차트 자체를 그립니다. 그런 다음, React 컴포넌트의 업데이트에 대응하여 차트를 업데이트하는 것만 남습니다.

render() {
    return <svg></svg>;
},

componentDidMount() {
    d3.select(this.getDOMNode())
      .call(chart(this.props));
},

shouldComponentUpdate(props) {
    d3.select(this.getDOMNode())
      .call(chart(props));
    return false;
}

참고로, 차트를 componentDidMount() 메서드에서도(첫 번째 렌더링용) 호출해야 하며, shouldComponentUpdate()에서도(이후 업데이트용) 호출해야 합니다. 또한 컴포넌트의 속성이나 상태를 차트로 전달할 방법이 필요한데, 이는 컨텍스트에 따라 다릅니다. 첫 번째 렌더링에서는 이미 이.props와 this.state에 설정되어 있지만, 이후의 업데이트에서는 새로운 속성이 아직 컴포넌트에 설정되지 않은 상태이므로 함수 매개변수를 사용해야 합니다.

componentDidMount() {
    d3.select(this.getDOMNode())
      .call(chart(this.props));
},

shouldComponentUpdate(props) {
    d3.select(this.getDOMNode())
      .call(chart(props));
    return false;
}

React는 SVG 요소를 직접 렌더링할 수도 있습니다. 다음은 예시입니다:

React와 D3 통합

// React 컴포넌트
import React from 'react';
import { select } from 'd3';

const MyComponent = () => {
  const svgRef = React.useRef();

  React.useEffect(() => {
    const svg = select(svgRef.current);
    // SVG 조작을 위한 D3 코드
  }, []);

  return <svg ref={svgRef} width={200} height={200}></svg>;
};

export default MyComponent;

D3를 유틸리티로 사용할 수도 있습니다. 즉, D3를 DOM 변경에 사용하지 않고, D3의 스케일과 축 기능을 활용하지만 D3 함수의 출력을 HTML/SVG 내에 보간합니다. 다음은 예시입니다:

// D3 코드
scale = d3.time.scale()
  .range([0, 100])
  .clamp(true);

// React 코드
<rect
  x="#{props.scale(start)}%"
  width="#{Math.abs(props.scale(end) - props.scale(start))}%"
/>

저는 useRef 훅을 사용하여 D3 시각화에 대한 참조를 저장하여 페이지에 다른 “내용”이 있을 때에만 차트를 업데이트할 수 있도록 조절합니다. D3에서는 이 튜토리얼에서 설명하는 재사용 가능한 차트 패턴을 사용합니다:

// React 코드
import React, { useEffect, useRef, useState } from 'react';
import { select } from 'd3';

const MyComponent = () => {
  const [data, setData] = useState(['red']);
  const refElement = useRef(null);
  const visFunction = useRef(null);

  const initVis = () => {
    visFunction.current = d3Chart().data(data);
    select(refElement.current).call(visFunction.current);
  };

  const updateVis = () => {
    visFunction.current.data(data);
  };

  useEffect(() => {
    if (data && data.length) {
      if (visFunction.current === null) {
        initVis();
      } else {
        updateVis();
      }
    }
  }, [data]);

  return (
    <>
      <div ref={refElement} className="d3Container"></div>
      <button onClick={() => setData(['blue'])}>Update</button>
    </>
  );
};

// D3 코드
const d3Chart = () => {
  // 차트 로직 작성
};

export default MyComponent;

이제 Facebook React 애플리케이션에 D3.js 그래픽을 통합하기 위한 다양한 전략을 가지고 있습니다. 필요에 맞는 방법을 선택하여 멋진 시각화를 만들기 시작하세요!

참고 자료 :

https://stackoverflow.com/questions/21903604/is-there-any-proper-way-to-integrate-d3-js-graphics-into-facebook-react-applicat

같은 카테고리의 다른 글 보기 :

reactjs

Leave a Comment