실시간 차트 갱신시 화면떨림 문제 해결

This commit is contained in:
Macbook
2026-05-27 14:54:50 +09:00
parent f7aac535d8
commit 7a0af36b9b
10 changed files with 517 additions and 130 deletions
+45 -2
View File
@@ -30,9 +30,11 @@ import { enrichIndicatorConfig, getIndicatorDef } from './utils/indicatorRegistr
import { initializeIndicatorConfigForEditor } from './utils/indicatorSettingsEditor';
import {
buildMainIndicatorConfig,
chartIndicatorsNeedDefaultsRefresh,
indicatorSettingsTemplateId,
indicatorTypeFromSettingsId,
isIndicatorSettingsTemplateId,
mergeGlobalDefaultsOntoChartIndicators,
} from './utils/indicatorMainConfig';
import { normalizeSmaConfig, createDefaultSmaPlotVisibility } from './utils/smaConfig';
import { normalizeIchimokuConfig } from './utils/ichimokuConfig';
@@ -49,6 +51,8 @@ import {
duplicateIndicatorInList,
mergeIndicators,
reorderIndicatorGroup,
removeIndicatorFromList,
removeIndicatorTypeFromList,
splitIndicatorPane,
replaceIndicatorConfigsFromTypes,
} from './utils/indicatorPaneMerge';
@@ -199,6 +203,7 @@ function App() {
const [mobileRightOpen, setMobileRightOpen] = useState(false);
const [mobileRightTab, setMobileRightTab] = useState<'trade' | 'orderbook'>('trade');
const [menuPage, setMenuPage] = useState<MenuPage>('chart');
const chartVisible = menuPage === 'chart';
const isMobile = useIsMobile();
// ── 마켓 패널 시세 데이터 ─────────────────────────────────────────────
@@ -1393,7 +1398,7 @@ function App() {
const slotRef = slotRefs.current[activeSlot];
if (slotRef) { slotRef.removeIndicatorByType(type); return; }
}
setIndicators(prev => prev.filter(i => i.type !== type));
setIndicators(prev => removeIndicatorTypeFromList(prev, type));
}, [layoutDef.count, activeSlot]);
/**
@@ -1480,6 +1485,41 @@ function App() {
const bulkSettingsIndicators = layoutDef.count > 1 ? activeSlotIndicators : indicators;
/** 설정 화면에서 DB 기본값 저장 후 차트 복귀 시 — 전역 기본값을 차트 인스턴스에 일괄 반영 */
const lastSyncedSettingsRevisionRef = useRef(indicatorSettingsRevision);
const syncChartsFromSavedDefaults = useCallback(() => {
const merge = (inds: IndicatorConfig[]) =>
mergeGlobalDefaultsOntoChartIndicators(inds, getParams, getVisualConfig);
if (layoutDef.count > 1) {
slotRefs.current.slice(0, layoutDef.count).forEach(slot => {
if (!slot) return;
const current = slot.getIndicators();
const next = merge(current);
if (chartIndicatorsNeedDefaultsRefresh(current, next)) {
slot.setIndicators(next);
}
});
const activeInds = slotRefs.current[activeSlot]?.getIndicators() ?? activeSlotIndicators;
const mergedActive = merge(activeInds);
if (chartIndicatorsNeedDefaultsRefresh(activeInds, mergedActive)) {
setActiveSlotIndicators(mergedActive.map(i => ({ ...i })));
}
} else {
setIndicators(prev => {
const next = merge(prev);
return chartIndicatorsNeedDefaultsRefresh(prev, next) ? next : prev;
});
}
}, [layoutDef.count, activeSlot, activeSlotIndicators, getParams, getVisualConfig]);
useLayoutEffect(() => {
if (!chartVisible) return;
if (indicatorSettingsRevision <= lastSyncedSettingsRevisionRef.current) return;
syncChartsFromSavedDefaults();
lastSyncedSettingsRevisionRef.current = indicatorSettingsRevision;
}, [chartVisible, indicatorSettingsRevision, syncChartsFromSavedDefaults]);
/** 보조지표 일괄 설정 적용 — 전체 지표 DB + 차트 인스턴스 병합 */
const handleBulkIndicatorApply = useCallback((result: {
chartIndicators: IndicatorConfig[];
@@ -1511,7 +1551,7 @@ function App() {
}, [layoutDef.count, activeSlot]);
const handleRemoveIndicatorById = useCallback((id: string) => {
setIndicators(prev => prev.filter(i => i.id !== id));
setIndicators(prev => removeIndicatorFromList(prev, id));
setFocusedIndicatorId(prev => prev === id ? null : prev);
setCtxToolbar(null);
setSettingsModalId(null);
@@ -2038,6 +2078,7 @@ function App() {
chartRealtimeSource={chartRealtimeSource as 'BACKEND_STOMP' | 'UPBIT_DIRECT'}
displayTimezone={displayTimezone}
compactMode
chartVisible={chartVisible}
/>
</div>
{/* 슬롯 1~7 */}
@@ -2075,6 +2116,7 @@ function App() {
chartRealtimeSource={chartRealtimeSource as 'BACKEND_STOMP' | 'UPBIT_DIRECT'}
displayTimezone={displayTimezone}
compactMode
chartVisible={chartVisible}
/>
</div>
))}
@@ -2114,6 +2156,7 @@ function App() {
<TradingChart
key={chartMountKey}
chartVisible={chartVisible}
bars={bars} barsMarket={barsMarket} market={symbol} timeframe={timeframe} displayTimezone={displayTimezone}
chartType={chartType} theme={theme} mode={mode}
indicators={effectiveIndicators} drawingTool={drawingTool}