
#5.13 ~ 5.16 2023.04.10 (월)
이번에는 API에서 받아온 data를 시각화 해볼거임.
APEXCHART는 수 많은 차트들을 만들 수 있는 자바스크립트 chart library임.
Apex공식홈페이지의 docs/integrations/react에 들어가서 밑의 명령어로 설치해줌.
npm install --save react-apexcharts apexcharts
//Chart.tsx
import { useQuery } from "react-query";
import { fetchCoinHistory } from "../api";
import ApexChart from "react-apexcharts"; // 1. import 해오기
interface IHistorical {
time_open: number;
time_close: number;
open: string;
high: string;
low: string;
close: string;
volume: string;
market_cap: number;
}
interface ChartProps {
coinId: string;
}
function Chart({ coinId }: ChartProps) {
const { isLoading, data } = useQuery<IHistorical[]>(["ohlcv", coinId], () =>
fetchCoinHistory(coinId)
);
console.log(data);
console.log(data?.map((price) => parseFloat(price.close)));
return (
<div>
{isLoading ? (
"Loading chart"
) : (
<ApexChart
type="line"
series={[
{
name: "Price",
data: data?.map((price) => parseFloat(price.close)) ?? [],
},
]}
options={{
theme: {
mode: "dark",
},
chart: {
height: 300,
width: 500,
toolbar: {
show: false,
},
background: "transparent",
},
grid: { show: false },
stroke: {
curve: "smooth",
width: 4,
},
yaxis: {
show: false,
},
xaxis: {
axisBorder: { show: false },
axisTicks: { show: false },
labels: { show: false },
},
}}
/>
)}
</div>
);
}
export default Chart;
ApexChart를 import 해옴.{isLoading ? "Loading chart" : <ApexChart/>} : 삼항연산자로 isLoading이 true면 "Loading chart"라는 문자가 보이게 false면 <ApexChart/>가 보이게 return 해줌.
위와 같이 코드를 작성했을때 오류가 났는데, 강의에서 제공해준 API는 close 데이터가 string이기 때문에 parseFloat를 통해 형 변환을 시켜줘야 했음.
위와 같이 작성해서 오류 해결함!
결과화면 ↓

차트를 좀 더 예쁘게 꾸며보자.
//Chart.tsx
import { useQuery } from "react-query";
import { fetchCoinHistory } from "../api";
import ApexChart from "react-apexcharts"; // 1. import 해오기
interface IHistorical {
time_open: number;
time_close: number;
open: string;
high: string;
low: string;
close: string;
volume: string;
market_cap: number;
}
interface ChartProps {
coinId: string;
}
function Chart({ coinId }: ChartProps) {
const { isLoading, data } = useQuery<IHistorical[]>(["ohlcv", coinId], () =>
fetchCoinHistory(coinId)
);
console.log(data);
console.log(data?.map((price) => parseFloat(price.close)));
return (
<div>
{isLoading ? (
"Loading chart"
) : (
<ApexChart
type="line"
series={[
{
name: "Price",
data: data?.map((price) => parseFloat(price.close)) ?? [],
},
]}
options={{
theme: {
mode: "dark",
},
chart: {
height: 300,
width: 500,
toolbar: {
show: false,
},
background: "transparent",
},
grid: { show: false },
stroke: {
curve: "smooth",
width: 4,
},
yaxis: {
show: false,
},
xaxis: {
axisBorder: { show: false },
axisTicks: { show: false },
labels: { show: false },
type: "datetime",
categories: data?.map((price) =>
new Date(price.time_close * 1000).toISOString()
),
},
fill: {
type: "gradient",
gradient: { gradientToColors: ["#0be881"], stops: [0, 100] },
},
colors: ["#0fbcf9"],
tooltip: {
y: {
formatter: (value) => `$ ${value.toFixed(2)}`,
},
},
}}
/>
)}
</div>
);
}
export default Chart;
$ ${value.toFixed(2)},}categories: data?.map((price) => new Date(price.time_close * 1000).toISOString()) price.time_close를 밀리초로 바꾸기 위해 1000을 곱해줌. 밑의 콘솔창 예시 참고하기
결과화면 ↓

apex chart의 옵션들을 다 찾는게 어렵다면 Demos를 살펴보는 것이 배우기 가장 좋은 방법임! 만들어진 코드를 보면서 어떻게 data를 구조화했고 어떻게 커스텀했는지 살펴보면 좋음.
마지막으로 좀 더 바꿔보자.

이제 코인의 가격이 실시간으로 보여주기 위해 5초마다 fetching을 할거임.
const { isLoading: tickersLoading, data: tickersData } = useQuery<PriceData>(
["tickers", coinId],
() => fetchCoinTickers(coinId),
{ refetchInterval: 5000 }
)


마지막으로 위의 제목을 바꿔볼건데 이걸 하기 위해선 React Helmet을 사용해야 함.
npm i react-helmet
npm i --save-dev @types/react-helmet
첫번째 명령어로 설치해주고 타입스크립트는 react-helmet을 모르기 때문에 두번째 명령어도 설치해주자.
//coin.tsx
import { Helmet } from "react-helmet"; // 1. import하기
function Coin() {
//코드생략
//state: { name: coin.name }
return (
<Container>
<Helmet>
<title>
{state?.name ? state.name : loading ? "Loading..." : infoData?.name}
</title>
</Helmet>
<Header> //원래 있었던 코드
<Title>
{state?.name ? state.name : loading ? "Loading..." : infoData?.name}
</Title>
</Header>
</Container>
);
}
export default Coin;
<Helmet>컴포넌트를 만들어서 안에 title 태그를 render해 줌. 여기서 무엇을 render하던 그게 문서의 head로 감.

결과 화면 ↓
