obv 추가수정
This commit is contained in:
@@ -808,17 +808,27 @@ export class ChartManager {
|
||||
}
|
||||
}
|
||||
|
||||
/** 스타일 갱신·초기 추가 후 OBV 등 본선(plot0) 시리즈 누락 보정 + 전체 setData */
|
||||
private async _ensureDualLinePlotSeriesForEntry(entry: IndicatorEntry): Promise<void> {
|
||||
if (!DUAL_LINE_INDICATOR_TYPES.has(entry.type)) return;
|
||||
const config = enrichIndicatorConfig(entry.config!);
|
||||
const def = getIndicatorDef(config.type);
|
||||
if (!def) return;
|
||||
if (this._dualLineMissingPlotIds(entry, config, def).length === 0) return;
|
||||
/** plot0·plot1 시리즈 전부 제거 후 DB 설정 스타일로 재생성 */
|
||||
private async _rebuildDualLinePlotSeriesForEntry(
|
||||
entry: IndicatorEntry,
|
||||
config: IndicatorConfig,
|
||||
def: NonNullable<ReturnType<typeof getIndicatorDef>>,
|
||||
): Promise<void> {
|
||||
if (this.rawBars.length === 0) return;
|
||||
|
||||
const pane = entry.paneIndex ?? this._readSeriesPaneIndex(entry.seriesList[0]) ?? 2;
|
||||
const indicatorHidden = !this._isIndicatorEffectivelyVisible(config);
|
||||
|
||||
for (const pl of entry.hlineRefs) {
|
||||
try { entry.seriesList[0]?.removePriceLine(pl); } catch { /* ok */ }
|
||||
}
|
||||
entry.hlineRefs = [];
|
||||
for (const s of entry.seriesList) {
|
||||
try { this.chart.removeSeries(s); } catch { /* ok */ }
|
||||
}
|
||||
entry.seriesList = [];
|
||||
entry.seriesMeta = [];
|
||||
|
||||
try {
|
||||
const result = await calculateIndicator(config.type, this.rawBars.slice(), config.params);
|
||||
this._appendMissingPlotSeriesToLists(
|
||||
@@ -838,6 +848,30 @@ export class ChartManager {
|
||||
const actualPane = this._readSeriesPaneIndex(entry.seriesList[0]);
|
||||
if (actualPane >= 2) entry.paneIndex = actualPane;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(`[Indicator] ${config.type} dual-line rebuild error:`, e);
|
||||
}
|
||||
}
|
||||
|
||||
/** 스타일 갱신·초기 추가 후 OBV 등 본선(plot0) 시리즈 누락 보정 + 전체 setData */
|
||||
private async _ensureDualLinePlotSeriesForEntry(entry: IndicatorEntry): Promise<void> {
|
||||
if (!DUAL_LINE_INDICATOR_TYPES.has(entry.type)) return;
|
||||
const config = enrichIndicatorConfig(entry.config!);
|
||||
const def = getIndicatorDef(config.type);
|
||||
if (!def) return;
|
||||
if (this.rawBars.length === 0) return;
|
||||
|
||||
const missing = this._dualLineMissingPlotIds(entry, config, def);
|
||||
if (missing.length > 0) {
|
||||
await this._rebuildDualLinePlotSeriesForEntry(entry, config, def);
|
||||
return;
|
||||
}
|
||||
|
||||
if (entry.seriesList.length === 0) return;
|
||||
try {
|
||||
const result = await calculateIndicator(config.type, this.rawBars.slice(), config.params);
|
||||
this._setIndicatorPlotsFullData(entry, result.plots as Record<string, PlotData>, config);
|
||||
entry.config = config;
|
||||
} catch (e) {
|
||||
console.error(`[Indicator] ${config.type} dual-line repair error:`, e);
|
||||
}
|
||||
@@ -1063,20 +1097,26 @@ export class ChartManager {
|
||||
this._notifyPaneLayout();
|
||||
}
|
||||
|
||||
/** OBV·RSI 등 본선(plot0) 시리즈 누락 시 재생성 + 전체 plot setData */
|
||||
/** OBV·RSI 등 본선(plot0) 시리즈 누락 시 재생성 + 전체 plot setData + 스타일(DB) 반영 */
|
||||
async repairDualLineSeries(): Promise<void> {
|
||||
for (const entry of this.indicators.values()) {
|
||||
if (!DUAL_LINE_INDICATOR_TYPES.has(entry.type) || !entry.config) continue;
|
||||
await this._ensureDualLinePlotSeriesForEntry(entry);
|
||||
if (entry.seriesList.length === 0 || this.rawBars.length === 0) continue;
|
||||
try {
|
||||
const config = enrichIndicatorConfig(entry.config);
|
||||
const result = await calculateIndicator(
|
||||
config.type, this.rawBars.slice(), config.params ?? {},
|
||||
);
|
||||
this._setIndicatorPlotsFullData(entry, result.plots as Record<string, PlotData>, config);
|
||||
this.applyIndicatorStyle(config);
|
||||
} catch { /* ok */ }
|
||||
const config = enrichIndicatorConfig(entry.config);
|
||||
const def = getIndicatorDef(entry.type);
|
||||
if (!def) continue;
|
||||
|
||||
const missing = this._dualLineMissingPlotIds(entry, config, def);
|
||||
if (missing.length > 0) {
|
||||
await this._rebuildDualLinePlotSeriesForEntry(entry, config, def);
|
||||
} else if (entry.seriesList.length > 0 && this.rawBars.length > 0) {
|
||||
try {
|
||||
const result = await calculateIndicator(
|
||||
config.type, this.rawBars.slice(), config.params ?? {},
|
||||
);
|
||||
this._setIndicatorPlotsFullData(entry, result.plots as Record<string, PlotData>, config);
|
||||
} catch { /* ok */ }
|
||||
}
|
||||
this.applyIndicatorStyle(config);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2902,7 +2942,7 @@ export class ChartManager {
|
||||
* 인디케이터의 스타일(색상·선폭·plotVisibility)을 in-place 로 일괄 적용.
|
||||
* 시리즈를 제거·재생성하지 않으므로 pane 재번호 문제가 없음.
|
||||
*/
|
||||
applyIndicatorStyle(config: IndicatorConfig): void {
|
||||
applyIndicatorStyle(config: IndicatorConfig, options?: { skipDualLineRefresh?: boolean }): void {
|
||||
config = enrichIndicatorConfig(config);
|
||||
const entry = this.indicators.get(config.id);
|
||||
if (!entry) return;
|
||||
@@ -3035,8 +3075,12 @@ export class ChartManager {
|
||||
void this._repaintHistogramSeries(config.id, config);
|
||||
}
|
||||
|
||||
if (DUAL_LINE_INDICATOR_TYPES.has(config.type)) {
|
||||
void this._ensureDualLinePlotSeriesForEntry(entry);
|
||||
if (DUAL_LINE_INDICATOR_TYPES.has(config.type) && !options?.skipDualLineRefresh) {
|
||||
void this._ensureDualLinePlotSeriesForEntry(entry).then(() => {
|
||||
if (entry.config) {
|
||||
this.applyIndicatorStyle(enrichIndicatorConfig(entry.config), { skipDualLineRefresh: true });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (this._candleOnlyLayout && this._isSubPaneIndicator(entry)) {
|
||||
|
||||
@@ -453,6 +453,7 @@ function normalizeDualLinePlotDef(saved: PlotDef, reg: PlotDef): PlotDef {
|
||||
title: reg.title,
|
||||
type: 'line',
|
||||
lineWidth: Math.max(1, saved.lineWidth ?? reg.lineWidth ?? 1),
|
||||
lineStyle: saved.lineStyle ?? reg.lineStyle ?? 'solid',
|
||||
color: resolvePlotLineColor(saved.color, reg.color),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -64,10 +64,15 @@ export function initializeIndicatorConfigForEditor(
|
||||
: { ...raw.params };
|
||||
const visual = getVisualConfig?.(raw.type, def.plots, def.hlines);
|
||||
|
||||
const mergedPlots = mergePlotDefs(
|
||||
raw.plots?.length ? raw.plots : undefined,
|
||||
mergePlotDefs(visual?.plots, def.plots),
|
||||
);
|
||||
|
||||
return enrichIndicatorConfig({
|
||||
...raw,
|
||||
params,
|
||||
plots: raw.plots?.length ? raw.plots : visual?.plots,
|
||||
plots: mergedPlots,
|
||||
hlines: raw.hlines?.length ? raw.hlines : visual?.hlines,
|
||||
cloudColors: raw.cloudColors ?? visual?.cloudColors,
|
||||
bandBackground: raw.bandBackground ?? visual?.bandBackground,
|
||||
|
||||
Reference in New Issue
Block a user