수정1
This commit is contained in:
@@ -103,26 +103,6 @@ const TradeSignalMiniChart: React.FC<Props> = ({
|
||||
applyNotificationSignalMarkers(mgr, signalMarkerRef.current, false);
|
||||
}, []);
|
||||
|
||||
/** OBV plot0(본선) 누락 시 refreshIndicators 로 강제 재생성 */
|
||||
const ensureObvDualLine = useCallback(async (attempt = 0) => {
|
||||
const mgr = managerRef.current;
|
||||
if (!mgr?.hasMainSeries() || !needsDeepObv) return;
|
||||
const obvCfg = chartIndicators.find(i => i.type === 'OBV');
|
||||
if (!obvCfg) return;
|
||||
|
||||
await mgr.repairDualLineSeries();
|
||||
const plotIds = mgr.getIndicatorSeriesPlotIds(obvCfg.id);
|
||||
const needsBoth = plotIds.length < 2 || !plotIds.includes('plot0');
|
||||
if (needsBoth && attempt < 4) {
|
||||
await mgr.refreshIndicators([obvCfg]);
|
||||
await mgr.repairDualLineSeries();
|
||||
const after = mgr.getIndicatorSeriesPlotIds(obvCfg.id);
|
||||
if ((after.length < 2 || !after.includes('plot0')) && attempt < 3) {
|
||||
setTimeout(() => void ensureObvDualLine(attempt + 1), 500 * (attempt + 1));
|
||||
}
|
||||
}
|
||||
}, [needsDeepObv, chartIndicators]);
|
||||
|
||||
const syncChartLayout = useCallback(() => {
|
||||
const wrap = canvasWrapRef.current;
|
||||
const mgr = managerRef.current;
|
||||
@@ -144,24 +124,13 @@ const TradeSignalMiniChart: React.FC<Props> = ({
|
||||
}
|
||||
syncChartLayout();
|
||||
applySignalMarkers();
|
||||
if (!mgr) return;
|
||||
void ensureObvDualLine();
|
||||
[0, 100, 500, 1200].forEach(delay => {
|
||||
setTimeout(() => {
|
||||
void managerRef.current?.repairDualLineSeries();
|
||||
void ensureObvDualLine();
|
||||
}, delay);
|
||||
});
|
||||
}, [syncChartLayout, applySignalMarkers, ensureObvDualLine]);
|
||||
}, [syncChartLayout, applySignalMarkers]);
|
||||
|
||||
const handleManagerReady = useCallback((mgr: ChartManager) => {
|
||||
managerRef.current = mgr;
|
||||
syncToManager(mgr);
|
||||
applySignalMarkers();
|
||||
if (needsDeepObv) {
|
||||
void mgr.repairDualLineSeries().then(() => ensureObvDualLine());
|
||||
}
|
||||
}, [syncToManager, applySignalMarkers, needsDeepObv, ensureObvDualLine]);
|
||||
}, [syncToManager, applySignalMarkers]);
|
||||
|
||||
const applyRealtimeBar = useCallback((bar: OHLCVBar, append: boolean) => {
|
||||
if (barsMarketRef.current !== marketRef.current) return;
|
||||
@@ -216,19 +185,6 @@ const TradeSignalMiniChart: React.FC<Props> = ({
|
||||
|
||||
const chartDataReady = barsReady && obvBarsReady && settingsLoaded;
|
||||
|
||||
useEffect(() => {
|
||||
if (!enabled || !chartDataReady) return;
|
||||
const mgr = managerRef.current;
|
||||
if (!mgr?.hasMainSeries()) return;
|
||||
const timers = [200, 800, 1600].map(delay =>
|
||||
setTimeout(() => {
|
||||
void mgr.repairDualLineSeries();
|
||||
void ensureObvDualLine();
|
||||
}, delay),
|
||||
);
|
||||
return () => timers.forEach(clearTimeout);
|
||||
}, [enabled, chartDataReady, chartIndicators, market, timeframe, settingsRevision, ensureObvDualLine]);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
chartLiveReadyRef.current = false;
|
||||
pendingBarRef.current = null;
|
||||
|
||||
@@ -753,7 +753,7 @@ export class ChartManager {
|
||||
config: IndicatorConfig,
|
||||
def: ReturnType<typeof getIndicatorDef> | undefined,
|
||||
): string[] {
|
||||
const plotDefs = config.plots ?? def?.plots ?? [];
|
||||
const plotDefs = def?.plots ?? config.plots ?? [];
|
||||
return plotDefs
|
||||
.filter(p => p.type !== 'histogram' && config.plotVisibility?.[p.id] !== false)
|
||||
.map(p => p.id);
|
||||
@@ -783,8 +783,11 @@ export class ChartManager {
|
||||
indicatorHidden: boolean,
|
||||
def: ReturnType<typeof getIndicatorDef>,
|
||||
): void {
|
||||
const plotDefs = sortDualLinePlotDefs(config.plots ?? def?.plots ?? [])
|
||||
.filter(p => p.type !== 'histogram' && config.plotVisibility?.[p.id] !== false);
|
||||
const regPlots = def?.plots ?? [];
|
||||
const styleById = Object.fromEntries((config.plots ?? regPlots).map(p => [p.id, p]));
|
||||
const plotDefs = sortDualLinePlotDefs(regPlots)
|
||||
.filter(p => p.type !== 'histogram' && config.plotVisibility?.[p.id] !== false)
|
||||
.map(p => ({ ...p, ...styleById[p.id], id: p.id, title: p.title }));
|
||||
const indicatorPriceFormat = priceFormatForIndicatorPane(pane);
|
||||
|
||||
for (const plotDef of plotDefs) {
|
||||
@@ -1092,7 +1095,7 @@ export class ChartManager {
|
||||
this._setIndicatorPlotsFullData(entry, result.plots as Record<string, PlotData>, config);
|
||||
}
|
||||
}
|
||||
this.applyIndicatorStyle(config);
|
||||
this.applyIndicatorStyle(config, { skipDualLineRefresh: true });
|
||||
if (config.type === 'BollingerBands' && !indicatorHidden) {
|
||||
attachBbBandFill(entry, config, this._shouldShowBbBandFillForConfig(config));
|
||||
entry.bbFillPrimitive?.requestRefresh();
|
||||
@@ -1165,7 +1168,7 @@ export class ChartManager {
|
||||
this._setIndicatorPlotsFullData(entry, result.plots as Record<string, PlotData>, config);
|
||||
} catch { /* ok */ }
|
||||
}
|
||||
this.applyIndicatorStyle(config);
|
||||
this.applyIndicatorStyle(config, { skipDualLineRefresh: true });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1282,7 +1285,8 @@ export class ChartManager {
|
||||
async refreshIndicators(configs: IndicatorConfig[]): Promise<void> {
|
||||
if (configs.length === 0) return;
|
||||
this.cancelPendingIndicatorUpdates();
|
||||
const loadGen = ++this._dataGeneration;
|
||||
/** setData 와 달리 generation 을 올리지 않음 — 배치 add 중 다른 지표 로드를 끊지 않음 */
|
||||
const loadGen = this._dataGeneration;
|
||||
|
||||
let any = false;
|
||||
for (const c of configs) {
|
||||
|
||||
Reference in New Issue
Block a user