캔들차트, 이동평균선, 일목균형표, 볼린저밴드 보이기 숨기기 기능적용

This commit is contained in:
Macbook
2026-06-03 00:19:44 +09:00
parent 08fb442d4a
commit 76e5b12d19
15 changed files with 427 additions and 69 deletions
+46 -1
View File
@@ -44,6 +44,13 @@ import {
replaceIndicatorConfigsFromTypes,
} from '../utils/indicatorPaneMerge';
import { sortIndicatorsByTypeOrder } from '../utils/indicatorListOrder';
import {
type ChartOverlayToggleKey,
type ChartOverlayVisibility,
chartOverlayKeyForType,
DEFAULT_CHART_OVERLAY_VISIBILITY,
listChartOverlayToggleItems,
} from '../utils/chartOverlayVisibility';
import { saveSlot } from '../utils/backendApi';
import type {
OHLCVBar, ChartType, Theme, Timeframe,
@@ -192,6 +199,8 @@ export interface ChartSlotProps {
chartPaneSeparator?: ChartPaneSeparatorOptions;
/** 크로스헤어 이동 시 OHLC·보조지표 수치 표시 */
chartCrosshairInfoVisible?: boolean;
/** 차트 마우스오버 줌·이동 플로팅 툴바 */
chartHoverToolbarVisible?: boolean;
/** 업비트 실시간 티커 맵 (슬롯 심볼별 현재가·등락) */
marketTickers?: Map<string, TickerData>;
}
@@ -220,6 +229,7 @@ const ChartSlot = forwardRef<ChartSlotHandle, ChartSlotProps>(function ChartSlot
chartVisible = true,
chartPaneSeparator,
chartCrosshairInfoVisible = true,
chartHoverToolbarVisible = true,
marketTickers,
}, ref) {
// ── 전역 지표 파라미터 + 시각 설정 (DB 동기화) ────────────────────────
@@ -649,6 +659,37 @@ const ChartSlot = forwardRef<ChartSlotHandle, ChartSlotProps>(function ChartSlot
setFocusedIndicatorId(null);
}, []);
const [overlayVisibility, setOverlayVisibility] = useState<ChartOverlayVisibility>(
() => ({ ...DEFAULT_CHART_OVERLAY_VISIBILITY }),
);
const overlayVisibilityRef = useRef(overlayVisibility);
useEffect(() => {
overlayVisibilityRef.current = overlayVisibility;
}, [overlayVisibility]);
const candleOverlayToggles = useMemo(
() => listChartOverlayToggleItems(overlayVisibility),
[overlayVisibility],
);
const handleToggleCandleOverlay = useCallback((key: ChartOverlayToggleKey) => {
setOverlayVisibility(prev => {
const next = { ...prev, [key]: !prev[key] };
const mgr = managerRef.current;
mgr?.setChartOverlayGroupVisible(key, next[key]);
if (mgr) {
for (const info of mgr.getIndicatorPaneInfo()) {
if (chartOverlayKeyForType(info.type) !== key) continue;
const reactInd = indicatorsRef.current.find(i => i.id === info.id);
mgr.applyIndicatorStyle(reactInd
? { ...info.config, ...reactInd, id: info.id, type: info.type }
: info.config);
}
}
return next;
});
}, []);
const handleDuplicateIndicator = useCallback((sourceId: string) => {
setIndicators(prev => duplicateIndicatorInList(sourceId, prev, newIndId) ?? prev);
}, []);
@@ -869,7 +910,7 @@ const ChartSlot = forwardRef<ChartSlotHandle, ChartSlotProps>(function ChartSlot
logScale={false}
drawingsLocked={compactMode}
drawingsVisible={!compactMode}
showHoverToolbar={!compactMode}
showHoverToolbar={!compactMode && chartHoverToolbarVisible}
volumeVisible={chartVolumeVisible}
candleAreaPriceLabelsEnabled={chartCandleAreaPriceLabels}
indicatorAreaPriceLabelsEnabled={chartSeriesPriceLabels}
@@ -895,6 +936,7 @@ const ChartSlot = forwardRef<ChartSlotHandle, ChartSlotProps>(function ChartSlot
mgr.setIndicatorAreaPriceLabelsEnabled(chartSeriesPriceLabels);
mgr.setVolumeVisible(chartVolumeVisible);
if (chartPaneSeparator) mgr.setPaneSeparatorOptions(chartPaneSeparator);
mgr.setChartOverlayVisibility(overlayVisibilityRef.current);
// Time sync: 가시 시간 범위 변화 구독
mgr.subscribeVisibleTimeRange(r => {
if (!r || isSyncingTimeRef.current) return;
@@ -919,6 +961,7 @@ const ChartSlot = forwardRef<ChartSlotHandle, ChartSlotProps>(function ChartSlot
// 첫 마운트 시 pending 상태였던 sync range 를 재적용한다
const mgr = managerRef.current;
if (!mgr) return;
mgr.setChartOverlayVisibility(overlayVisibilityRef.current);
if (skipSyncApplyRef.current) {
skipSyncApplyRef.current = false;
const fb = mgr.hasIchimoku() ? 28 : 0;
@@ -971,6 +1014,8 @@ const ChartSlot = forwardRef<ChartSlotHandle, ChartSlotProps>(function ChartSlot
onToggleIndicatorHidden={handleToggleHidden}
onOpenIndicatorSettings={id => setSettingsModalId(id)}
onFullView={onFullView ? () => onFullView(symbolRef.current) : undefined}
candleOverlayToggles={compactMode ? undefined : candleOverlayToggles}
onToggleCandleOverlay={compactMode ? undefined : handleToggleCandleOverlay}
/>
{/* 컨텍스트 툴바 */}