실시간 차트 갱신오류 수정
This commit is contained in:
@@ -7,6 +7,20 @@ import { DISPLAY_COUNT } from '../hooks/useUpbitData';
|
||||
|
||||
/** Upbit 실시간 — 초기 히스토리가 이 개수 미만이면 setData 하지 않음 (종목 전환 직후 1~2봉만 로드되는 깨짐 방지) */
|
||||
const MIN_BARS_FOR_FULL_RELOAD = Math.min(50, Math.floor(DISPLAY_COUNT / 4));
|
||||
|
||||
/** 종목 전환 직후 stale/partial 데이터 차단 — fetch 완료(barsMarket 확정) 후 sparse history도 렌더 허용 */
|
||||
function canApplyChartBars(
|
||||
barData: OHLCVBar[],
|
||||
barsMarket: string | null | undefined,
|
||||
market: string,
|
||||
): boolean {
|
||||
if (barData.length === 0) return false;
|
||||
if (barsMarket === undefined) return true;
|
||||
if (barsMarket == null || barsMarket !== market) return false;
|
||||
if (!market.startsWith('KRW-')) return true;
|
||||
if (barData.length >= MIN_BARS_FOR_FULL_RELOAD) return true;
|
||||
return barData.length >= 2;
|
||||
}
|
||||
import DrawingCanvas, { hitTestDrawing } from './DrawingCanvas';
|
||||
import PaneLegend, { type PaneLegendProps } from './PaneLegend';
|
||||
import ChartHoverToolbar from './ChartHoverToolbar';
|
||||
@@ -167,14 +181,9 @@ const TradingChart: React.FC<TradingChartProps> = ({
|
||||
const [candleOnlyMode, setCandleOnlyMode] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const ready = barsMarket == null
|
||||
? false
|
||||
: barsMarket === undefined
|
||||
? true
|
||||
: barsMarket === market;
|
||||
if (ready) {
|
||||
if (barsMarket === market) {
|
||||
barsRef.current = bars;
|
||||
} else if (barsMarket != null && barsMarket !== market) {
|
||||
} else {
|
||||
barsRef.current = [];
|
||||
}
|
||||
}, [bars, barsMarket, market]);
|
||||
@@ -296,8 +305,7 @@ const TradingChart: React.FC<TradingChartProps> = ({
|
||||
const barData = barsRef.current;
|
||||
const inds = indicatorsRef.current;
|
||||
if (!m || barData.length === 0) return;
|
||||
if (barsMarket !== undefined && barsMarket !== market) return;
|
||||
if (market.startsWith('KRW-') && barData.length < MIN_BARS_FOR_FULL_RELOAD) return;
|
||||
if (!canApplyChartBars(barData, barsMarket, market)) return;
|
||||
prevBarsKey.current = '';
|
||||
reloadAllRef.current?.(
|
||||
m, barData,
|
||||
@@ -315,7 +323,7 @@ const TradingChart: React.FC<TradingChartProps> = ({
|
||||
const barData = barsRef.current;
|
||||
const inds = indicatorsRef.current;
|
||||
if (!m || barData.length === 0) return;
|
||||
if (barsMarket !== undefined && barsMarket !== market) return;
|
||||
if (!canApplyChartBars(barData, barsMarket, market)) return;
|
||||
|
||||
const expected = countExpectedVisibleIndicators(inds);
|
||||
if (expected === 0) return;
|
||||
@@ -699,8 +707,7 @@ const TradingChart: React.FC<TradingChartProps> = ({
|
||||
// 데이터가 이미 barsRef에 있지만 차트에 아직 세팅되지 않은 경우 (예: 멀티레이아웃 초기 렌더) 재로드
|
||||
if (barsRef.current.length > 0 && !m.hasMainSeries()) {
|
||||
const bm = barsMarketRef.current;
|
||||
if (bm != null && bm !== marketRef.current) return;
|
||||
if (marketRef.current.startsWith('KRW-') && barsRef.current.length < MIN_BARS_FOR_FULL_RELOAD) return;
|
||||
if (!canApplyChartBars(barsRef.current, bm, marketRef.current)) return;
|
||||
void reloadAll(
|
||||
m,
|
||||
barsRef.current,
|
||||
@@ -723,6 +730,22 @@ const TradingChart: React.FC<TradingChartProps> = ({
|
||||
});
|
||||
ro.observe(containerRef.current);
|
||||
|
||||
const bootstrapIfReady = () => {
|
||||
const m = managerRef.current;
|
||||
if (!m || m.hasMainSeries()) return;
|
||||
const data = barsRef.current;
|
||||
if (!canApplyChartBars(data, barsMarketRef.current, marketRef.current)) return;
|
||||
void reloadAllRef.current(
|
||||
m,
|
||||
data,
|
||||
prevChartType.current,
|
||||
prevTheme.current,
|
||||
prevLogScale.current,
|
||||
indicatorsRef.current,
|
||||
);
|
||||
};
|
||||
requestAnimationFrame(() => requestAnimationFrame(bootstrapIfReady));
|
||||
|
||||
return () => {
|
||||
unsub();
|
||||
unsubClick();
|
||||
@@ -772,12 +795,7 @@ const TradingChart: React.FC<TradingChartProps> = ({
|
||||
useEffect(() => {
|
||||
const mgr = managerRef.current;
|
||||
if (!mgr || !chartMgr || bars.length === 0) return;
|
||||
|
||||
const barsReady = barsMarket === undefined
|
||||
? true
|
||||
: barsMarket === market;
|
||||
if (!barsReady) return;
|
||||
if (market.startsWith('KRW-') && bars.length < MIN_BARS_FOR_FULL_RELOAD) return;
|
||||
if (!canApplyChartBars(bars, barsMarket, market)) return;
|
||||
|
||||
// manager 준비 전 bars 가 먼저 도착한 경우(로그인 직후 등) 메인 시리즈 누락 방지
|
||||
if (!mgr.hasMainSeries()) {
|
||||
@@ -887,7 +905,7 @@ const TradingChart: React.FC<TradingChartProps> = ({
|
||||
useEffect(() => {
|
||||
const mgr = managerRef.current;
|
||||
if (!mgr || !chartMgr || bars.length === 0) return;
|
||||
if (barsMarket !== undefined && barsMarket !== market) return;
|
||||
if (!canApplyChartBars(bars, barsMarket, market)) return;
|
||||
|
||||
const expected = countExpectedVisibleIndicators(indicators);
|
||||
if (expected === 0) return;
|
||||
@@ -897,7 +915,7 @@ const TradingChart: React.FC<TradingChartProps> = ({
|
||||
window.setTimeout(() => {
|
||||
const m = managerRef.current;
|
||||
if (!m || !m.hasMainSeries()) return;
|
||||
if (barsMarket !== undefined && barsMarket !== market) return;
|
||||
if (!canApplyChartBars(bars, barsMarket, market)) return;
|
||||
const exp = countExpectedVisibleIndicators(indicatorsRef.current);
|
||||
if (exp === 0 || m.getLoadedIndicatorCount() >= exp) return;
|
||||
prevBarsKey.current = '';
|
||||
|
||||
Reference in New Issue
Block a user