크로스헤어 수정
This commit is contained in:
@@ -164,10 +164,6 @@ interface IndicatorEntry {
|
|||||||
bbFillPrimitive?: BollingerBandFillPrimitive;
|
bbFillPrimitive?: BollingerBandFillPrimitive;
|
||||||
config: IndicatorConfig;
|
config: IndicatorConfig;
|
||||||
cloudPlugin?: IchimokuCloudPlugin; // 일목균형표 구름 플러그인
|
cloudPlugin?: IchimokuCloudPlugin; // 일목균형표 구름 플러그인
|
||||||
/** pane 'right' 축 오염 방지용 전용 priceScaleId (OBV 제외 서브 pane 지표) */
|
|
||||||
isolatedScaleId?: string;
|
|
||||||
/** isolatedScale autoscaleInfoProvider 초기 min/max */
|
|
||||||
plotAutoscaleBounds?: { min: number; max: number };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface AlertEntry { price: number; label: string; line: IPriceLine; }
|
interface AlertEntry { price: number; label: string; line: IPriceLine; }
|
||||||
@@ -1022,7 +1018,7 @@ export class ChartManager {
|
|||||||
pane: number,
|
pane: number,
|
||||||
indicatorHidden: boolean,
|
indicatorHidden: boolean,
|
||||||
def: ReturnType<typeof getIndicatorDef>,
|
def: ReturnType<typeof getIndicatorDef>,
|
||||||
scaleOpts: ReturnType<ChartManager['_isolatedScaleSeriesOptions']> = null,
|
scaleOpts: ReturnType<ChartManager['_autoscaleSeriesOptions']> = null,
|
||||||
): void {
|
): void {
|
||||||
const plotDefs = this._dualLinePlotDefsForRender(config, def);
|
const plotDefs = this._dualLinePlotDefsForRender(config, def);
|
||||||
const indicatorPriceFormat = priceFormatForIndicatorSeries(def);
|
const indicatorPriceFormat = priceFormatForIndicatorSeries(def);
|
||||||
@@ -1222,7 +1218,7 @@ export class ChartManager {
|
|||||||
|
|
||||||
const plotDefsRaw = config.plots ?? def?.plots ?? [];
|
const plotDefsRaw = config.plots ?? def?.plots ?? [];
|
||||||
const plotRange = this._computePlotsValueRange(result.plots as Record<string, PlotData>);
|
const plotRange = this._computePlotsValueRange(result.plots as Record<string, PlotData>);
|
||||||
const scaleOpts = this._isolatedScaleSeriesOptions(config, plotRange);
|
const scaleOpts = this._autoscaleSeriesOptions(config, plotRange);
|
||||||
const indicatorPriceFormat = priceFormatForIndicatorSeries(def);
|
const indicatorPriceFormat = priceFormatForIndicatorSeries(def);
|
||||||
|
|
||||||
if (config.type === 'OBV') {
|
if (config.type === 'OBV') {
|
||||||
@@ -1350,15 +1346,10 @@ export class ChartManager {
|
|||||||
const entry: IndicatorEntry = {
|
const entry: IndicatorEntry = {
|
||||||
id: config.id, type: config.type, seriesList, seriesMeta,
|
id: config.id, type: config.type, seriesList, seriesMeta,
|
||||||
paneIndex: pane, alertLines: [], hlineRefs, fillPrimitive, config,
|
paneIndex: pane, alertLines: [], hlineRefs, fillPrimitive, config,
|
||||||
isolatedScaleId: scaleOpts?.priceScaleId,
|
|
||||||
plotAutoscaleBounds: plotRange ?? undefined,
|
|
||||||
};
|
};
|
||||||
const actualPane = this._readSeriesPaneIndex(seriesList[0]);
|
const actualPane = this._readSeriesPaneIndex(seriesList[0]);
|
||||||
const minSub = this._minIndicatorSubPane();
|
const minSub = this._minIndicatorSubPane();
|
||||||
if (actualPane >= minSub) entry.paneIndex = actualPane;
|
if (actualPane >= minSub) entry.paneIndex = actualPane;
|
||||||
if (entry.isolatedScaleId != null && entry.paneIndex != null && entry.paneIndex >= minSub) {
|
|
||||||
this._applyIsolatedScalePaneOptions(entry.isolatedScaleId, entry.paneIndex);
|
|
||||||
}
|
|
||||||
if (this._indicatorLoadStale(dataGenAtStart) || this.indicators.has(config.id)) {
|
if (this._indicatorLoadStale(dataGenAtStart) || this.indicators.has(config.id)) {
|
||||||
this._discardIndicatorSeries(seriesList, { fillPrimitive });
|
this._discardIndicatorSeries(seriesList, { fillPrimitive });
|
||||||
return;
|
return;
|
||||||
@@ -2226,11 +2217,7 @@ export class ChartManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _indicatorScaleId(configId: string): string {
|
/** plot 데이터 min/max — autoscaleInfoProvider 용 */
|
||||||
return `ind-${configId}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** plot 데이터 min/max — 전용 가격축 autoscale 용 */
|
|
||||||
private _computePlotsValueRange(
|
private _computePlotsValueRange(
|
||||||
plots: Record<string, PlotData>,
|
plots: Record<string, PlotData>,
|
||||||
plotIds?: string[],
|
plotIds?: string[],
|
||||||
@@ -2250,14 +2237,14 @@ export class ChartManager {
|
|||||||
return { min: lo, max: hi };
|
return { min: lo, max: hi };
|
||||||
}
|
}
|
||||||
|
|
||||||
/** OBV 제외 서브 pane 지표 — pane 공유 'right' 축 오염(종가·타 지표 값 혼입) 방지 */
|
/** OBV 제외 서브 pane — pane 기본 'right' 축 + autoscale (overlay priceScaleId 는 UI·크로스헤어 라벨 없음) */
|
||||||
private _usesIsolatedPriceScale(type: string): boolean {
|
private _usesAutoscaleProvider(type: string): boolean {
|
||||||
if (type === 'OBV') return false;
|
if (type === 'OBV') return false;
|
||||||
const def = getIndicatorDef(type);
|
const def = getIndicatorDef(type);
|
||||||
return !!(def && !def.overlay && !def.returnsMarkers);
|
return !!(def && !def.overlay && !def.returnsMarkers);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _makeIsolatedAutoscaleProvider(lo: number, hi: number) {
|
private _makeAutoscaleProvider(lo: number, hi: number) {
|
||||||
return (baseImpl: () => { priceRange: { minValue: number; maxValue: number } } | null) => {
|
return (baseImpl: () => { priceRange: { minValue: number; maxValue: number } } | null) => {
|
||||||
let minV = lo;
|
let minV = lo;
|
||||||
let maxV = hi;
|
let maxV = hi;
|
||||||
@@ -2273,37 +2260,19 @@ export class ChartManager {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private _isolatedScaleSeriesOptions(
|
private _autoscaleSeriesOptions(
|
||||||
config: IndicatorConfig,
|
config: IndicatorConfig,
|
||||||
plotRange: { min: number; max: number } | null,
|
plotRange: { min: number; max: number } | null,
|
||||||
): {
|
): { autoscaleInfoProvider: ReturnType<ChartManager['_makeAutoscaleProvider']> } | null {
|
||||||
priceScaleId: string;
|
if (!this._usesAutoscaleProvider(config.type)) return null;
|
||||||
autoscaleInfoProvider?: ReturnType<ChartManager['_makeIsolatedAutoscaleProvider']>;
|
if (!plotRange || plotRange.max <= plotRange.min) return null;
|
||||||
} | null {
|
|
||||||
if (!this._usesIsolatedPriceScale(config.type)) return null;
|
|
||||||
const scaleId = this._indicatorScaleId(config.id);
|
|
||||||
if (!plotRange || plotRange.max <= plotRange.min) {
|
|
||||||
return { priceScaleId: scaleId };
|
|
||||||
}
|
|
||||||
let { min, max } = plotRange;
|
let { min, max } = plotRange;
|
||||||
const def = getIndicatorDef(config.type);
|
const def = getIndicatorDef(config.type);
|
||||||
if (def?.hlines?.some(h => h.price === 0)) {
|
if (def?.hlines?.some(h => h.price === 0)) {
|
||||||
min = Math.min(min, 0);
|
min = Math.min(min, 0);
|
||||||
max = Math.max(max, 0);
|
max = Math.max(max, 0);
|
||||||
}
|
}
|
||||||
return {
|
return { autoscaleInfoProvider: this._makeAutoscaleProvider(min, max) };
|
||||||
priceScaleId: scaleId,
|
|
||||||
autoscaleInfoProvider: this._makeIsolatedAutoscaleProvider(min, max),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private _applyIsolatedScalePaneOptions(scaleId: string, pane: number): void {
|
|
||||||
try {
|
|
||||||
this.chart.priceScale(scaleId, pane).applyOptions({
|
|
||||||
visible: true,
|
|
||||||
scaleMargins: { top: 0.12, bottom: 0.12 },
|
|
||||||
});
|
|
||||||
} catch { /* ok */ }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 볼륨 pane(1)이 실제로 표시되는지 여부 */
|
/** 볼륨 pane(1)이 실제로 표시되는지 여부 */
|
||||||
@@ -2430,7 +2399,7 @@ export class ChartManager {
|
|||||||
if (!moved && entry.paneIndex === target) continue;
|
if (!moved && entry.paneIndex === target) continue;
|
||||||
entry.paneIndex = target;
|
entry.paneIndex = target;
|
||||||
|
|
||||||
// 통일된 pane 에서 OBV·전용축 지표 옵션 재확정 (이동 중 손실 방지)
|
// 통일된 pane 에서 OBV 전용 축 옵션 재확정 (이동 중 손실 방지)
|
||||||
if (entry.type === 'OBV' && entry.config) {
|
if (entry.type === 'OBV' && entry.config) {
|
||||||
try {
|
try {
|
||||||
this.chart.priceScale(`obv-${entry.config.id}`, target).applyOptions({
|
this.chart.priceScale(`obv-${entry.config.id}`, target).applyOptions({
|
||||||
@@ -2438,8 +2407,6 @@ export class ChartManager {
|
|||||||
scaleMargins: { top: 0.12, bottom: 0.12 },
|
scaleMargins: { top: 0.12, bottom: 0.12 },
|
||||||
});
|
});
|
||||||
} catch { /* ok */ }
|
} catch { /* ok */ }
|
||||||
} else if (entry.isolatedScaleId) {
|
|
||||||
this._applyIsolatedScalePaneOptions(entry.isolatedScaleId, target);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user