[Recharts] bar 를 floating bar 로 만들어 진짜 주식 차트처럼 그리기

THOVY·2022년 11월 14일
1

PROJECT

목록 보기
5/20

시작 👊

주식 차트를 그리는데 "상한가"로만 표현된다.😟

내가 원하는 차트 그림은 이게 아니야.

내가 원하는 차트는 진짜 주식 차트 처럼

하한가 상한가를 가지고 막대의 길이를 조절하고 싶다.

내가 가져온 데이터(한국투자증권 주식 API)에 이렇게 모든 게 담겨 있기 때문에

주가 아래쪽 바닥에는 거래량까지 표현할 수 있다.
사실 거래량을 표시하는 것은 어렵지 않다.

거래량은 바닥부터 올라오면 되는 그냥 막대그래프 기 때문에 <Bar/> 를 하나 더 넣고 데이터를 넣어주면 된다.

결국 내가 원하는 건 🤔

  1. 하한가 상한가 를 이용해 막대를 공중에 띄우기 floating
  2. 전일 대비 부호 를 이용해 막대그래프 색깔 바꾸기
  3. 바닥에 거래량 막대 표시하기

🙂 만들어보자

🙋‍♂️ 1번부터 만들어볼까욤.

  1. dataKey 값에는
    String or Number 를 넣을 수 있다.
    하지만
    LineChart 에서는
    function 까지 가능하다.

  2. function 을 넣어보자.

<BarChart data={stockData} width={500} height={300}>
  <CartesianGrid strokeDasharray="3 3"/>
  <XAxis dataKey="stck_bsop_date"/>
  <YAxis />
  <Tooltip/>
  <Bar
  	dataKey={
    (data)=>{
      const range = [data.stck_hgpr, data.stck_lwpr]
      return range}}
    fill = "#E94560"
  />
</BarChart>

우리가 받아온 주가 data 인 stockData<BarChart data={stockData}> 로 들어가서
<Bar> 에 있는 dataKey 로 하나씩 뿌려진다.

  1. 그냥 String 으로 보내기 위해서는 dataKey="stck_hgpr" 이라고 쓰면된다. 그 안에 있는 값을 뿌려주는 거라고 생각됨.
    하지만 나는 범위로 그리고 싶었기 때문에 리스트형태로 보내줬어야한다.
    Barchart API Docs
    Barchart API Docs Exam

이것처럼 보내줘야하는데, 우리가 stockData 를 받아오면 바로 값이 정해지므로 화살표함수를 이용해봤지!

결과


따란~!
심심하지만 원하는 결과가 나왔다.

🙆‍♂️ 2번을 만들어볼까욤.

차트 기둥마다 색깔 바꾸기는 Custom 에서 힌트를 받을 수 있다.

이렇게 <Bar> 컴포넌트 안쪽에 <Cell> 컴포넌트를 하나 만들어서 거기서 path 를 사용하고 있다.

내가 처음에 생각했던

solution 1 ❌

<Bar> 컴포넌트의 속성값으로 fill 이 있으니 거기에 적어주면 되지 않을까 해서

<BarChart data={stockData} width={500} height={300}>
  <CartesianGrid strokeDasharray="3 3"/>
  <XAxis dataKey="stck_bsop_date"/>
  <YAxis />
  <Tooltip/>
  <Bar
  	dataKey={
    (data)=>{
      const range = [data.stck_hgpr, data.stck_lwpr]
      return range}}
    fill = {(stockData.prdy_vrss_sign > 3) ? "#006DEE" : "#E94560"}
  />
</BarChart>

이렇게 적었는데

그러면 그림이 그려지지 않는다.

solution 2 ❌

그래서 dataKey 처럼 함수를 넣어볼까.

<Bar
  ...
  
  fill={(e)=>{
    const a = e.stck_hgpr;
    return a
  }}
/>

하면

solution 3 ✅

그래서 살펴본 Docs 의 Custom 부분.

<Cell> 을 이용해보자!

<Bar
 ...
>
 	{stockData.map((data)=>(
      <Cell fill={(data.prdy_vrss_sign > 3) ? "#006DEE" : "#E94560"}/>
  	))}
</Bar>

따란!

쉽다 쉬워~ (색깔만 이틀잡아먹음)🤣

👨‍💻 3번을 만들어볼까욤.

새로 추가하려고 하는 Bar 컴포넌트와 거기에 데이터 를 추가해주자

👍 차트 조합
다양한 형태의 차트를 조합하고 싶다면 ComposedChart 를 사용해야한다
예를들면 하나는 Bar, 다른 하나는 Line chart 를 이용하려면 ComposedChart 를 이용하자!
그러지 않으면 해당 Chart 와 같은 것만 표시된다!
🎇즉, BarChart 내부에 Bar 와 Line 을 넣으면 Bar 만 표시되고 Line 은 표시되지 않는다.
하지만 ComposedChart 내부에 Bar 와 Line 을 넣으면 둘 다 표시된다!

나는 Bar 형태만 사용할 거기 때문에 BarChart 를 그대로 사용할 거다.

<BarChart>
  ...
  <Bar
    dataKey={
      (data)=>{
      const range = [data.stck_hgpr, data.stck_lwpr]
      return range}}
    fill= "#E94560"
  >
    {stockData.map((data)=>(
      <Cell fill={(data.prdy_vrss_sign > 3) ? "#006DEE" : "#E94560"}/>
    ))}
  </Bar>
  <Bar dataKey={(e)=>((e.acml_vol)/10000)}/>
</BarChart>

data 의 양이 너무 많아서 데이터에서 10000을 나눠줬다.

나누지 않으면...

거래량 데이터만 표시되는 게 아니고 주가 데이터도 표시는 되는데 너무 작아서 안보이게 된다..
거래량의 단위와 주가의 단위 차이가 너무 크니까 이렇게 된다.

그래서 진짜들은

차트를 구분해놓나보다...

하지만 문제가 또 있다

고정적으로 10000 을 나누다보니 거래량이 적은 곳들은 또....

나를 너무 힘들게 한다...

이건 간단하게 for 문으로 해결할 수 있을 거 같다.
아 ... 근데 귀찮은데...

잠깐 힘써볼까.



다양한 범위에서도 비교적 안정적으로 잘 표시해준다.
물론


예외는 있는 거 같다.

뭐 어쨌든 내가 원하는 차트로 완벽히 구현된 건 아니지만, 그럭저럭 만족스러운 차트가 되었다!

고생했다!
오랜만!

오늘은 여기까지

추가

Docs 를 읽어보다 SyncId 라는 걸 발견했다.

😮?!!

😲!!!!!!!

아니 그럼 하나의 Chart 에서 두 개의 Bar 로 표현한 게 아니라 두 개의 Chart 를 Synchronize 시킨 거구나!!

두 개의 Chart 를 Synchronize 해 진짜 주식 차트처럼 만들어보자

두 개의 Chart 를 Synchronize 해 진짜 주식 차트처럼 만들기

profile
BEAT A SHOTGUN

1개의 댓글

comment-user-thumbnail
2023년 3월 4일

안녕하세요 글 잘 보았습니다. 게시글 참고해서 한국투자증권 API를 쓰려고 하는데 토큰 발급부터 aixoserror이 계속 떠서 2일동안 계속 이거만 붙잡다가 질문드립니다ㅜㅜ
혹시 한국투자증권API 코드 조금만 볼 수 있을까요??

답글 달기