직접 만든 물리엔진으로 데이터 시각화 하기 - boostcampwm-2022/web17-waglewagle GitHub Wiki

데이터 시각화 (1)

⚠️ 핵심기능이 외부라이브러리에 의존해도 될까?

  • 데이터 시각화를 위한 라이브러리를 찾던 중, React의 렌더링 방식에 어울리는 방식으로 동작하는 2차원 원형 배치 라이브러리를 찾기가 어려웠습니다.
  • 필요한 동작에 비해 라이브러리가 무겁거나, 렌더링까지 라이브러리에서 맡고 있어서 UI 로직과의 분리가 어려웠습니다.

⚪ 버블차트로 데이터 시각화

  • 처음에는 워드 클라우드를 직접 구현하려고 했었습니다. 문제는 워드 클라우드를 사용할 경우, 유저가 입력한 키워드의 길이에 따라서, 초기 워드 클라우드 모양에 대한 예외처리가 필요하다는 부분이 있었습니다.
  • 또한 워드 클라우드가 충분히 인터랙티브하게 느껴지지 않는다는 단점이 있었습니다.
  • 따라서 버블차트를 통해서 구현하는 것으로 이야기가 나뉘어졌습니다.

🤔 물리엔진으로 직접 만듭시다.

  • 처음에는 버블차트를 2차원 원형 적재 알고리즘을 사용하여 구현하려고 했습니다.
  • 이후 2차원 원형 적재 알고리즘은 인터랙티브한 데이터 시각화가 어렵고 유저 입장에서 지루할 수 있겠다는 생각이 들었습니다.
  • 물리엔진을 통해서 2차원 원형 배치를 구현한다면 문제를 해결할 수 있다는 아이디어를 가지고 중력과 마찰력 충돌력을 중심으로 저희 프로젝트에 알맞은 2차원 원형 배치 물리엔진을 구현하였습니다.

⚛️ 물리엔진 만들기

  • 만들 예정인 버블 차트의 UI를 리액트 컴포넌트로 먼저 만들었습니다. radius, X 좌표, Y 좌표를 상태로 두어서 위치와 크기를 동적으로 변경할 수 있도록 하였습니다.
  • 2차원 원형 배치를 위한 중력과 마찰력, 충돌력을 모델링하고 물리엔진을 구현하였습니다.
  • 중력은 중심점으로 위치를 이동시키려는 힘, 마찰력은 현재의 속력을 잃게 만드는 힘, 충돌력은 겹침이 발생했을 때 겹침을 해소하는 힘이라고 정의하고 물리엔진을 구현하였습니다.
  • 앞서 만든 컴포넌트들을 이 물리엔진으로 연산하여 위치를 정해주었습니다.
  • 이후 setInterval과 transform : translate()로 조정하여 애니메이션 최적화를 할 수 있었습니다.

🧑‍🔬 결과

  • 위치 연산 로직과 UI 렌더링 로직을 완전히 분리, 리액트의 렌더링 방식과 DOM 객체의 정보를 모두 활용할 수 있어서 인터랙티브한 버블 차트를 만들 수 있었습니다.
  • UI 로직을 분리한 덕분에, 같은 동작에서 버블 150개에서 **CPU 사용량이 90%**로 측정되었던 렌더링 과정을 **CPU 사용량 12%**로 최적화할 수 있었습니다.