최근 작업하고 있는 페이지에서 light-weight chart라는 라이브러리를 사용했다. 매우 가볍고 간결하며 사용법도 어렵지 않다.
google에 lightweight-chart를 검색하면 TradingView페이지에서 이 라이브러리에 대해서 살펴볼 수 있다.
원하는 차트 커스텀별로 코드를 볼 수 있는데 순수자바스크립트로 이루어져 있다.
실시간으로 캔들이 그려져야 하기 때문에 리얼타임 이뮬레이션을 선택했다.
react에서
import React, { useState, useEffect, useRef } from 'react;
import { createChart } from 'light-weight-charts';
로 import 해주었고
useEffect속에는 차트를 만드는 함수 호출하는 것만 넣어줬다.
그리고 내가 원하던 것은,
1. 차트에 들어올 정보 코드 짜기 ===> 제공되는 코드를 이용하되 react에 맞춰 바꾸고 원하는 모양과 색으로 옵션을 달리 했다.
2. 차트를 원하는 곳에 넣기
이었다. ===> useRef사용했다.
const makeChart = () => {
let chart = createChart(chartBox.current.id, {
//첫 번째 인자로 사용된 chartBox는 ref설정 해준 div이다.
width: 500,
height: 300,
layout: {
backgroundColor: '#000000',
textColor: 'rgba(255,255,255,0)',
},
crosshair: {
mode: window.LightweightCharts.CrosshairMode.Normal,
//원래는 이 위에 window가 없어야 한다는데 나는 window가 없으면 crosshair에 대해서 에러가 나서 window를 붙이고 진행했다.
},
options: {
responsive: true,
maintainAspectRatio: false,
},
});
let candleSeries = chart.addCandlestickSeries({
upColor: '',
downColor: '',
borderDownColor:'',
borderUpColor: '',
wickDownColor: '',
wichUpColor: '',
//원하는 색들을 넣어주면된다.
});
let data = [
{
time: '2020-05-09',
open: 180.34,
high: 180.99,
low: 178.57,
close: 179.85,
},
{
time: '2020-05-10',
open: 180.34,
high: 190.99,
low: 179.57,
close: 185.31,
},
.
.
.
];
candleSeries.setData(data);
let lastClose = data[data.length -1].close;
let lastIndex = data.length -1;
let targetIndex = lastIndex + 105 + Math.round(Math.random() + 30);
let targetPrice = getRandomPrice();
let currentIndex = lastIndex + 1;
let currentBusinessDay = { day: 10, month: 5, year: 2020 };
let ticksInCurrentBar = 0;
let currentBar = {
open: null,
high: null,
low: null,
close: null,
time: currentBusinessDay,
};
const mergeTickToBar = (price) => {
if (currentBar.open === null) {
currentBar.open = price;
currentBar.high = price;
currentBar.low = price;
currentBar.close = price;
} else {
currentBar.close = price;
currentBar.high = Math.max(currentBar.high, price);
currentBar.low = Math.min(currentBar.low, price);
}
candleSeries.update(currentBar);
};
const reset = () => {
candleSeries.setData(data);
lastClose = data[data.length - 1].close;
lastIndex = data.length - 1;
targetIndex = lastIndex + 5 + Math.round(Math.random() + 30);
targetPrice = getRandomPrice();
currentIndex = lastIndex + 1;
currentBusinessDay = { day: 10, month: 5, year: 2020 };
ticksInCurrentBar = 0;
};
const getRandomPrice = () => {
return 10 + Math.round(Math.random() * 10000) / 100;
};
const nextBusinessDay = (time) => {
let d = newDate();
d.setUTCFullYear(time.year);
d.setUTCMonth(time.month -1);
d.setUTCDate(time.day +1);
d.setUTCHours(0.0.0.0);
return {
year: d.getUTCFullYear(),
month: d.getUTCMonth() +1,
day: d.getUTCDate(),
}
};
setInterval(() => {
let deltaY = targetPrice - lastClose;
let deltaX = targetIndex - lastIndex;
let angle = deltaY / deltaX;
let basePrice = lastClose + (currentIndex - lastIndex) * angle;
let noise = 0.1 - Math.random() * 0.2 + 1.0;
let noisedPrice = basePrice * noise;
mergeTickToBar(noisedPrice);
if (++ticksInCurrentBar === 5) {
// 옆에 bar로 이동
currentIndex++;
currentBusinessDay = nextBusinessDay(currentBusinessDay);
currentBar = {
open: null,
high: null,
low: null,
close: null,
time: currentBusinessDay,
};
ticksInCurrentBar = 0;
if (currentIndex === 5000) {
reset();
return;
}
if (currentIndex === targetIndex) {
// 트렌드 바꾸기
lastClose = noisedPrice;
lastIndex = currentIndex;
targetIndex = lastIndex + 5 + Math.round(Math.random() + 30);
targetPrice = getRandomPrice();
}
}
}, 5000;
})
}
이렇게 이용했다. 그러면 캔들이 자동으로 옆에 그려진다.
실제 사용했던 코드에서도 보완해야 할 점들이 많지만 무엇보다 hook쓰는게 익숙하지 않아서 useEffect나 useRef를 사용하는 데에 있어서 버벅거렸었다. hook이 어서 익숙해지기를!
안녕하세요, 혹시 제가 초보라 몇가지 여쭈고 싶은게 있어서요
하단에 가로축 날짜말고 5분단위로 22:05 이런식으로 나오게 하고 싶은데
방법 아시면 답변 주시면 감사하겠습니다.