기억보단 기록을/React

React Chart Library 조사

_OIL 2023. 5. 10. 22:09
반응형
해당 글은 2021년 3월 13일에 작성된 글입니다

차트라이브러리 선택 종목 데이터를 매핑하기 위해 React 차트 라이브러리 탐색했습니다. 많은 라이브러리가 존재한다는 것을 알게 되었지만 어떤 것이 현 프로젝트에 맞는 것인지 판단하기 어려워 알맞은 차트 라이브러리가 무엇인지 조사하고 정리했습니다.

 

필요한 차트 유형

 

[Candlestick 와 Line를 합친 그래프]                                                                                      [Bar 그래프]
[두개의 요소를 비교하는 Bar 그래프]                                                                 [Area Chart그래프]

라이브러리 심사 조건

  • 참고하기 쉬운 공식 문서
  • 인기(github star, npm weekly Downloads)
  • 다양한 차트 타입
  • 의존성 여부(의존성이 작은 것을 선호)
  • 필요한 차트 유형을 쉽게 만들 수 있는지

테스트 방식

현 프로젝트 개발에 사용 중인 주식 종목 데이터(stockHistories)를 불러와 lines, candles, box 차트를 구현해봅니다.

차트 라이브러리

  1. react-stockcharts 난이도 ★★★★★ 인기 ★☆☆☆☆ 적합성 ★★★☆☆
    차트 유형이 많고 고도화되었지만 문서가 친절하지 않습니다. 프로젝트에 쓰이는 종목 데이터를 매핑해보려고 했으나 별도의 데이터 변환 작업을 해야 돼서 간단한 테스트 작업조차도 힘든 라이브러리입니다.
  2. recharts 난이도 ★★☆☆☆ 인기 ★★★☆☆ 적합성 ★★☆☆☆
    import { Area, AreaChart, CartesianGrid, Tooltip, XAxis, YAxis } from "recharts";
    import React from "react";
    
    import { STOCK_HISTORIES } from "@graphql/stock";
    import { useQuery } from "@apollo/client";
    
    function AreaChartComponent() {
      const { loading, error, data } = useQuery(STOCK_HISTORIES, {
        variables: { stockCode: "000810", firstDate: "2021-02-17", lastDate: "2021-03-10", cycleCode: "D" },
        onCompleted: (data) => {
        
        },
      });
    
      if (loading) return <p>Loading ...</p>;
      const { stockHistories } = data;
      return (
        <AreaChart
          width={500}
          height={400}
          data={stockHistories}
          margin={{
            top: 10,
            right: 30,
            left: 0,
            bottom: 0,
          }}
        >
          <CartesianGrid strokeDasharray="3 3" />
          <XAxis dataKey="trdDate" />
          <YAxis />
          <Tooltip />
          <Area type="monotone" dataKey="trdVolume" stroke="#8884d8" fill="#8884d8" />
        </AreaChart>
      );
    }
    
    export default AreaChartComponent;
    문서가 잘 구성되어있으며 사용하기도 쉽습니다. 라이브러리에 존재하는 props 네이밍도 간결하게 구성되어서 쉽게 접근할 수 있습니다. 애니메이션이 기본 적용되어 보기에 좋고 적당한 커스텀도 가능한 것 같습니다. 다만 candleStickChart에 대한 지원이 공식적으로 없는 것으로 보아 모든 차트 유형을 대응할 수는 없을 것 같습니다.

[recharts] stockHistories Query의 trdVolume 표시

3. apexcharts

난이도 ★★☆☆☆

인기 ★★★★☆

적합성 ★★★★☆

차트 종류가 다양하며 문서도 잘 정리되어있습니다. candleStick과 line을 조합할 수 있는 기능이 있습니다. 프로젝트 요구 사항에 적합한 커스텀도 가능할 것으로 보이며 라이브러리에 대한 이해도와 숙련도가 높아진다면 역동적인 차트들을 구현할 수 있을 것으로 보입니다.

//apexchart candle with line example

import React, { Component, useEffect, useState } from "react";

import { STOCK_HISTORIES } from "@graphql/stock";
import dynamic from "next/dynamic";
import produce from "immer";
import { useQuery } from "@apollo/client";

const Chart = dynamic(() => import("react-apexcharts"), { ssr: false });
const ApexCharts = dynamic(() => import("apexcharts"), { ssr: false });

export default function ApexCandleChart(props) {
  const [test, setTest] = useState({
    series: [
      {
        name: "line",
        type: "line",
        data: [],
      },
      {
        name: "candle",
        type: "candlestick",
        data: [],
      },
    ],
    options: {
      chart: {
        type: "candlestick",
        height: 350,
      },
      title: {
        text: "CandleStick Chart",
        align: "left",
      },
      xaxis: {
        type: "category",

        // categories: [1, 2, 3, 4, 5],
      },
      yaxis: {
        tooltip: {
          enabled: true,
        },
      },
    },
  });

  const { loading, error, data } = useQuery(STOCK_HISTORIES, {
    variables: { stockCode: "000810", firstDate: "2021-02-17", lastDate: "2021-03-09", cycleCode: "D" },
    onCompleted: ({ stockHistories }) => {
      const candles = stockHistories.map((item) => {
        //[{ x: date, y: [O,H,L,C] }]
        return {
          x: item.trdDate,
          y: [
            parseFloat(item.openPrice),
            parseFloat(item.highPrice),
            parseFloat(item.lowPrice),
            parseFloat(item.closePrice),
          ],
        };
      });

      const lines = stockHistories.map((item) => {
        return {
          x: item.trdDate,
          y: parseFloat(item.highPrice),
        };
      });

      setTest((prevState) => ({
        ...prevState,
        series: [
          {
            name: "line",
            type: "line",
            data: lines,
          },
          {
            name: "candle",
            type: "candlestick",
            data: candles,
          },
        ],
      }));
    },
  });

  if (loading) return <p>Loading ...</p>;
  const { stockHistories } = data;

  return (
    <div id="chart">
      <Chart options={test?.options} series={test?.series} type="candlestick" height={350} />
    </div>
  );
}

[apexcharts] candleStick with lines

 

4. chart js with chart-js-2

난이도 ★★★☆☆

인기 ★★★★★

적합성 ★★☆☆☆

조사한 차트 라이브러리 중에서 가장 인기가 많습니다. 기본적인 차트 유형과 기능들은 적지만 이미 많은 사람들이 고도화된 플러그인들을 올려두었기 때문에 상관없습니다. 다만 상황에 맞는 플러그인들을 일일이 탑재해야 되고 탑재된 플러그인들이 현 프로젝트에 사용 중인 nextjs와 제대로 호환이 될지는 장담할 수 없습니다. 또한 플러그인들을 사용하기 위해 해당 플러그인을 조사해야 되는 번거로움도 존재합니다. chart-js-2는 chart js를 React로 감싼 모듈이고 공식적인 문서가 없어서 chart js의 문서를 봐야 합니다.

결론

13개 정도의 차트 라이브러리를 조사했고 그중 현 프로젝트에 어울리는 라이브러리 4개만 테스트해봤습니다.

비교적 간단한 테스트를 진행했지만 대부분의 라이브러리가 candleChart와 lineChart를 혼합한 그래프를 구현하기 위해서는 지저분한 커스텀 코드를 만들거나 무거운 플러그인을 탑재해야 됐었습니다.

더 나아가 단순히 데이터들만 매핑하는 것이 아니라 그래프를 확대, 축소, 스크롤, 영역 드래그 등 과 같은 이벤트 호출 시 유동적으로 변동하는 차트를 만들기 위해서는 상황에 맞는 이벤트 함수가 존재해야 되는데 apexcharts만 찾기 쉽게 문서가 잘 정리되어 있는 반면 나머지 라이브러리 들은 해당 기능이 없거나 숨겨져 있어 원하는 동작을 단시간에 구현하기 어렵겠다는 느낌을 많이 받았습니다.

그래서 저는 apexcharts를 먼저 사용해 볼 생각입니다.


2022. 10. 07 최근 소식

antd chart를 애용하고 있습니다. 그래프 종류도 다양하고 공식 문서가 잘되어있어서 프로젝트에 쉽게 적용가능합니다!

공식 문서 기본언어가 중국어라서 처음엔 거부감이 들지만 영어 번역도 지원하니 나쁘진 않아요

참고

반응형