Skip to content

Commit c26921e

Browse files
committed
feat: 차트 페이지네이션 작업중
1 parent 71fb299 commit c26921e

File tree

2 files changed

+65
-61
lines changed

2 files changed

+65
-61
lines changed

src/features/tradeview/ui/Chart/ValueSeries.tsx

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import * as am5stock from '@amcharts/amcharts5/stock';
22
import * as am5xy from '@amcharts/amcharts5/xy';
33
import type { PropsWithChildren } from 'react';
4-
54
import { isNullish } from '~/shared/utils';
65
import type { CandlestickData } from '../../types/tradeview.type';
76
import { isDisposed } from '../../utils';
@@ -18,7 +17,7 @@ export type ValueSeriesProps = PropsWithChildren<
1817
Partial<StockAxis> & {
1918
pastTimeData?: CandlestickData[];
2019
seriesSettings?: SeriesSettings;
21-
fetchPastTimeData?: () => Promise<void>;
20+
fetchPastTimeData?: (prevData: CandlestickData) => CandlestickData[];
2221
}
2322
>;
2423

@@ -99,9 +98,16 @@ export default function ValueSeries({
9998
dateAxis.on('start', async (value) => {
10099
if (!value) return;
101100

102-
if (value < 0) {
103-
fetchPastTimeData?.();
104-
// dateAxis.zoom(0, 1, 0);
101+
if (value < -0.1) {
102+
const generatedPastData = fetchPastTimeData?.(
103+
newValueSeries.data.values[0] as CandlestickData,
104+
);
105+
106+
if (!generatedPastData) return;
107+
108+
const newData = [...generatedPastData, ...newValueSeries.data.values];
109+
110+
newValueSeries.data.setAll(newData);
105111
}
106112
});
107113

src/features/tradeview/ui/Chart/ValueSeriesWithData.tsx

Lines changed: 54 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { useCallback, useState } from 'react';
21
import type { CandlestickData } from '../../types/tradeview.type';
32
import ValueSeries, { type ValueSeriesProps } from './ValueSeries';
43

@@ -49,65 +48,64 @@ const DUMMY_DATA: CandlestickData[] = (() => {
4948
return data;
5049
})();
5150

52-
export default function ValueSeriesWithData(props: ValueSeriesProps) {
53-
const [data, setData] = useState<CandlestickData[]>(DUMMY_DATA);
54-
55-
const fetchPastTimeData = useCallback(async () => {
56-
setData((prevData) => {
57-
if (prevData.length === 0) return prevData;
58-
59-
// 기존 데이터의 가장 오래된 타임스탬프와 가격을 기준으로 함
60-
const oldestData = prevData[0];
61-
const oldestTimestamp = oldestData.Timestamp;
62-
const basePrice = oldestData.Open;
63-
const baseVolume = 1000;
64-
65-
const pastData: CandlestickData[] = [];
66-
67-
// 100개의 1분봉 데이터를 가장 오래된 데이터보다 이전 시간으로 생성
68-
for (let i = 10; i >= 1; i--) {
69-
const date = new Date(oldestTimestamp);
70-
date.setMinutes(date.getMinutes() - i);
71-
72-
// 이전 봉의 종가를 기준으로 랜덤 변동 (-1% ~ +1%)
73-
const changePercent = (Math.random() * 2 - 1) / 100;
74-
const prevClose = pastData.length
75-
? pastData[pastData.length - 1].Close
76-
: basePrice;
77-
78-
const open = prevClose;
79-
const close = open * (1 + changePercent);
80-
81-
// 고가는 시가와 종가 중 큰 값보다 0-1% 높게
82-
const highBaseValue = Math.max(open, close);
83-
const high = highBaseValue * (1 + Math.random() * 0.01);
84-
85-
// 저가는 시가와 종가 중 작은 값보다 0-1% 낮게
86-
const lowBaseValue = Math.min(open, close);
87-
const low = lowBaseValue * (1 - Math.random() * 0.01);
88-
89-
// 거래량 (기준 거래량의 30-200%)
90-
const volume = baseVolume * (0.3 + Math.random() * 1.7);
91-
92-
pastData.push({
93-
Timestamp: date.getTime(),
94-
Open: Number(open.toFixed(2)),
95-
Close: Number(close.toFixed(2)),
96-
High: Number(high.toFixed(2)),
97-
Low: Number(low.toFixed(2)),
98-
Volume: Math.round(volume),
99-
});
100-
}
101-
102-
// 새로운 과거 데이터를 기존 데이터 앞에 추가
103-
return [...pastData, ...prevData];
104-
});
105-
}, []);
51+
const fetchPastTimeData = (prevData: CandlestickData) => {
52+
const pastData: CandlestickData[] = [];
53+
54+
// 시작점은 주어진 데이터
55+
let currentClose = prevData.Close;
56+
const baseVolume = prevData.Volume;
57+
const baseTimestamp = prevData.Timestamp;
58+
59+
// 10개의 과거 데이터를 생성 (시간 역순으로)
60+
for (let i = 10; i >= 1; i--) {
61+
// 1분씩 과거로 이동 (새로운 Date 객체 생성)
62+
const pastTimestamp = baseTimestamp - i * 60 * 1000; // i분 전
63+
64+
// 이전 봉의 종가를 기준으로 시가 생성 (작은 갭 허용)
65+
const gapPercent = (Math.random() * 0.4 - 0.2) / 100; // -0.2% ~ +0.2%
66+
const open = currentClose * (1 + gapPercent);
67+
68+
// 종가 생성 (-2% ~ +2% 변동)
69+
const changePercent = (Math.random() * 4 - 2) / 100;
70+
const close = open * (1 + changePercent);
71+
72+
// 고가와 저가 생성
73+
const maxPrice = Math.max(open, close);
74+
const minPrice = Math.min(open, close);
75+
76+
// 고가: 시가/종가 중 높은 값보다 0~2% 높게
77+
const high = maxPrice * (1 + Math.random() * 0.02);
78+
79+
// 저가: 시가/종가 중 낮은 값보다 0~2% 낮게
80+
const low = minPrice * (1 - Math.random() * 0.02);
81+
82+
// 거래량 (기준의 50~150%)
83+
const volume = baseVolume * (0.5 + Math.random());
10684

85+
const candlestick: CandlestickData = {
86+
Timestamp: pastTimestamp,
87+
Open: Number(open.toFixed(2)),
88+
Close: Number(close.toFixed(2)),
89+
High: Number(high.toFixed(2)),
90+
Low: Number(low.toFixed(2)),
91+
Volume: Math.round(volume),
92+
};
93+
94+
pastData.push(candlestick);
95+
96+
// 다음 반복을 위해 현재 종가를 다음 봉의 기준으로 설정
97+
currentClose = close;
98+
}
99+
100+
// 시간순으로 정렬 (과거 -> 현재)
101+
return pastData.sort((a, b) => a.Timestamp - b.Timestamp);
102+
};
103+
104+
export default function ValueSeriesWithData(props: ValueSeriesProps) {
107105
return (
108106
<ValueSeries
109107
{...props}
110-
pastTimeData={data}
108+
pastTimeData={DUMMY_DATA}
111109
fetchPastTimeData={fetchPastTimeData}
112110
/>
113111
);

0 commit comments

Comments
 (0)