Skip to content

Commit

Permalink
차트 분리 및 실시간 차트 표현 방식 수정
Browse files Browse the repository at this point in the history
  • Loading branch information
dragonsuperf committed Mar 18, 2021
1 parent af1a094 commit eba202b
Show file tree
Hide file tree
Showing 5 changed files with 2,404 additions and 10,440 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ module.exports = {
rules: {
'prettier/prettier': 'error',
'no-use-before-define': 'off',
'@typescript-eslint/no-use-before-define': ['error'],
// '@typescript-eslint/no-use-before-define': ['error'],
'react/jsx-filename-extension': [1, { extensions: ['.tsx'] }],
'import/extensions': 'off',
'import/no-extraneous-dependencies': 'off',
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"@toast-ui/react-chart": "^4.1.4",
"@types/react": "^17.0.3",
"@types/react-dom": "^17.0.2",
"@types/styled-components": "^5.1.9",
"axios": "^0.21.1",
"babel-jest": "^26.6.3",
"babel-loader": "^8.2.2",
Expand All @@ -50,6 +51,7 @@
"redux": "^4.0.5",
"source-map-loader": "^2.0.1",
"style-loader": "^2.0.0",
"styled-components": "^5.2.1",
"ts-loader": "^8.0.17",
"ts-node": "^9.1.1",
"typescript": "^4.2.3",
Expand Down
82 changes: 39 additions & 43 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@ import React, { useEffect, useState } from 'react';
import axios from 'axios';
import Moment from 'moment';
import useWebSocket, { ReadyState } from 'react-use-websocket';
import styled from 'styled-components';
import CandleStickChart from './components/CandleStickChart';

const ChartContainer = styled.section`
display: flex;
width: 100%;
`;

axios.defaults.baseURL = 'https://api.bithumb.com/public';

export interface TickPrice {
Expand All @@ -19,64 +25,55 @@ function App() {
const SOCKET_API_SUB = `{"type":"ticker", "symbols": ["BTC_KRW"], "tickTypes": ["30M"]}`;

const [currency, setCurrency] = useState('BTC');
const [selectedCurrencyDatas, setSelectedCurrencyDatas] = useState<TickPrice[]>([]);
const [currentPrice, setCurrentPrice] = useState<TickPrice>();
const [prevTickDatas, setPrevTickDatas] = useState<TickPrice[]>([]);
const [realtimeTickDatas, setRealtimeTickDatas] = useState<TickPrice[]>([]);
const [currentPrice, setCurrentPrice] = useState('0');
const candleStickApi = `/candlestick/${currency}_KRW/1m`;

const { sendMessage, lastMessage, readyState } = useWebSocket(SOCKET_URL);

useEffect(() => {
getPrevTickDatas();
}, []);

useEffect(() => {
if (lastMessage !== null) {
const data = JSON.parse(lastMessage.data).content;
if (data !== null && data !== undefined) {
const newDate = Moment(`${data.date} ${data.time}`);
let newTickData = {
tickDate: newDate.format('HH:mm:ss'),
minPrice: Number(data.openPrice),
startPrice: Number(data.openPrice),
endPrice: Number(data.closePrice),
maxPrice: Number(data.closePrice),
};

const newCurrencyData = selectedCurrencyDatas;

if (currentPrice === undefined) newCurrencyData.shift();
else if (newDate.format('ss') === '00') {
newTickData = {
...newTickData,
minPrice: Math.min(newTickData.minPrice, currentPrice.endPrice),
startPrice: currentPrice.startPrice,
endPrice: currentPrice.endPrice,
maxPrice: Math.max(newTickData.maxPrice, currentPrice.endPrice),
if (realtimeTickDatas.length === 0) {
const newTickData: TickPrice = {
tickDate: newDate.format('HH:mm:ss'),
minPrice: Number(data.closePrice),
startPrice: Number(data.closePrice),
endPrice: Number(data.closePrice),
maxPrice: Number(data.closePrice),
};
newCurrencyData.shift();
} else {
newTickData = {
...newTickData,
minPrice: Math.min(newTickData.minPrice, currentPrice.endPrice),
startPrice: currentPrice.startPrice,
endPrice: currentPrice.endPrice,
maxPrice: Math.max(newTickData.maxPrice, currentPrice.endPrice),
};
newCurrencyData.pop();
setRealtimeTickDatas([...realtimeTickDatas, newTickData]);
return;
}
console.log(newTickData);
setCurrentPrice(newTickData);
const prevTickData = realtimeTickDatas[realtimeTickDatas.length - 1];
const newTickData: TickPrice = {
tickDate: newDate.format('HH:mm:ss'),
minPrice: Number(Math.min(prevTickData.endPrice, data.closePrice)),
startPrice: Number(prevTickData.endPrice),
endPrice: Number(data.closePrice),
maxPrice: Number(Math.max(prevTickData.endPrice, data.closePrice)),
};

newCurrencyData.push(newTickData);
setSelectedCurrencyDatas(newCurrencyData);
setCurrentPrice(newTickData.endPrice.toString());
setRealtimeTickDatas([...realtimeTickDatas, newTickData]);
}
}
}, [lastMessage]);

useEffect(() => {
switch (readyState) {
case ReadyState.OPEN:
console.log('open');
sendMessage(SOCKET_API_SUB);
break;
default:
console.log('idle....');
break;
}
}, [readyState]);
Expand All @@ -93,7 +90,7 @@ function App() {
});
};

const getCurrentCryptoCurrency = () => {
const getPrevTickDatas = () => {
axios
.get(candleStickApi)
.then((response: any) => {
Expand All @@ -102,19 +99,18 @@ function App() {
const newTickPriceList: TickPrice[] = convertDataToTickPrice(
currentData.slice(currentDataLength - 100, currentDataLength - 1),
);
setSelectedCurrencyDatas(newTickPriceList);
setPrevTickDatas(newTickPriceList);
setTimeout(getPrevTickDatas, 60000);
})
.catch((error) => console.log(error));
};

useEffect(() => {
getCurrentCryptoCurrency();
}, []);

return (
<>
<div>React!</div>
<CandleStickChart currencyDatas={selectedCurrencyDatas} />
<ChartContainer>
<CandleStickChart currencyDatas={prevTickDatas} chartTitle="이전 기록" />
<CandleStickChart currencyDatas={realtimeTickDatas} chartTitle={`현재가: ${currentPrice} KRW`} />
</ChartContainer>
</>
);
}
Expand Down
51 changes: 31 additions & 20 deletions src/components/CandleStickChart.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import { Chart } from 'react-google-charts';
import React from 'react';
import styled from 'styled-components';
import { TickPrice } from '../App';

const ChartItem = styled.div`
flex-grow: 1;
max-width: 50%;
`;

interface ChartProps {
chartTitle: string;
currencyDatas: TickPrice[];
}

function CandleStickChart({ currencyDatas }: ChartProps) {
function CandleStickChart({ chartTitle, currencyDatas }: ChartProps) {
const tickPriceToChartData = () => {
if (currencyDatas === undefined) return false;

Expand All @@ -21,26 +28,30 @@ function CandleStickChart({ currencyDatas }: ChartProps) {
return chartData;
};

if (currencyDatas.length === 0) return null;

return (
<Chart
height={350}
chartType="CandlestickChart"
loader={<div>Loading Chart</div>}
data={tickPriceToChartData()}
options={{
legend: 'none',
bar: { groupWidth: '50%' }, // Remove space between bars.
candlestick: {
fallingColor: { strokeWidth: 0, fill: '#0051c7' },
risingColor: { strokeWidth: 0, fill: '#a52714' },
},
hAxis: {
title: 'test',
ticks: [22058, 22080, 22100, 22120],
},
}}
rootProps={{ 'data-testid': '2' }}
/>
<ChartItem>
<Chart
height={350}
chartType="CandlestickChart"
loader={<div>Loading Chart</div>}
data={tickPriceToChartData()}
options={{
legend: 'none',
bar: { groupWidth: '50%' }, // Remove space between bars.
candlestick: {
fallingColor: { strokeWidth: 0, fill: '#0051c7' },
risingColor: { strokeWidth: 0, fill: '#a52714' },
},
hAxis: {
title: chartTitle,
ticks: [22058, 22080, 22100, 22120],
},
}}
rootProps={{ 'data-testid': '2' }}
/>
</ChartItem>
);
}

Expand Down
Loading

0 comments on commit eba202b

Please sign in to comment.