전략편집기 복합지표 기능 반영
This commit is contained in:
@@ -210,6 +210,9 @@ export class ChartManager {
|
||||
/** 차트 하단 거래량 pane 표시 */
|
||||
private _volumeVisible = true;
|
||||
|
||||
/** applyPaneLayout / resetPaneHeights 에서 측정한 마지막 가용 높이(px) */
|
||||
private _lastLayoutAvailableHeight?: number;
|
||||
|
||||
constructor(container: HTMLElement, theme: Theme) {
|
||||
this.container = container;
|
||||
const t = getTheme(theme);
|
||||
@@ -221,6 +224,7 @@ export class ChartManager {
|
||||
background: { type: ColorType.Solid, color: t.bgColor },
|
||||
textColor: t.textColor,
|
||||
fontSize: 12,
|
||||
panes: { enableResize: false },
|
||||
},
|
||||
grid: {
|
||||
vertLines: { color: t.gridColor },
|
||||
@@ -288,6 +292,7 @@ export class ChartManager {
|
||||
}
|
||||
this.indicators.clear();
|
||||
this.patternMarkers = [];
|
||||
this._removeExtraSubPanes();
|
||||
|
||||
this._disposeMainMarkersPlugin();
|
||||
if (this.mainSeries) { try { this.chart.removeSeries(this.mainSeries); } catch { /* ok */ } this.mainSeries = null; }
|
||||
@@ -535,6 +540,10 @@ export class ChartManager {
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(`[Indicator] ${config.type} error:`, e);
|
||||
} finally {
|
||||
if (this._activeIndicatorPaneIndices().size > 0) {
|
||||
this.resetPaneHeights(this._lastLayoutAvailableHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -557,6 +566,7 @@ export class ChartManager {
|
||||
this.indicators.clear();
|
||||
this.patternMarkers = this.patternMarkers.filter(() => false);
|
||||
this._reapplyAllPatternMarkers();
|
||||
this._removeExtraSubPanes();
|
||||
|
||||
// ② 새 순서로 재추가 (병합 호스트 → 멤버 순)
|
||||
this._indRunning = false;
|
||||
@@ -590,7 +600,8 @@ export class ChartManager {
|
||||
this.patternMarkers = this.patternMarkers.filter(p => p.id !== id);
|
||||
this._reapplyAllPatternMarkers();
|
||||
this.indicators.delete(id);
|
||||
this.resetPaneHeights();
|
||||
this._removeExtraSubPanes();
|
||||
this.resetPaneHeights(this._lastLayoutAvailableHeight);
|
||||
this._notifyPaneLayout();
|
||||
}
|
||||
|
||||
@@ -1232,6 +1243,7 @@ export class ChartManager {
|
||||
this.indicators.clear();
|
||||
this.patternMarkers = [];
|
||||
this._reapplyAllPatternMarkers();
|
||||
this._removeExtraSubPanes();
|
||||
|
||||
for (const cfg of configs) {
|
||||
await this.addIndicator(cfg);
|
||||
@@ -2047,6 +2059,20 @@ export class ChartManager {
|
||||
return indices;
|
||||
}
|
||||
|
||||
/** pane 2+ 빈 sub-pane 제거 — 제거·재로드 후 고아 pane 이 높이를 나눠 가져가는 것 방지 */
|
||||
private _removeExtraSubPanes(): void {
|
||||
for (;;) {
|
||||
const panes = this.chart.panes();
|
||||
if (panes.length <= 2) return;
|
||||
const last = panes.length - 1;
|
||||
try {
|
||||
this.chart.removePane(last);
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** chart-container 기준 Y(px) → pane index (0=캔들, 1=거래량, 2+=보조지표) */
|
||||
getPaneIndexAtChartY(chartY: number): number {
|
||||
const layouts = this.getPaneLayouts();
|
||||
@@ -2374,6 +2400,16 @@ export class ChartManager {
|
||||
return this.indicators.size;
|
||||
}
|
||||
|
||||
/** 실제 시리즈·구름이 붙은 보조지표 수 (부분 로드·중단 감지용) */
|
||||
getLoadedIndicatorCount(): number {
|
||||
let n = 0;
|
||||
for (const entry of this.indicators.values()) {
|
||||
if (entry.config?.hidden === true) continue;
|
||||
if (entry.cloudPlugin || entry.seriesList.length > 0) n += 1;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
/** 현재 로드된 rawBars 개수 반환 (데이터 로드 여부 확인용) */
|
||||
getRawBarsLength(): number {
|
||||
return this.rawBars.length;
|
||||
@@ -2732,12 +2768,16 @@ export class ChartManager {
|
||||
const N = activeIndPanes.size;
|
||||
const H = (availableHeight && availableHeight > 0)
|
||||
? availableHeight
|
||||
: this.container.clientHeight;
|
||||
: (this._lastLayoutAvailableHeight && this._lastLayoutAvailableHeight > 0
|
||||
? this._lastLayoutAvailableHeight
|
||||
: this.container.clientHeight);
|
||||
|
||||
const volumeShown = this._volumeVisible && !this._candleOnlyLayout;
|
||||
const VOL_FRAC = this._volumeFrac(H);
|
||||
const MIN_IND_PX = 80;
|
||||
const ORPHAN_STRETCH = 0.0001;
|
||||
/** 보조지표 pane 은 동일 stretch weight → 항상 같은 높이 */
|
||||
const IND_EQUAL_WEIGHT = 1;
|
||||
|
||||
const remaining = Math.max(0, 1 - mainFrac - (volumeShown ? VOL_FRAC : 0));
|
||||
const eachIndFrac = N > 0 ? remaining / N : 0;
|
||||
@@ -2746,13 +2786,20 @@ export class ChartManager {
|
||||
? eachIndFrac
|
||||
: MIN_IND_PX / H;
|
||||
|
||||
const indWeight = IND_EQUAL_WEIGHT;
|
||||
const indUnit = Math.max(actualIndFrac, 1e-9);
|
||||
const mainWeight = N > 0 ? mainFrac / indUnit : mainFrac;
|
||||
const volWeight = volumeShown
|
||||
? (N > 0 ? VOL_FRAC / indUnit : VOL_FRAC)
|
||||
: ORPHAN_STRETCH;
|
||||
|
||||
for (let i = 0; i < panes.length; i++) {
|
||||
if (i === 0) {
|
||||
panes[i].setStretchFactor(mainFrac);
|
||||
panes[i].setStretchFactor(mainWeight);
|
||||
} else if (i === 1) {
|
||||
panes[i].setStretchFactor(volumeShown ? VOL_FRAC : ORPHAN_STRETCH);
|
||||
panes[i].setStretchFactor(volumeShown ? volWeight : ORPHAN_STRETCH);
|
||||
} else if (activeIndPanes.has(i)) {
|
||||
panes[i].setStretchFactor(actualIndFrac);
|
||||
panes[i].setStretchFactor(indWeight);
|
||||
} else {
|
||||
panes[i].setStretchFactor(ORPHAN_STRETCH);
|
||||
}
|
||||
@@ -2801,13 +2848,19 @@ export class ChartManager {
|
||||
const panes = this.chart.panes();
|
||||
if (panes.length === 0) return availableHeight ?? this.container.clientHeight;
|
||||
|
||||
if (availableHeight != null && availableHeight > 0) {
|
||||
this._lastLayoutAvailableHeight = availableHeight;
|
||||
}
|
||||
|
||||
if (this._candleOnlyLayout) {
|
||||
return this._resetPaneHeightsCandleFullscreen(availableHeight);
|
||||
}
|
||||
|
||||
const H = (availableHeight && availableHeight > 0)
|
||||
? availableHeight
|
||||
: this.container.clientHeight;
|
||||
: (this._lastLayoutAvailableHeight && this._lastLayoutAvailableHeight > 0
|
||||
? this._lastLayoutAvailableHeight
|
||||
: this.container.clientHeight);
|
||||
const N = this._activeIndicatorPaneIndices().size;
|
||||
const { mainFrac } = this._paneHeightFractions(N, this._volumeFrac(H));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user