boostcampwm-2022 / Web35-CryptoGraph

실시간 암호화폐 데이터 시각화 웹 서비스
19 stars 4 forks source link

Issue#96/candle chart refactor #129

Closed kongyb closed 1 year ago

kongyb commented 1 year ago

개요

작업사항

생각해볼점

실시간 정보 UI의 렌더함수와 updateChart의 분리

data-join을 줄이기위해 상태 및 함수들을 분리하려는 노력을 했으나 실시간 가격정보를 나타내는 UI는 분리를 하지 못했습니다.
updateChart는 캔들차트에 나타나는 캔들유닛이 변경되야 할때 data-join을 이용하여 캔들유닛들을 렌더링하는데, 캔들차트에 나타나는 캔들유닛은 components/candlechart/index.tsx에서 선언되는 option상태에 의존하고 props로 전달받는 candleData에도 의존하고 있습니다.
option은 항상 캔들차트에 그려지는 캔들유닛에 영향을 끼치지만, candleData는 사실 캔들차트에 그려져야하는 캔들유닛의 시작인덱스가 0이 아니라면 영햘을 끼치진 않습니다.
분리해보려고 이리저리 생각해보았지만, 좋은 방법이 떠오르지 않았습니다.

소켓관련하여

실시간으로 정보를 전달받기 위해 소켓을 사용하고 있는데 우측의 실시간 가격정보 컴포넌트 때문에 모든 코인의 거래정보를 받아와야 합니다.
많은 양의 정보가 짧은 주기로 페이지에 들어오고 있고 제가 로컬에서 작업할 때는 소켓을 연결하는 것 과 연결하지 않는 것에서 은근히 렌더링 속도에 체감을 느낄 수 있었습니다.
소켓의 사용이 필수적이라면 소켓에서 들어오는 정보를 바로바로 반영하는 것이 아니라 어느정도 텀을두고 한번에 반영하여 렌더하는 것이 어떨까라는 생각을 했습니다.

마우스 이벤트

마우스 이벤트의 최적화를 위해 쓰로틀을 도입하는 것도 좋을 것 같습니다.
현재 마우스가 캔들차트를 벗어나면 캔들차트의 UI가 사라져야하는데 인식이 되지않는 문제가 있습니다.

이미지

Dec-10-2022 00-43-03

kongyb commented 1 year ago

기존 renderOption의 속성
candleWidth: 캔들차트에 그려지는 캔들유닛의 width
minCandleWidth, maxCandleWidth: candleWidth의 최솟값,최댓값 캔들차트가 그려지는 div의 너비에 영향을 받는다. (최솟값을 5로 설정)
renderStartDataIndex: 캔들차트에 제일 오른쪽에 그려지는 캔들유닛의 데이터인덱스 드래그이벤트에 영향을 받는다.
renderCandleCount: 캔들차트에 그려지는 캔들유닛의 갯수 휠이벤트와 캔들차트가 그려지는 div의 너비에 영향을 받는다.

휠이벤트와 드래그 이벤트는 이벤트 리스너에서 처리 화면크기가 변경될때 candleWidth를 고정시키고 renderCandleCount, minCandleWidth, maxCandleWidth를 조정하는 방향으로 변경
useEffect를 이용하여 화면크기가 변경될때 renderOption을 갱신한다. 화면크기가 변경되면 renderStartDataIndex, candleWidth는 고정하고 나머지 속성들은 width로 새로 계산하여 갱신

export function getRenderOptionByWindow(
  width: number,
  prev: CandleChartRenderOption
): CandleChartRenderOption {
  const renderCandleCount = Math.ceil(width / prev.candleWidth)
  const minCandleWidth = Math.max(5, Math.ceil(width / 200))
  const maxCandleWidth = Math.max(5, Math.ceil(width / 10))
  return {
    ...prev,
    renderCandleCount,
    minCandleWidth,
    maxCandleWidth
  }
}

기존의 초기상태의 renderOption을 반환하는 함수도 minCandleWidth, maxCandleWidth변경 초깃값을 설정하는 useState와 외부에서 전달되는 props (market혹은 period)가 변경될때 호출

export function getInitRenderOption(width: number) {
  const candleWidth = Math.ceil(width / DEFAULT_CANDLE_COUNT)
  return {
    candleWidth,
    minCandleWidth: Math.max(5, Math.ceil(width / 200)),
    maxCandleWidth: Math.max(5, Math.ceil(width / 10)),
    renderStartDataIndex: DEFAULT_RENDER_START_INDEX,
    renderCandleCount: DEFAULT_CANDLE_COUNT
  }
}

minCandleWidth와 maxCandleWidth 모두 화면크기를 반영할 수 있도록 조정, 최솟값은 5로 고정 차트크기의 너비가 50px이하일때는 휠이벤트에 반응하지 않는다.