일목균형표 구름 미표시 수정: cloudPlugin을 mainSeries에 부착
서버에서 일목균형표 구름이 표시되지 않는 근본 원인 수정. LWC의 ISeriesPrimitive는 부착된 시리즈가 visible:false이거나 priceScale 문제가 있으면 렌더링되지 않을 수 있음. 수정: - cloudPlugin 부착 대상을 SpanA(plot3) → mainSeries로 변경 mainSeries는 항상 visible:true이고 메인 priceScale을 사용하므로 어떤 DB 설정 값에 관계없이 구름이 확실히 렌더링됨 - clearForSymbolChange/setData/reloadIndicatorsOnly/_detachIndicatorEntry에서 mainSeries로부터의 cloudPlugin detach 처리 추가 - applyIndicatorStyle에서 ichimokuCloudHost 특수 처리 제거 (더이상 불필요) Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -348,6 +348,7 @@ export class ChartManager {
|
|||||||
|
|
||||||
for (const entry of this.indicators.values()) {
|
for (const entry of this.indicators.values()) {
|
||||||
if (entry.cloudPlugin) {
|
if (entry.cloudPlugin) {
|
||||||
|
try { this.mainSeries?.detachPrimitive(entry.cloudPlugin); } catch { /* ok */ }
|
||||||
for (const s of entry.seriesList) { try { s.detachPrimitive(entry.cloudPlugin); } catch { /* ok */ } }
|
for (const s of entry.seriesList) { try { s.detachPrimitive(entry.cloudPlugin); } catch { /* ok */ } }
|
||||||
}
|
}
|
||||||
detachBbBandFill(entry);
|
detachBbBandFill(entry);
|
||||||
@@ -377,6 +378,7 @@ export class ChartManager {
|
|||||||
// 기존 보조지표 시리즈를 모두 제거 (새 데이터로 재계산하기 위해)
|
// 기존 보조지표 시리즈를 모두 제거 (새 데이터로 재계산하기 위해)
|
||||||
for (const entry of this.indicators.values()) {
|
for (const entry of this.indicators.values()) {
|
||||||
if (entry.cloudPlugin) {
|
if (entry.cloudPlugin) {
|
||||||
|
try { this.mainSeries?.detachPrimitive(entry.cloudPlugin); } catch { /* ok */ }
|
||||||
for (const s of entry.seriesList) { try { s.detachPrimitive(entry.cloudPlugin); } catch { /* ok */ } }
|
for (const s of entry.seriesList) { try { s.detachPrimitive(entry.cloudPlugin); } catch { /* ok */ } }
|
||||||
}
|
}
|
||||||
detachBbBandFill(entry);
|
detachBbBandFill(entry);
|
||||||
@@ -867,6 +869,7 @@ export class ChartManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (entry.cloudPlugin) {
|
if (entry.cloudPlugin) {
|
||||||
|
try { this.mainSeries?.detachPrimitive(entry.cloudPlugin); } catch { /* ok */ }
|
||||||
for (const s of entry.seriesList) {
|
for (const s of entry.seriesList) {
|
||||||
try { s.detachPrimitive(entry.cloudPlugin); } catch { /* ok */ }
|
try { s.detachPrimitive(entry.cloudPlugin); } catch { /* ok */ }
|
||||||
}
|
}
|
||||||
@@ -891,6 +894,7 @@ export class ChartManager {
|
|||||||
// ① 기존 보조지표 시리즈 모두 제거 (메인·볼륨 제외)
|
// ① 기존 보조지표 시리즈 모두 제거 (메인·볼륨 제외)
|
||||||
for (const entry of this.indicators.values()) {
|
for (const entry of this.indicators.values()) {
|
||||||
if (entry.cloudPlugin) {
|
if (entry.cloudPlugin) {
|
||||||
|
try { this.mainSeries?.detachPrimitive(entry.cloudPlugin); } catch { /* ok */ }
|
||||||
for (const s of entry.seriesList) { try { s.detachPrimitive(entry.cloudPlugin); } catch { /* ok */ } }
|
for (const s of entry.seriesList) { try { s.detachPrimitive(entry.cloudPlugin); } catch { /* ok */ } }
|
||||||
}
|
}
|
||||||
if (entry.fillPrimitive && entry.seriesList[0]) {
|
if (entry.fillPrimitive && entry.seriesList[0]) {
|
||||||
@@ -1306,12 +1310,15 @@ export class ChartManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 구름 플러그인 (과거 + 미래 포함)
|
// 구름 플러그인 (과거 + 미래 포함)
|
||||||
|
// mainSeries 에 attach: mainSeries 는 항상 visible:true 이고 메인 priceScale 을 사용하므로
|
||||||
|
// primitive 가 확실하게 렌더링된다. SpanA(plot3) 시리즈의 visibility/priceScale 변화에
|
||||||
|
// 영향을 받지 않도록 mainSeries 우선, 없으면 SpanA→첫 번째 시리즈 순으로 fallback.
|
||||||
const cloudPlugin = new IchimokuCloudPlugin();
|
const cloudPlugin = new IchimokuCloudPlugin();
|
||||||
const colors = resolveIchimokuCloudColors(_config.cloudColors);
|
const colors = resolveIchimokuCloudColors(_config.cloudColors);
|
||||||
cloudPlugin.setColors(colors.bullishColor, colors.bearishColor);
|
cloudPlugin.setColors(colors.bullishColor, colors.bearishColor);
|
||||||
const host = spanASeriesRef ?? seriesList[0];
|
const cloudHost = this.mainSeries ?? spanASeriesRef ?? seriesList[0] ?? null;
|
||||||
if (host) {
|
if (cloudHost) {
|
||||||
host.attachPrimitive(cloudPlugin);
|
cloudHost.attachPrimitive(cloudPlugin);
|
||||||
this._applyIchimokuCloudPlugin(cloudPlugin, result.plots, _config);
|
this._applyIchimokuCloudPlugin(cloudPlugin, result.plots, _config);
|
||||||
}
|
}
|
||||||
return { cloudPlugin, seriesMeta };
|
return { cloudPlugin, seriesMeta };
|
||||||
@@ -2437,16 +2444,6 @@ export class ChartManager {
|
|||||||
|
|
||||||
const plotById = Object.fromEntries(plotDefs.map((p: PlotDef) => [p.id, p]));
|
const plotById = Object.fromEntries(plotDefs.map((p: PlotDef) => [p.id, p]));
|
||||||
|
|
||||||
// 일목균형표: 구름 플러그인이 붙은 호스트 시리즈(plot3 우선, 없으면 seriesList[0]) 식별
|
|
||||||
// LWC는 visible:false 시리즈에 붙은 primitive를 렌더링하지 않으므로
|
|
||||||
// 호스트 시리즈는 항상 visible:true 로 유지하고, 사용자가 라인을 숨길 경우
|
|
||||||
// 투명 색상으로 처리한다.
|
|
||||||
const ichimokuCloudHost: ISeriesApi<SeriesType> | null = (() => {
|
|
||||||
if (entry.type !== 'IchimokuCloud' || !entry.cloudPlugin) return null;
|
|
||||||
const plot3Idx = entry.seriesMeta.findIndex(m => m.plotId === 'plot3');
|
|
||||||
return plot3Idx >= 0 ? entry.seriesList[plot3Idx] : (entry.seriesList[0] ?? null);
|
|
||||||
})();
|
|
||||||
|
|
||||||
entry.seriesList.forEach((series, i) => {
|
entry.seriesList.forEach((series, i) => {
|
||||||
let plot: PlotDef | undefined;
|
let plot: PlotDef | undefined;
|
||||||
const pid = entry.seriesMeta[i]?.plotId;
|
const pid = entry.seriesMeta[i]?.plotId;
|
||||||
@@ -2456,19 +2453,16 @@ export class ChartManager {
|
|||||||
const visible = indicatorVisible && config.plotVisibility?.[plot.id] !== false;
|
const visible = indicatorVisible && config.plotVisibility?.[plot.id] !== false;
|
||||||
const paneIdx = entry.paneIndex ?? 0;
|
const paneIdx = entry.paneIndex ?? 0;
|
||||||
const indicatorPriceFormat = priceFormatForIndicatorPane(paneIdx);
|
const indicatorPriceFormat = priceFormatForIndicatorPane(paneIdx);
|
||||||
const isCloudHost = series === ichimokuCloudHost;
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
const opts: Record<string, unknown> = {
|
const opts: Record<string, unknown> = {
|
||||||
// 구름 호스트 시리즈: 지표 전체가 hidden 일 때만 실제로 visible:false
|
visible,
|
||||||
visible: isCloudHost ? indicatorVisible : visible,
|
|
||||||
};
|
};
|
||||||
if (indicatorPriceFormat) {
|
if (indicatorPriceFormat) {
|
||||||
opts['priceFormat'] = indicatorPriceFormat;
|
opts['priceFormat'] = indicatorPriceFormat;
|
||||||
}
|
}
|
||||||
if (!entry.seriesMeta[i]?.isHistogram) {
|
if (!entry.seriesMeta[i]?.isHistogram) {
|
||||||
// 구름 호스트 시리즈가 사용자에 의해 숨겨진 경우 → 라인을 투명 처리
|
opts['color'] = plot.color ?? '#aaa';
|
||||||
opts['color'] = (isCloudHost && !visible) ? 'rgba(0,0,0,0)' : (plot.color ?? '#aaa');
|
|
||||||
if (plot.lineWidth != null) opts['lineWidth'] = plot.lineWidth;
|
if (plot.lineWidth != null) opts['lineWidth'] = plot.lineWidth;
|
||||||
opts['lineStyle'] = plotSeriesLineStyle(plot.lineStyle);
|
opts['lineStyle'] = plotSeriesLineStyle(plot.lineStyle);
|
||||||
let plotAllows = true;
|
let plotAllows = true;
|
||||||
|
|||||||
Reference in New Issue
Block a user