보조지표 툴바추가

This commit is contained in:
Macbook
2026-05-29 23:51:13 +09:00
parent 095b0d7db7
commit 6332d198b1
11 changed files with 846 additions and 436 deletions
+70 -13
View File
@@ -1,20 +1,21 @@
import type { Theme } from '../types';
import type { HLineStyle } from '../utils/indicatorRegistry';
/** 캔들·거래량·보조지표 pane 사이 구분선 */
export interface ChartPaneSeparatorOptions {
/** 단일 pane 구분선 스타일 */
export interface PaneSeparatorStyle {
visible: boolean;
color: string;
width: 1 | 2 | 3 | 4;
lineStyle: HLineStyle;
}
export const DEFAULT_CHART_PANE_SEPARATOR: ChartPaneSeparatorOptions = {
visible: true,
color: '#2a2e3a',
width: 1,
lineStyle: 'solid',
};
/** 캔들·보조지표 / 보조지표 간 구분선 설정 */
export interface ChartPaneSeparatorOptions {
/** 캔들(·거래량) 영역 ↔ 첫 보조지표 pane */
mainToIndicator: PaneSeparatorStyle;
/** 보조지표 pane 사이 */
indicatorToIndicator: PaneSeparatorStyle;
}
const THEME_DEFAULT_COLORS: Record<Theme, string> = {
dark: 'rgba(122, 162, 247, 0.15)',
@@ -26,11 +27,23 @@ export function themeDefaultPaneSeparatorColor(theme: Theme): string {
return THEME_DEFAULT_COLORS[theme] ?? THEME_DEFAULT_COLORS.dark;
}
export function resolveChartPaneSeparatorOptions(
raw?: Partial<ChartPaneSeparatorOptions> | null,
export const DEFAULT_PANE_SEPARATOR_STYLE: PaneSeparatorStyle = {
visible: true,
color: '#2a2e3a',
width: 1,
lineStyle: 'solid',
};
export const DEFAULT_CHART_PANE_SEPARATOR: ChartPaneSeparatorOptions = {
mainToIndicator: { ...DEFAULT_PANE_SEPARATOR_STYLE },
indicatorToIndicator: { ...DEFAULT_PANE_SEPARATOR_STYLE },
};
export function resolvePaneSeparatorStyle(
raw?: Partial<PaneSeparatorStyle> | null,
theme: Theme = 'dark',
): ChartPaneSeparatorOptions {
const base = { ...DEFAULT_CHART_PANE_SEPARATOR };
): PaneSeparatorStyle {
const base = { ...DEFAULT_PANE_SEPARATOR_STYLE };
if (!raw || typeof raw !== 'object') {
return { ...base, color: themeDefaultPaneSeparatorColor(theme) };
}
@@ -45,8 +58,52 @@ export function resolveChartPaneSeparatorOptions(
return base;
}
/** @deprecated 이전 단일 구분선 형식 — 하위 호환 */
function isLegacyFlatSeparator(
raw: Record<string, unknown>,
): raw is Partial<PaneSeparatorStyle> {
return 'visible' in raw && !('mainToIndicator' in raw);
}
export function resolveChartPaneSeparatorOptions(
raw?: Partial<ChartPaneSeparatorOptions> | Record<string, unknown> | null,
theme: Theme = 'dark',
): ChartPaneSeparatorOptions {
if (!raw || typeof raw !== 'object') {
const style = resolvePaneSeparatorStyle(null, theme);
return {
mainToIndicator: { ...style },
indicatorToIndicator: { ...style },
};
}
if (isLegacyFlatSeparator(raw)) {
const legacy = resolvePaneSeparatorStyle(raw, theme);
return {
mainToIndicator: { ...legacy },
indicatorToIndicator: { ...legacy },
};
}
const r = raw as Partial<ChartPaneSeparatorOptions>;
return {
mainToIndicator: resolvePaneSeparatorStyle(r.mainToIndicator, theme),
indicatorToIndicator: resolvePaneSeparatorStyle(r.indicatorToIndicator, theme),
};
}
export type PaneBoundaryKind = 'mainToIndicator' | 'indicatorToIndicator' | 'other';
/** 인접 pane 경계 종류 (pane 0=캔들, 1=거래량, 2+=보조지표) */
export function classifyPaneBoundary(
lowerPaneIndex: number,
upperPaneIndex: number,
): PaneBoundaryKind {
if (upperPaneIndex >= 2 && lowerPaneIndex < 2) return 'mainToIndicator';
if (lowerPaneIndex >= 2 && upperPaneIndex >= 2) return 'indicatorToIndicator';
return 'other';
}
/** LWC pane 구분선 — 커스텀 오버레이 사용 시 투명 처리 */
export function applyPaneSeparatorToChartOptions(opts: ChartPaneSeparatorOptions) {
export function applyPaneSeparatorToChartOptions(_opts: ChartPaneSeparatorOptions) {
return {
layout: {
panes: {