실시간 차트 보조지표 값 소수점 표시

This commit is contained in:
Macbook
2026-05-30 10:39:50 +09:00
parent 33c2d4b337
commit c7ba13e7ed
23 changed files with 226 additions and 40 deletions
+61 -15
View File
@@ -245,8 +245,10 @@ export class ChartManager {
/** 현재 크로스헤어가 위에 있는 시리즈의 entryId ('__main__' | indicatorId | null) */
private _crosshairEntryId: string | null = null;
/** 우측 가격축 라벨·plot 설명(전환선 등)·금액 색상 하이라이트 */
private _seriesPriceLabelsEnabled = true;
/** 캔들 pane(0~1) 오버레이 지표 — 우측 가격축 라벨·설명 */
private _candleAreaPriceLabelsEnabled = true;
/** 하단 보조지표 pane(2+) — 우측 가격축 라벨·설명 */
private _indicatorAreaPriceLabelsEnabled = true;
/** 차트 하단 거래량 pane 표시 */
private _volumeVisible = true;
@@ -514,12 +516,31 @@ export class ChartManager {
fmt,
);
this.chart.applyOptions({
localization: { timeFormatter, priceFormatter: formatChartAxisPrice },
localization: { timeFormatter },
timeScale: { tickMarkFormatter: this._tickMarkFormatter() },
});
this._applyAllSeriesPriceFormats();
this._notifyPaneLayout();
}
/** pane별 priceFormat — 전역 priceFormatter 는 보조지표 라벨 포맷을 덮어씀 */
private _applyAllSeriesPriceFormats(): void {
if (this.mainSeries) {
try {
this.mainSeries.applyOptions({ priceFormat: MAIN_PRICE_FORMAT } as Parameters<ISeriesApi<SeriesType>['applyOptions']>[0]);
} catch { /* ok */ }
}
for (const entry of this.indicators.values()) {
const fmt = priceFormatForIndicatorPane(entry.paneIndex ?? 0);
if (!fmt) continue;
for (const series of entry.seriesList) {
try {
series.applyOptions({ priceFormat: fmt } as Parameters<ISeriesApi<SeriesType>['applyOptions']>[0]);
} catch { /* ok */ }
}
}
}
setDisplayTimezone(tz: string, timeframe?: Timeframe, chartTimeFormat?: string): void {
this.displayTimezone = tz || DEFAULT_DISPLAY_TIMEZONE;
if (timeframe) this.displayTimeframe = timeframe;
@@ -688,7 +709,7 @@ export class ChartManager {
seriesMeta.push({ plotId: plotDef.id, isHistogram: true, color: plotDef.color });
} else {
const isPlotVisible = !indicatorHidden && config.plotVisibility?.[plotDef.id] !== false;
const showPriceLabel = this.shouldShowSeriesPriceLabel(config);
const showPriceLabel = this.shouldShowSeriesPriceLabel(config, true, pane);
const showSeriesTitle = pane < 2 && showPriceLabel;
series = this.chart.addSeries(LineSeries, {
color: plotDef.color,
@@ -777,6 +798,7 @@ export class ChartManager {
this._removeOrphanSubPanes();
if (this._activeIndicatorPaneIndices().size > 0) {
this._resyncIndicatorPaneIndices();
this._applyAllSeriesPriceFormats();
} else {
this._trimTrailingEmptySubPanes();
}
@@ -1253,7 +1275,7 @@ export class ChartManager {
);
}
const showPriceLabel = this.shouldShowSeriesPriceLabel(_config, info.lastVal);
const showPriceLabel = this.shouldShowSeriesPriceLabel(_config, info.lastVal, pane);
const series = this.chart.addSeries(LineSeries, {
color: info.color,
lineWidth: 1,
@@ -2275,16 +2297,35 @@ export class ChartManager {
series.applyOptions(opts as any);
}
/** 차트 설정: 보조지표 우측 가격축 라벨·설명 on/off */
/** 차트 설정: 캔들·보조지표 영역 가격축 라벨·설명 (동일 값이면 기존 API 호환) */
setSeriesPriceLabelsEnabled(enabled: boolean): void {
this._seriesPriceLabelsEnabled = enabled;
this.setCandleAreaPriceLabelsEnabled(enabled);
this.setIndicatorAreaPriceLabelsEnabled(enabled);
}
setCandleAreaPriceLabelsEnabled(enabled: boolean): void {
this._candleAreaPriceLabelsEnabled = enabled;
this._refreshPriceLabelStyles();
}
setIndicatorAreaPriceLabelsEnabled(enabled: boolean): void {
this._indicatorAreaPriceLabelsEnabled = enabled;
this._refreshPriceLabelStyles();
}
getCandleAreaPriceLabelsEnabled(): boolean {
return this._candleAreaPriceLabelsEnabled;
}
getIndicatorAreaPriceLabelsEnabled(): boolean {
return this._indicatorAreaPriceLabelsEnabled;
}
private _refreshPriceLabelStyles(): void {
for (const entry of this.indicators.values()) {
this.applyIndicatorStyle(entry.config);
}
}
getSeriesPriceLabelsEnabled(): boolean {
return this._seriesPriceLabelsEnabled;
this._applyAllSeriesPriceFormats();
}
/** 차트 설정: 거래량 pane 표시 on/off */
@@ -2308,8 +2349,12 @@ export class ChartManager {
private shouldShowSeriesPriceLabel(
config: IndicatorConfig,
plotAllowsLastValue = true,
paneIndex = 0,
): boolean {
return this._seriesPriceLabelsEnabled
const areaEnabled = paneIndex < 2
? this._candleAreaPriceLabelsEnabled
: this._indicatorAreaPriceLabelsEnabled;
return areaEnabled
&& plotAllowsLastValue
&& config.lastValueVisible !== false;
}
@@ -2318,8 +2363,9 @@ export class ChartManager {
config: IndicatorConfig,
plot: PlotDef | undefined,
plotAllowsLastValue = true,
paneIndex = 0,
): string {
if (!this.shouldShowSeriesPriceLabel(config, plotAllowsLastValue)) return '';
if (!this.shouldShowSeriesPriceLabel(config, plotAllowsLastValue, paneIndex)) return '';
if (config.type === 'IchimokuCloud' && plot?.id) {
return getIchimokuPlotTitle(plot.id);
}
@@ -2362,10 +2408,10 @@ export class ChartManager {
if (entry.type === 'IchimokuCloud') {
plotAllows = entry.seriesMeta[i]?.plotId !== 'plot2';
}
const showPriceLabel = this.shouldShowSeriesPriceLabel(config, plotAllows);
const showPriceLabel = this.shouldShowSeriesPriceLabel(config, plotAllows, paneIdx);
opts['lastValueVisible'] = showPriceLabel;
opts['title'] = paneIdx < 2 && showPriceLabel
? this.seriesTitleForPlot(config, plot, plotAllows)
? this.seriesTitleForPlot(config, plot, plotAllows, paneIdx)
: '';
} else {
opts['color'] = plot.color ?? '#aaa';
+3 -1
View File
@@ -386,7 +386,9 @@ export interface AppSettingsDto {
btAutoPopup?: boolean;
/** 백테스팅 매수/매도 마커에 금액 표시 여부 (기본 true) */
btShowPrice?: boolean;
/** 보조지표 우측 가격축 라벨·설명·금액 하이라이트 (기본 true) */
/** 캔들 영역 오버레이 지표 가격축 라벨·설명 (기본 true) */
chartCandleAreaPriceLabels?: boolean;
/** 하단 보조지표 pane 가격축 라벨·설명 (기본 true) */
chartSeriesPriceLabels?: boolean;
/** 차트 하단 거래량 바 표시 (기본 true) */
chartVolumeVisible?: boolean;