@coderyo/renderer-lite 1.0.0-rc.4 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +19 -1
- package/dist/index.js +80 -4
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,10 @@ import { Bar } from '@coderyo/data';
|
|
|
2
2
|
import { IndicatorConfig } from '@coderyo/indicators';
|
|
3
3
|
import { IChartApi, LineData, UTCTimestamp } from 'lightweight-charts';
|
|
4
4
|
|
|
5
|
+
interface ChartVisibleRange {
|
|
6
|
+
fromMs: number;
|
|
7
|
+
toMs: number;
|
|
8
|
+
}
|
|
5
9
|
interface TransformState {
|
|
6
10
|
visibleFromMs: number;
|
|
7
11
|
visibleToMs: number;
|
|
@@ -19,6 +23,11 @@ declare class TimeScaleBus {
|
|
|
19
23
|
register(chart: IChartApi): void;
|
|
20
24
|
subscribeTransform(listener: TransformListener): () => void;
|
|
21
25
|
setBarsTimeRange(fromMs: number, toMs: number): void;
|
|
26
|
+
getVisibleRange(): ChartVisibleRange | null;
|
|
27
|
+
getBarSpacing(): number;
|
|
28
|
+
setBarSpacing(spacing: number): void;
|
|
29
|
+
setVisibleTimeRange(range: ChartVisibleRange): void;
|
|
30
|
+
scrollToLogicalPosition(position: number, animated?: boolean): void;
|
|
22
31
|
private syncFrom;
|
|
23
32
|
private emit;
|
|
24
33
|
}
|
|
@@ -77,7 +86,9 @@ declare class PaneOrchestrator {
|
|
|
77
86
|
private showGrid;
|
|
78
87
|
private readonly maxRenderPoints;
|
|
79
88
|
private barByTime;
|
|
89
|
+
private barTimesOrdered;
|
|
80
90
|
private didInitialFit;
|
|
91
|
+
private skipNextInitialFit;
|
|
81
92
|
private indicatorConfig;
|
|
82
93
|
private priceLine;
|
|
83
94
|
private barAnimator;
|
|
@@ -102,6 +113,13 @@ declare class PaneOrchestrator {
|
|
|
102
113
|
private findNearestBar;
|
|
103
114
|
private createIndicatorStack;
|
|
104
115
|
resetViewState(): void;
|
|
116
|
+
/** Skip the next automatic fitContent after setBars (used by reloadHistory). */
|
|
117
|
+
preserveViewportOnNextSetBars(): void;
|
|
118
|
+
getVisibleRange(): ChartVisibleRange | null;
|
|
119
|
+
getBarSpace(): number;
|
|
120
|
+
setBarSpace(px: number): void;
|
|
121
|
+
setVisibleRange(range: ChartVisibleRange): void;
|
|
122
|
+
scrollToTimestamp(tsMs: number, animationMs?: number): void;
|
|
105
123
|
/** Clear series while symbol/interval data reloads (avoids overlapping candles). */
|
|
106
124
|
clearBars(): void;
|
|
107
125
|
fitContent(): void;
|
|
@@ -168,4 +186,4 @@ declare function bollOverlayLines(bars: Bar[], period: number, mult: number, sou
|
|
|
168
186
|
lower: LineData<UTCTimestamp>[];
|
|
169
187
|
};
|
|
170
188
|
|
|
171
|
-
export { type CrosshairPayload, IndicatorPaneStack, type IndicatorPaneStackOptions, PaneOrchestrator, type PaneOrchestratorOptions, type PinePlotLine, type ScaleMode, TimeScaleBus, type TransformState, bollOverlayLines, emaOverlayLine, maOverlayLine, volMaOverlayLine };
|
|
189
|
+
export { type ChartVisibleRange, type CrosshairPayload, IndicatorPaneStack, type IndicatorPaneStackOptions, PaneOrchestrator, type PaneOrchestratorOptions, type PinePlotLine, type ScaleMode, TimeScaleBus, type TransformState, bollOverlayLines, emaOverlayLine, maOverlayLine, volMaOverlayLine };
|
package/dist/index.js
CHANGED
|
@@ -309,6 +309,44 @@ var TimeScaleBus = class {
|
|
|
309
309
|
this.visibleToMs = toMs;
|
|
310
310
|
this.emit();
|
|
311
311
|
}
|
|
312
|
+
getVisibleRange() {
|
|
313
|
+
if (this.visibleToMs <= this.visibleFromMs) return null;
|
|
314
|
+
return { fromMs: this.visibleFromMs, toMs: this.visibleToMs };
|
|
315
|
+
}
|
|
316
|
+
getBarSpacing() {
|
|
317
|
+
const chart = this.charts[0];
|
|
318
|
+
return chart ? chart.timeScale().options().barSpacing : 6;
|
|
319
|
+
}
|
|
320
|
+
setBarSpacing(spacing) {
|
|
321
|
+
if (!Number.isFinite(spacing) || spacing <= 0) return;
|
|
322
|
+
this.syncing = true;
|
|
323
|
+
for (const chart of this.charts) {
|
|
324
|
+
chart.timeScale().applyOptions({ barSpacing: spacing });
|
|
325
|
+
}
|
|
326
|
+
this.syncing = false;
|
|
327
|
+
this.emit();
|
|
328
|
+
}
|
|
329
|
+
setVisibleTimeRange(range) {
|
|
330
|
+
const from = Math.floor(range.fromMs / 1e3);
|
|
331
|
+
const to = Math.floor(range.toMs / 1e3);
|
|
332
|
+
if (to <= from) return;
|
|
333
|
+
this.visibleFromMs = range.fromMs;
|
|
334
|
+
this.visibleToMs = range.toMs;
|
|
335
|
+
this.syncing = true;
|
|
336
|
+
for (const chart of this.charts) {
|
|
337
|
+
chart.timeScale().setVisibleRange({ from, to });
|
|
338
|
+
}
|
|
339
|
+
this.syncing = false;
|
|
340
|
+
this.emit();
|
|
341
|
+
}
|
|
342
|
+
scrollToLogicalPosition(position, animated = false) {
|
|
343
|
+
this.syncing = true;
|
|
344
|
+
for (const chart of this.charts) {
|
|
345
|
+
chart.timeScale().scrollToPosition(position, animated);
|
|
346
|
+
}
|
|
347
|
+
this.syncing = false;
|
|
348
|
+
this.emit();
|
|
349
|
+
}
|
|
312
350
|
syncFrom(source, range) {
|
|
313
351
|
this.syncing = true;
|
|
314
352
|
for (const chart of this.charts) {
|
|
@@ -417,7 +455,9 @@ var PaneOrchestrator = class {
|
|
|
417
455
|
showGrid = false;
|
|
418
456
|
maxRenderPoints;
|
|
419
457
|
barByTime = /* @__PURE__ */ new Map();
|
|
458
|
+
barTimesOrdered = [];
|
|
420
459
|
didInitialFit = false;
|
|
460
|
+
skipNextInitialFit = false;
|
|
421
461
|
indicatorConfig = null;
|
|
422
462
|
priceLine = null;
|
|
423
463
|
barAnimator = null;
|
|
@@ -655,16 +695,18 @@ var PaneOrchestrator = class {
|
|
|
655
695
|
setBars(bars, gaps) {
|
|
656
696
|
const renderBars = lodDecimateBars(bars, this.maxRenderPoints);
|
|
657
697
|
this.barByTime = new Map(renderBars.map((b) => [b.t, b]));
|
|
658
|
-
|
|
659
|
-
const vols = [];
|
|
698
|
+
this.barTimesOrdered = renderBars.map((b) => b.t);
|
|
660
699
|
const gapSet = new Set(gaps ?? []);
|
|
661
700
|
const seenTimes = /* @__PURE__ */ new Set();
|
|
701
|
+
const candles = [];
|
|
702
|
+
const vols = [];
|
|
662
703
|
for (let i = 0; i < renderBars.length; i++) {
|
|
663
704
|
const b = renderBars[i];
|
|
664
705
|
const time = toUtcSeconds2(b.t);
|
|
665
706
|
if (seenTimes.has(time)) continue;
|
|
666
707
|
seenTimes.add(time);
|
|
667
|
-
if (
|
|
708
|
+
if (gapSet.has(b.t)) {
|
|
709
|
+
candles.push({ time });
|
|
668
710
|
}
|
|
669
711
|
candles.push(barToCandle(b));
|
|
670
712
|
vols.push(barToVolume(b));
|
|
@@ -685,12 +727,13 @@ var PaneOrchestrator = class {
|
|
|
685
727
|
}
|
|
686
728
|
if (renderBars.length > 0) {
|
|
687
729
|
this.syncChartSize();
|
|
688
|
-
if (!this.didInitialFit) {
|
|
730
|
+
if (!this.didInitialFit && !this.skipNextInitialFit) {
|
|
689
731
|
this.mainChart.timeScale().fitContent();
|
|
690
732
|
this.volumeChart.timeScale().fitContent();
|
|
691
733
|
this.indicators?.fitContent();
|
|
692
734
|
this.didInitialFit = true;
|
|
693
735
|
}
|
|
736
|
+
this.skipNextInitialFit = false;
|
|
694
737
|
}
|
|
695
738
|
}
|
|
696
739
|
subscribeCrosshair(listener) {
|
|
@@ -737,13 +780,46 @@ var PaneOrchestrator = class {
|
|
|
737
780
|
}
|
|
738
781
|
resetViewState() {
|
|
739
782
|
this.didInitialFit = false;
|
|
783
|
+
this.skipNextInitialFit = false;
|
|
740
784
|
this.bus.visibleFromMs = 0;
|
|
741
785
|
this.bus.visibleToMs = 0;
|
|
742
786
|
}
|
|
787
|
+
/** Skip the next automatic fitContent after setBars (used by reloadHistory). */
|
|
788
|
+
preserveViewportOnNextSetBars() {
|
|
789
|
+
this.skipNextInitialFit = true;
|
|
790
|
+
this.didInitialFit = true;
|
|
791
|
+
}
|
|
792
|
+
getVisibleRange() {
|
|
793
|
+
return this.bus.getVisibleRange();
|
|
794
|
+
}
|
|
795
|
+
getBarSpace() {
|
|
796
|
+
return this.bus.getBarSpacing();
|
|
797
|
+
}
|
|
798
|
+
setBarSpace(px) {
|
|
799
|
+
this.bus.setBarSpacing(px);
|
|
800
|
+
}
|
|
801
|
+
setVisibleRange(range) {
|
|
802
|
+
this.bus.setVisibleTimeRange(range);
|
|
803
|
+
this.didInitialFit = true;
|
|
804
|
+
}
|
|
805
|
+
scrollToTimestamp(tsMs, animationMs) {
|
|
806
|
+
const time = toUtcSeconds2(tsMs);
|
|
807
|
+
const idx = this.mainChart.timeScale().timeToIndex(time, true);
|
|
808
|
+
if (idx == null) {
|
|
809
|
+
const nearest = this.findNearestBar(tsMs);
|
|
810
|
+
if (nearest == null) return;
|
|
811
|
+
const i = this.barTimesOrdered.indexOf(nearest.t);
|
|
812
|
+
if (i < 0) return;
|
|
813
|
+
this.bus.scrollToLogicalPosition(i, (animationMs ?? 0) > 0);
|
|
814
|
+
return;
|
|
815
|
+
}
|
|
816
|
+
this.bus.scrollToLogicalPosition(idx, (animationMs ?? 0) > 0);
|
|
817
|
+
}
|
|
743
818
|
/** Clear series while symbol/interval data reloads (avoids overlapping candles). */
|
|
744
819
|
clearBars() {
|
|
745
820
|
this.barAnimator?.cancel();
|
|
746
821
|
this.barByTime = /* @__PURE__ */ new Map();
|
|
822
|
+
this.barTimesOrdered = [];
|
|
747
823
|
this.mainSeries.setData([]);
|
|
748
824
|
this.maSeries.setData([]);
|
|
749
825
|
this.volumeSeries.setData([]);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/pane-orchestrator.ts","../src/chart-grid.ts","../src/indicator-panes.ts","../src/pane-resize.ts","../src/time-scale-bus.ts","../src/bar-smooth-animator.ts"],"sourcesContent":["import {\n CandlestickSeries,\n ColorType,\n createChart,\n HistogramSeries,\n LineSeries,\n type CandlestickData,\n type HistogramData,\n type IChartApi,\n type ISeriesApi,\n type IPriceLine,\n type MouseEventParams,\n type Time,\n type UTCTimestamp,\n} from 'lightweight-charts';\nimport type { Bar } from '@coderyo/data';\nimport { lodDecimateBars } from '@coderyo/series';\nimport { gridOptions } from './chart-grid.js';\nimport type { IndicatorConfig } from '@coderyo/indicators';\n\nimport {\n IndicatorPaneStack,\n bollOverlayLines,\n emaOverlayLine,\n maOverlayLine,\n volMaOverlayLine,\n} from './indicator-panes.js';\nimport { attachPaneResizer } from './pane-resize.js';\nimport { TimeScaleBus } from './time-scale-bus.js';\nimport { BarSmoothAnimator } from './bar-smooth-animator.js';\n\nexport type ScaleMode = 'linear' | 'log';\n\nexport interface CrosshairPayload {\n time: number;\n price: number | null;\n ohlcv: { o: number; h: number; l: number; c: number; v?: number } | null;\n}\n\nexport interface PinePlotLine {\n title: string;\n color?: string;\n values: (number | null)[];\n}\n\nexport interface PaneOrchestratorOptions {\n container: HTMLElement;\n indicatorRoot?: HTMLElement;\n theme?: 'dark' | 'light';\n scaleMode?: ScaleMode;\n maxRenderPoints?: number;\n /** Show chart grid lines (default false). */\n showGrid?: boolean;\n /** null = no MA overlays and no MACD/RSI/KDJ panes. */\n indicatorConfig?: IndicatorConfig | null;\n /** Pine-lite plot lines on main chart (when pineEnabled). */\n pinePlots?: PinePlotLine[] | null;\n /** Animate last candle + price line toward new OHLC (~150ms). */\n smoothPriceUpdate?: boolean;\n smoothPriceDurationMs?: number;\n}\n\nfunction toUtcSeconds(tMs: number): UTCTimestamp {\n return Math.floor(tMs / 1000) as UTCTimestamp;\n}\n\nfunction barToCandle(b: Bar): CandlestickData {\n return { time: toUtcSeconds(b.t), open: b.o, high: b.h, low: b.l, close: b.c };\n}\n\nfunction barToVolume(b: Bar): HistogramData<UTCTimestamp> {\n return { time: toUtcSeconds(b.t), value: b.v ?? 0 };\n}\n\nexport class PaneOrchestrator {\n readonly bus = new TimeScaleBus();\n private readonly mainChart: IChartApi;\n private readonly volumeChart: IChartApi;\n private readonly mainSeries: ISeriesApi<'Candlestick'>;\n private readonly volumeSeries: ISeriesApi<'Histogram'>;\n private readonly maSeries: ISeriesApi<'Line'>;\n private readonly emaSeries: ISeriesApi<'Line'>;\n private readonly bollUpper: ISeriesApi<'Line'>;\n private readonly bollMiddle: ISeriesApi<'Line'>;\n private readonly bollLower: ISeriesApi<'Line'>;\n private readonly volMaSeries: ISeriesApi<'Line'>;\n private readonly indicatorRoot?: HTMLElement;\n private indicators: IndicatorPaneStack | null;\n private pinePlotSeries: ISeriesApi<'Line'>[] = [];\n private pinePlots: PinePlotLine[] | null = null;\n private overlayCanvas: HTMLCanvasElement | null = null;\n private dark = true;\n private showGrid = false;\n private readonly maxRenderPoints: number;\n private barByTime = new Map<number, Bar>();\n private didInitialFit = false;\n private indicatorConfig: IndicatorConfig | null = null;\n private priceLine: IPriceLine | null = null;\n private barAnimator: BarSmoothAnimator | null = null;\n private smoothPriceDurationMs = 150;\n\n constructor(opts: PaneOrchestratorOptions) {\n this.maxRenderPoints = opts.maxRenderPoints ?? 4000;\n this.dark = opts.theme !== 'light';\n this.showGrid = opts.showGrid ?? false;\n const layout = this.layoutForTheme(this.dark);\n const grid = gridOptions(this.showGrid, this.dark);\n\n const mainEl = document.createElement('div');\n mainEl.style.cssText = 'flex:7;min-height:120px;width:100%;position:relative;';\n const volEl = document.createElement('div');\n volEl.style.cssText = 'flex:2;min-height:64px;width:100%;position:relative;';\n\n opts.container.style.cssText =\n 'display:flex;flex-direction:column;height:100%;width:100%;min-height:240px;overflow:hidden;';\n opts.container.append(mainEl, volEl);\n attachPaneResizer(mainEl, volEl, { storageKey: 'tradview:pane:main-volume' });\n\n this.mainChart = createChart(mainEl, { layout, grid, autoSize: true });\n this.volumeChart = createChart(volEl, {\n layout,\n grid,\n autoSize: true,\n rightPriceScale: { scaleMargins: { top: 0.8, bottom: 0 } },\n });\n\n if (opts.scaleMode === 'log') {\n this.mainChart.priceScale('right').applyOptions({ mode: 1 });\n }\n\n this.mainSeries = this.mainChart.addSeries(CandlestickSeries, {\n upColor: '#26a69a',\n downColor: '#ef5350',\n borderVisible: false,\n wickUpColor: '#26a69a',\n wickDownColor: '#ef5350',\n });\n this.maSeries = this.mainChart.addSeries(LineSeries, {\n color: '#f0b429',\n lineWidth: 1,\n title: 'MA',\n });\n this.emaSeries = this.mainChart.addSeries(LineSeries, {\n color: '#7ee787',\n lineWidth: 1,\n title: 'EMA',\n visible: false,\n });\n this.bollUpper = this.mainChart.addSeries(LineSeries, {\n color: '#8b949e',\n lineWidth: 1,\n title: 'BOLL↑',\n visible: false,\n });\n this.bollMiddle = this.mainChart.addSeries(LineSeries, {\n color: '#8b949e88',\n lineWidth: 1,\n lineStyle: 2,\n title: 'BOLL',\n visible: false,\n });\n this.bollLower = this.mainChart.addSeries(LineSeries, {\n color: '#8b949e',\n lineWidth: 1,\n title: 'BOLL↓',\n visible: false,\n });\n this.volumeSeries = this.volumeChart.addSeries(HistogramSeries, {\n color: '#26a69a55',\n priceFormat: { type: 'volume' },\n });\n this.volMaSeries = this.volumeChart.addSeries(LineSeries, {\n color: '#58a6ff',\n lineWidth: 1,\n title: 'VolMA5',\n });\n\n this.bus.register(this.mainChart);\n this.bus.register(this.volumeChart);\n\n this.indicatorRoot = opts.indicatorRoot;\n this.indicatorConfig = opts.indicatorConfig ?? null;\n this.pinePlots = opts.pinePlots ?? null;\n this.indicators = this.createIndicatorStack();\n\n this.initOverlay(mainEl);\n this.setSmoothPriceUpdate(opts.smoothPriceUpdate ?? false, opts.smoothPriceDurationMs);\n }\n\n setSmoothPriceUpdate(enabled: boolean, durationMs = 150): void {\n this.smoothPriceDurationMs = durationMs;\n if (enabled) {\n if (!this.barAnimator) {\n this.barAnimator = new BarSmoothAnimator(durationMs, (bar) => this.applyLastBarToSeries(bar));\n } else {\n this.barAnimator.setDuration(durationMs);\n }\n return;\n }\n this.barAnimator?.cancel();\n this.barAnimator = null;\n if (this.priceLine) {\n this.mainSeries.removePriceLine(this.priceLine);\n this.priceLine = null;\n }\n }\n\n /** Update the last candle (and price line); optional smooth interpolation. */\n updateLastBar(target: Bar, opts?: { smooth?: boolean; durationMs?: number }): void {\n const prev = this.barByTime.get(target.t);\n const smooth = opts?.smooth ?? !!this.barAnimator;\n const duration = opts?.durationMs ?? this.smoothPriceDurationMs;\n if (smooth && this.barAnimator) {\n this.barAnimator.setDuration(duration);\n this.barAnimator.animateTo(target, prev ?? target);\n return;\n }\n this.barAnimator?.cancel();\n this.applyLastBarToSeries(target);\n }\n\n private applyLastBarToSeries(bar: Bar): void {\n this.barByTime.set(bar.t, bar);\n this.mainSeries.update(barToCandle(bar));\n this.volumeSeries.update(barToVolume(bar));\n this.ensurePriceLine(bar.c);\n if (this.indicatorConfig) {\n const bars = [...this.barByTime.values()].sort((a, b) => a.t - b.t);\n this.applyMainOverlays(bars);\n this.indicators?.setBars(bars);\n }\n }\n\n private ensurePriceLine(price: number): void {\n if (!this.priceLine) {\n this.priceLine = this.mainSeries.createPriceLine({\n price,\n color: '#58a6ff',\n lineWidth: 1,\n lineStyle: 2,\n axisLabelVisible: true,\n title: '',\n });\n } else {\n this.priceLine.applyOptions({ price });\n }\n }\n\n setTheme(theme: 'dark' | 'light'): void {\n this.dark = theme === 'dark';\n const layout = this.layoutForTheme(this.dark);\n const grid = gridOptions(this.showGrid, this.dark);\n this.mainChart.applyOptions({ layout, grid });\n this.volumeChart.applyOptions({ layout, grid });\n this.indicators?.setTheme(theme);\n }\n\n setIndicatorConfig(config: IndicatorConfig | null): void {\n this.indicatorConfig = config;\n if (!config) {\n this.indicators = null;\n this.maSeries.setData([]);\n this.emaSeries.setData([]);\n this.bollUpper.setData([]);\n this.bollMiddle.setData([]);\n this.bollLower.setData([]);\n this.volMaSeries.setData([]);\n this.emaSeries.applyOptions({ visible: false });\n this.bollUpper.applyOptions({ visible: false });\n this.bollMiddle.applyOptions({ visible: false });\n this.bollLower.applyOptions({ visible: false });\n return;\n }\n if (!this.indicators) this.indicators = this.createIndicatorStack();\n const bars = [...this.barByTime.values()].sort((a, b) => a.t - b.t);\n this.indicators?.setConfig(config);\n if (bars.length > 0) {\n this.applyMainOverlays(bars);\n this.indicators?.setBars(bars);\n }\n }\n\n setPinePlots(plots: PinePlotLine[] | null): void {\n this.pinePlots = plots;\n const bars = [...this.barByTime.values()].sort((a, b) => a.t - b.t);\n this.syncPinePlotSeries(bars);\n }\n\n private applyMainOverlays(bars: Bar[]): void {\n const cfg = this.indicatorConfig;\n if (!cfg) return;\n this.maSeries.applyOptions({ title: `MA${cfg.maPeriod}` });\n this.maSeries.setData(maOverlayLine(bars, cfg.maPeriod, cfg.source));\n this.volMaSeries.setData(volMaOverlayLine(bars, cfg.volMaPeriod));\n\n if (cfg.showEma) {\n this.emaSeries.applyOptions({ visible: true, title: `EMA${cfg.emaPeriod}` });\n this.emaSeries.setData(emaOverlayLine(bars, cfg.emaPeriod, cfg.source));\n } else {\n this.emaSeries.applyOptions({ visible: false });\n this.emaSeries.setData([]);\n }\n\n if (cfg.showBoll) {\n const bands = bollOverlayLines(bars, cfg.bollPeriod, cfg.bollMult, cfg.source);\n this.bollUpper.applyOptions({ visible: true });\n this.bollMiddle.applyOptions({ visible: true });\n this.bollLower.applyOptions({ visible: true });\n this.bollUpper.setData(bands.upper);\n this.bollMiddle.setData(bands.middle);\n this.bollLower.setData(bands.lower);\n } else {\n this.bollUpper.applyOptions({ visible: false });\n this.bollMiddle.applyOptions({ visible: false });\n this.bollLower.applyOptions({ visible: false });\n this.bollUpper.setData([]);\n this.bollMiddle.setData([]);\n this.bollLower.setData([]);\n }\n this.syncPinePlotSeries(bars);\n }\n\n private syncPinePlotSeries(bars: Bar[]): void {\n for (const s of this.pinePlotSeries) this.mainChart.removeSeries(s);\n this.pinePlotSeries = [];\n if (!this.pinePlots?.length || bars.length === 0) return;\n\n const palette = ['#58a6ff', '#d2a8ff', '#ff7b72', '#ffa657'];\n for (let i = 0; i < this.pinePlots.length; i++) {\n const plot = this.pinePlots[i]!;\n const series = this.mainChart.addSeries(LineSeries, {\n color: plot.color ?? palette[i % palette.length]!,\n lineWidth: 1,\n title: plot.title,\n });\n const out: { time: UTCTimestamp; value: number }[] = [];\n for (let j = 0; j < bars.length; j++) {\n const v = plot.values[j];\n if (v == null) continue;\n out.push({ time: toUtcSeconds(bars[j]!.t), value: v });\n }\n series.setData(out);\n this.pinePlotSeries.push(series);\n }\n }\n\n setShowGrid(show: boolean): void {\n this.showGrid = show;\n const grid = gridOptions(show, this.dark);\n this.mainChart.applyOptions({ grid });\n this.volumeChart.applyOptions({ grid });\n this.indicators?.setShowGrid(show);\n }\n\n setBars(bars: Bar[], gaps?: number[]): void {\n const renderBars = lodDecimateBars(bars, this.maxRenderPoints);\n this.barByTime = new Map(renderBars.map((b) => [b.t, b]));\n\n const candles: CandlestickData[] = [];\n const vols: HistogramData<UTCTimestamp>[] = [];\n const gapSet = new Set(gaps ?? []);\n const seenTimes = new Set<number>();\n\n for (let i = 0; i < renderBars.length; i++) {\n const b = renderBars[i]!;\n const time = toUtcSeconds(b.t);\n if (seenTimes.has(time)) continue;\n seenTimes.add(time);\n if (i > 0 && gapSet.has(b.t)) {\n // whitespace: skip connecting — LWC uses sparse times\n }\n candles.push(barToCandle(b));\n vols.push(barToVolume(b));\n }\n\n this.mainSeries.setData(candles);\n this.volumeSeries.setData(vols);\n if (this.indicatorConfig) {\n this.applyMainOverlays(renderBars);\n this.indicators?.setBars(renderBars);\n } else {\n this.maSeries.setData([]);\n this.emaSeries.setData([]);\n this.bollUpper.setData([]);\n this.bollMiddle.setData([]);\n this.bollLower.setData([]);\n this.volMaSeries.setData([]);\n this.syncPinePlotSeries(renderBars);\n }\n\n if (renderBars.length > 0) {\n this.syncChartSize();\n if (!this.didInitialFit) {\n this.mainChart.timeScale().fitContent();\n this.volumeChart.timeScale().fitContent();\n this.indicators?.fitContent();\n this.didInitialFit = true;\n }\n }\n }\n\n subscribeCrosshair(listener: (payload: CrosshairPayload | null) => void): () => void {\n const handler = (param: MouseEventParams<Time>) => {\n if (param.time == null || !param.point) {\n listener(null);\n return;\n }\n const tMs = typeof param.time === 'number' ? param.time * 1000 : null;\n if (tMs == null) {\n listener(null);\n return;\n }\n const price = this.mainSeries.coordinateToPrice(param.point.y) ?? null;\n const bar = this.barByTime.get(tMs) ?? this.findNearestBar(tMs);\n listener({\n time: tMs,\n price,\n ohlcv: bar\n ? { o: bar.o, h: bar.h, l: bar.l, c: bar.c, v: bar.v }\n : null,\n });\n };\n this.mainChart.subscribeCrosshairMove(handler);\n return () => this.mainChart.unsubscribeCrosshairMove(handler);\n }\n\n private findNearestBar(tMs: number): Bar | null {\n let best: Bar | null = null;\n let bestDt = Infinity;\n for (const b of this.barByTime.values()) {\n const dt = Math.abs(b.t - tMs);\n if (dt < bestDt) {\n bestDt = dt;\n best = b;\n }\n }\n return bestDt < 120_000 ? best : null;\n }\n\n private createIndicatorStack(): IndicatorPaneStack | null {\n if (!this.indicatorRoot || !this.indicatorConfig) return null;\n return new IndicatorPaneStack(this.indicatorRoot, this.bus, {\n theme: this.dark ? 'dark' : 'light',\n showGrid: this.showGrid,\n config: this.indicatorConfig,\n });\n }\n\n resetViewState(): void {\n this.didInitialFit = false;\n this.bus.visibleFromMs = 0;\n this.bus.visibleToMs = 0;\n }\n\n /** Clear series while symbol/interval data reloads (avoids overlapping candles). */\n clearBars(): void {\n this.barAnimator?.cancel();\n this.barByTime = new Map();\n this.mainSeries.setData([]);\n this.maSeries.setData([]);\n this.volumeSeries.setData([]);\n this.volMaSeries.setData([]);\n this.indicators?.clearBars();\n }\n\n fitContent(): void {\n this.mainChart.timeScale().fitContent();\n this.volumeChart.timeScale().fitContent();\n this.indicators?.fitContent();\n this.didInitialFit = true;\n }\n\n scrollToRealtime(): void {\n this.mainChart.timeScale().scrollToRealTime();\n this.volumeChart.timeScale().scrollToRealTime();\n this.indicators?.scrollToRealtime();\n }\n\n setLogScale(enabled: boolean): void {\n this.mainChart.priceScale('right').applyOptions({ mode: enabled ? 1 : 0 });\n }\n\n resize(): void {\n this.syncChartSize();\n this.syncOverlaySize();\n this.indicators?.resize();\n }\n\n getOverlayCanvas(): HTMLCanvasElement | null {\n return this.overlayCanvas;\n }\n\n timeToX(tMs: number): number | null {\n const coord = this.mainChart.timeScale().timeToCoordinate(toUtcSeconds(tMs));\n if (coord == null) return null;\n return coord * devicePixelRatio;\n }\n\n priceToY(price: number): number | null {\n const coord = this.mainSeries.priceToCoordinate(price);\n if (coord == null) return null;\n return coord * devicePixelRatio;\n }\n\n xToTime(x: number): number | null {\n const t = this.mainChart.timeScale().coordinateToTime(x / devicePixelRatio);\n if (t == null) return null;\n return Number(t) * 1000;\n }\n\n yToPrice(y: number): number | null {\n const p = this.mainSeries.coordinateToPrice(y / devicePixelRatio);\n return p ?? null;\n }\n\n destroy(): void {\n this.barAnimator?.cancel();\n if (this.priceLine) {\n this.mainSeries.removePriceLine(this.priceLine);\n this.priceLine = null;\n }\n this.mainChart.remove();\n this.volumeChart.remove();\n this.indicators?.destroy();\n this.overlayCanvas?.remove();\n }\n\n private initOverlay(parent: HTMLElement) {\n const canvas = document.createElement('canvas');\n canvas.style.cssText =\n 'position:absolute;left:0;top:0;width:100%;height:100%;pointer-events:none;z-index:10;';\n parent.style.position = 'relative';\n parent.appendChild(canvas);\n this.overlayCanvas = canvas;\n this.syncOverlaySize();\n this.bus.subscribeTransform(() => {\n this.syncOverlaySize();\n });\n }\n\n /** Let drawing overlay receive clicks; cursor mode keeps pan/zoom on LWC. */\n setOverlayPointerEvents(mode: 'auto' | 'none'): void {\n if (this.overlayCanvas) this.overlayCanvas.style.pointerEvents = mode;\n }\n\n private syncOverlaySize() {\n if (!this.overlayCanvas?.parentElement) return;\n const parent = this.overlayCanvas.parentElement;\n if (parent.lastElementChild !== this.overlayCanvas) {\n parent.appendChild(this.overlayCanvas);\n }\n const rect = parent.getBoundingClientRect();\n this.overlayCanvas.width = rect.width * devicePixelRatio;\n this.overlayCanvas.height = rect.height * devicePixelRatio;\n }\n\n private syncChartSize(): void {\n const mainEl = this.mainChart.chartElement().parentElement;\n const volEl = this.volumeChart.chartElement().parentElement;\n if (mainEl) {\n const w = mainEl.clientWidth;\n const h = mainEl.clientHeight;\n if (w > 0 && h > 0) this.mainChart.resize(w, h);\n }\n if (volEl) {\n const w = volEl.clientWidth;\n const h = volEl.clientHeight;\n if (w > 0 && h > 0) this.volumeChart.resize(w, h);\n }\n }\n\n private layoutForTheme(dark: boolean) {\n return {\n background: { type: ColorType.Solid, color: dark ? '#0d1117' : '#ffffff' },\n textColor: dark ? '#e6edf3' : '#24292f',\n };\n }\n}","/** LWC grid line options — default off per product spec. */\nexport function gridOptions(showGrid: boolean, dark: boolean) {\n const color = dark ? '#21262d' : '#d0d7de';\n return {\n vertLines: { visible: showGrid, color },\n horzLines: { visible: showGrid, color },\n };\n}","import {\n ColorType,\n createChart,\n HistogramSeries,\n LineSeries,\n type HistogramData,\n type IChartApi,\n type ISeriesApi,\n type LineData,\n type UTCTimestamp,\n} from 'lightweight-charts';\nimport type { Bar } from '@coderyo/data';\nimport {\n type IndicatorConfig,\n DEFAULT_INDICATOR_CONFIG,\n boll,\n kdj,\n macd,\n rsi,\n sma,\n ema,\n} from '@coderyo/indicators';\nimport { gridOptions } from './chart-grid.js';\nimport type { TimeScaleBus } from './time-scale-bus.js';\n\nexport interface IndicatorPaneStackOptions {\n theme?: 'dark' | 'light';\n showGrid?: boolean;\n config?: IndicatorConfig;\n}\n\nfunction barsForSource(bars: Bar[], source: IndicatorConfig['source']): Bar[] {\n if (source === 'close') return bars;\n return bars.map((b) => ({ ...b, c: (b.h + b.l + b.c) / 3 }));\n}\n\nfunction toUtcSeconds(tMs: number): UTCTimestamp {\n return Math.floor(tMs / 1000) as UTCTimestamp;\n}\n\nfunction lineData(bars: Bar[], values: (number | null)[]): LineData<UTCTimestamp>[] {\n const out: LineData<UTCTimestamp>[] = [];\n for (let i = 0; i < bars.length; i++) {\n const v = values[i];\n if (v == null) continue;\n out.push({ time: toUtcSeconds(bars[i]!.t), value: v });\n }\n return out;\n}\n\nfunction histData(bars: Bar[], values: (number | null)[]): HistogramData<UTCTimestamp>[] {\n const out: HistogramData<UTCTimestamp>[] = [];\n for (let i = 0; i < bars.length; i++) {\n const v = values[i];\n if (v == null) continue;\n out.push({\n time: toUtcSeconds(bars[i]!.t),\n value: v,\n color: v >= 0 ? '#26a69a88' : '#ef535088',\n });\n }\n return out;\n}\n\nexport class IndicatorPaneStack {\n private readonly macdChart: IChartApi;\n private readonly rsiChart: IChartApi;\n private readonly kdjChart: IChartApi;\n private readonly macdLine: ISeriesApi<'Line'>;\n private readonly macdSignal: ISeriesApi<'Line'>;\n private readonly macdHist: ISeriesApi<'Histogram'>;\n private readonly rsiLine: ISeriesApi<'Line'>;\n private readonly kdjK: ISeriesApi<'Line'>;\n private readonly kdjD: ISeriesApi<'Line'>;\n private readonly kdjJ: ISeriesApi<'Line'>;\n private dark = true;\n private showGrid = false;\n private config: IndicatorConfig = DEFAULT_INDICATOR_CONFIG;\n private readonly macdWrap: HTMLElement;\n private readonly rsiWrap: HTMLElement;\n private readonly kdjWrap: HTMLElement;\n\n constructor(\n private readonly root: HTMLElement,\n bus: TimeScaleBus,\n opts: IndicatorPaneStackOptions | 'dark' | 'light' = 'dark',\n ) {\n const o = typeof opts === 'string' ? { theme: opts, showGrid: false } : opts;\n this.dark = o.theme !== 'light';\n this.showGrid = o.showGrid ?? false;\n this.config = o.config ?? DEFAULT_INDICATOR_CONFIG;\n this.root.style.display = 'flex';\n this.root.style.flexDirection = 'column';\n this.root.style.flex = '2';\n this.root.style.minHeight = '0';\n this.root.style.overflow = 'hidden';\n\n const macdPane = this.createPaneWrap('MACD');\n const rsiPane = this.createPaneWrap('RSI');\n const kdjPane = this.createPaneWrap('KDJ');\n this.macdWrap = macdPane.wrap;\n this.rsiWrap = rsiPane.wrap;\n this.kdjWrap = kdjPane.wrap;\n this.root.append(macdPane.wrap, rsiPane.wrap, kdjPane.wrap);\n this.applyPaneVisibility();\n\n const layout = this.layoutForTheme(this.dark);\n const grid = gridOptions(this.showGrid, this.dark);\n this.macdChart = createChart(macdPane.el, { layout, grid, autoSize: true });\n this.rsiChart = createChart(rsiPane.el, { layout, grid, autoSize: true });\n this.kdjChart = createChart(kdjPane.el, { layout, grid, autoSize: true });\n\n for (const c of [this.macdChart, this.rsiChart, this.kdjChart]) bus.register(c);\n\n this.macdLine = this.macdChart.addSeries(LineSeries, { color: '#2962ff', lineWidth: 1 });\n this.macdSignal = this.macdChart.addSeries(LineSeries, { color: '#ff9800', lineWidth: 1 });\n this.macdHist = this.macdChart.addSeries(HistogramSeries, {\n priceFormat: { type: 'price', precision: 4, minMove: 0.0001 },\n });\n this.rsiLine = this.rsiChart.addSeries(LineSeries, { color: '#ab47bc', lineWidth: 1 });\n this.kdjK = this.kdjChart.addSeries(LineSeries, { color: '#42a5f5', lineWidth: 1 });\n this.kdjD = this.kdjChart.addSeries(LineSeries, { color: '#ffa726', lineWidth: 1 });\n this.kdjJ = this.kdjChart.addSeries(LineSeries, { color: '#ef5350', lineWidth: 1 });\n }\n\n setConfig(config: IndicatorConfig): void {\n this.config = config;\n this.applyPaneVisibility();\n }\n\n private applyPaneVisibility(): void {\n this.macdWrap.style.display = this.config.showMacd ? '' : 'none';\n this.rsiWrap.style.display = this.config.showRsi ? '' : 'none';\n this.kdjWrap.style.display = this.config.showKdj ? '' : 'none';\n }\n\n clearBars(): void {\n this.macdLine.setData([]);\n this.macdSignal.setData([]);\n this.macdHist.setData([]);\n this.rsiLine.setData([]);\n this.kdjK.setData([]);\n this.kdjD.setData([]);\n this.kdjJ.setData([]);\n }\n\n setBars(bars: Bar[]): void {\n if (bars.length === 0) return;\n const src = barsForSource(bars, this.config.source);\n const m = macd(src, this.config.macdFast, this.config.macdSlow, this.config.macdSignal);\n this.macdLine.setData(lineData(bars, m.macd));\n this.macdSignal.setData(lineData(bars, m.signal));\n this.macdHist.setData(histData(bars, m.histogram));\n\n this.rsiLine.setData(lineData(bars, rsi(src, this.config.rsiPeriod)));\n\n const k = kdj(src, this.config.kdjPeriod, this.config.kdjKSmooth, this.config.kdjDSmooth);\n this.kdjK.setData(lineData(bars, k.k));\n this.kdjD.setData(lineData(bars, k.d));\n this.kdjJ.setData(lineData(bars, k.j));\n\n this.macdChart.timeScale().fitContent();\n this.rsiChart.timeScale().fitContent();\n this.kdjChart.timeScale().fitContent();\n this.resize();\n }\n\n setTheme(theme: 'dark' | 'light'): void {\n this.dark = theme === 'dark';\n const layout = this.layoutForTheme(this.dark);\n const grid = gridOptions(this.showGrid, this.dark);\n this.macdChart.applyOptions({ layout, grid });\n this.rsiChart.applyOptions({ layout, grid });\n this.kdjChart.applyOptions({ layout, grid });\n }\n\n setShowGrid(show: boolean): void {\n this.showGrid = show;\n const grid = gridOptions(show, this.dark);\n this.macdChart.applyOptions({ grid });\n this.rsiChart.applyOptions({ grid });\n this.kdjChart.applyOptions({ grid });\n }\n\n fitContent(): void {\n this.macdChart.timeScale().fitContent();\n this.rsiChart.timeScale().fitContent();\n this.kdjChart.timeScale().fitContent();\n }\n\n scrollToRealtime(): void {\n this.macdChart.timeScale().scrollToRealTime();\n this.rsiChart.timeScale().scrollToRealTime();\n this.kdjChart.timeScale().scrollToRealTime();\n }\n\n resize(): void {\n for (const { chart, el } of [\n { chart: this.macdChart, el: this.macdChart.chartElement().parentElement },\n { chart: this.rsiChart, el: this.rsiChart.chartElement().parentElement },\n { chart: this.kdjChart, el: this.kdjChart.chartElement().parentElement },\n ]) {\n if (!el) continue;\n const w = el.clientWidth;\n const h = el.clientHeight;\n if (w > 0 && h > 0) chart.resize(w, h);\n }\n }\n\n destroy(): void {\n this.macdChart.remove();\n this.rsiChart.remove();\n this.kdjChart.remove();\n this.root.replaceChildren();\n }\n\n private createPaneWrap(label: string): { wrap: HTMLElement; el: HTMLElement } {\n const wrap = document.createElement('div');\n wrap.style.cssText =\n 'flex:1;min-height:72px;width:100%;position:relative;border-top:1px solid #30363d;';\n const tag = document.createElement('span');\n tag.textContent = label;\n tag.style.cssText =\n 'position:absolute;left:6px;top:4px;z-index:2;font-size:10px;color:#8b949e;pointer-events:none;';\n const el = document.createElement('div');\n el.style.cssText = 'width:100%;height:100%;';\n wrap.append(tag, el);\n return { wrap, el };\n }\n\n private layoutForTheme(dark: boolean) {\n return {\n background: { type: ColorType.Solid, color: dark ? '#0d1117' : '#ffffff' },\n textColor: dark ? '#e6edf3' : '#24292f',\n };\n }\n}\n\nexport function maOverlayLine(\n bars: Bar[],\n period = 20,\n source: IndicatorConfig['source'] = 'close',\n): LineData<UTCTimestamp>[] {\n const src = barsForSource(bars, source);\n return lineData(bars, sma(src, period));\n}\n\nexport function volMaOverlayLine(bars: Bar[], period = 5): LineData<UTCTimestamp>[] {\n const volBars = bars.map((b) => ({ ...b, c: b.v ?? 0 }));\n return lineData(bars, sma(volBars, period, 'close'));\n}\n\nexport function emaOverlayLine(\n bars: Bar[],\n period: number,\n source: IndicatorConfig['source'] = 'close',\n): LineData<UTCTimestamp>[] {\n const src = barsForSource(bars, source);\n return lineData(bars, ema(src, period));\n}\n\nexport function bollOverlayLines(\n bars: Bar[],\n period: number,\n mult: number,\n source: IndicatorConfig['source'] = 'close',\n): {\n upper: LineData<UTCTimestamp>[];\n middle: LineData<UTCTimestamp>[];\n lower: LineData<UTCTimestamp>[];\n} {\n const src = barsForSource(bars, source);\n const bands = boll(src, period, mult);\n return {\n upper: lineData(bars, bands.upper),\n middle: lineData(bars, bands.middle),\n lower: lineData(bars, bands.lower),\n };\n}","export function attachPaneResizer(\n topPane: HTMLElement,\n bottomPane: HTMLElement,\n opts: { minTopPx?: number; minBottomPx?: number; storageKey?: string } = {},\n): () => void {\n const minTop = opts.minTopPx ?? 120;\n const minBottom = opts.minBottomPx ?? 60;\n const parent = topPane.parentElement;\n if (!parent) return () => {};\n\n const handle = document.createElement('div');\n handle.style.cssText =\n 'height:4px;cursor:row-resize;background:#30363d;flex-shrink:0;touch-action:none;';\n bottomPane.insertAdjacentElement('beforebegin', handle);\n\n const saved = opts.storageKey ? localStorage.getItem(opts.storageKey) : null;\n if (saved) {\n const ratio = Number(saved);\n if (Number.isFinite(ratio) && ratio > 0 && ratio < 1) {\n topPane.style.flex = `${ratio * 10}`;\n bottomPane.style.flex = `${(1 - ratio) * 10}`;\n }\n }\n\n let dragging = false;\n\n const onMove = (clientY: number) => {\n const rect = parent.getBoundingClientRect();\n const y = clientY - rect.top;\n const ratio = Math.min(0.85, Math.max(0.15, y / rect.height));\n const topPx = ratio * rect.height;\n const bottomPx = rect.height - topPx - handle.offsetHeight;\n if (topPx < minTop || bottomPx < minBottom) return;\n topPane.style.flex = `${ratio * 10}`;\n bottomPane.style.flex = `${(1 - ratio) * 10}`;\n if (opts.storageKey) localStorage.setItem(opts.storageKey, String(ratio));\n };\n\n const stop = () => {\n dragging = false;\n document.body.style.cursor = '';\n };\n\n handle.addEventListener('pointerdown', (e) => {\n dragging = true;\n handle.setPointerCapture(e.pointerId);\n document.body.style.cursor = 'row-resize';\n });\n handle.addEventListener('pointermove', (e) => {\n if (dragging) onMove(e.clientY);\n });\n handle.addEventListener('pointerup', stop);\n handle.addEventListener('pointercancel', stop);\n\n return () => handle.remove();\n}","import type { IChartApi, LogicalRange } from 'lightweight-charts';\n\nexport interface TransformState {\n visibleFromMs: number;\n visibleToMs: number;\n width: number;\n height: number;\n}\n\ntype TransformListener = (state: TransformState) => void;\n\n/** Sync visible logical range across multiple LWC panes (§10.4.1). */\nexport class TimeScaleBus {\n private charts: IChartApi[] = [];\n private listeners = new Set<TransformListener>();\n private syncing = false;\n visibleFromMs = 0;\n visibleToMs = 0;\n\n register(chart: IChartApi): void {\n if (this.charts.includes(chart)) return;\n this.charts.push(chart);\n chart.timeScale().subscribeVisibleLogicalRangeChange((range) => {\n if (this.syncing || !range) return;\n const tr = chart.timeScale().getVisibleRange();\n if (tr && typeof tr.from === 'number' && typeof tr.to === 'number') {\n this.visibleFromMs = tr.from * 1000;\n this.visibleToMs = tr.to * 1000;\n }\n this.syncFrom(chart, range);\n });\n }\n\n subscribeTransform(listener: TransformListener): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n setBarsTimeRange(fromMs: number, toMs: number): void {\n this.visibleFromMs = fromMs;\n this.visibleToMs = toMs;\n this.emit();\n }\n\n private syncFrom(source: IChartApi, range: LogicalRange) {\n this.syncing = true;\n for (const chart of this.charts) {\n if (chart !== source) {\n chart.timeScale().setVisibleLogicalRange(range);\n }\n }\n this.syncing = false;\n this.emit();\n }\n\n private emit(): void {\n const state: TransformState = {\n visibleFromMs: this.visibleFromMs,\n visibleToMs: this.visibleToMs,\n width: 0,\n height: 0,\n };\n for (const l of this.listeners) l(state);\n }\n}","import type { Bar } from '@coderyo/data';\n\nfunction lerp(a: number, b: number, t: number): number {\n return a + (b - a) * t;\n}\n\nfunction easeOutCubic(t: number): number {\n return 1 - Math.pow(1 - t, 3);\n}\n\n/** Interpolate last candle OHLC toward target over `durationMs` (interrupts on new target). */\nexport class BarSmoothAnimator {\n private raf = 0;\n private start = 0;\n private from: Bar | null = null;\n private to: Bar | null = null;\n\n constructor(\n private durationMs: number,\n private readonly onFrame: (bar: Bar) => void,\n ) {}\n\n setDuration(ms: number): void {\n this.durationMs = ms;\n }\n\n animateTo(target: Bar, from?: Bar): void {\n if (this.raf) cancelAnimationFrame(this.raf);\n const base = from ?? this.to ?? target;\n this.from = { ...base, t: target.t };\n this.to = { ...target };\n this.start = performance.now();\n\n const step = (now: number) => {\n const raw = Math.min(1, (now - this.start) / this.durationMs);\n const p = easeOutCubic(raw);\n const f = this.from!;\n const t = this.to!;\n const frame: Bar = {\n t: t.t,\n o: lerp(f.o, t.o, p),\n h: lerp(f.h, t.h, p),\n l: lerp(f.l, t.l, p),\n c: lerp(f.c, t.c, p),\n v: t.v,\n };\n this.onFrame(frame);\n if (raw < 1) {\n this.raf = requestAnimationFrame(step);\n } else {\n this.raf = 0;\n this.onFrame(t);\n }\n };\n this.raf = requestAnimationFrame(step);\n }\n\n cancel(): void {\n if (this.raf) cancelAnimationFrame(this.raf);\n this.raf = 0;\n }\n}"],"mappings":"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","names":["ColorType","createChart","HistogramSeries","LineSeries","toUtcSeconds","createChart","LineSeries","HistogramSeries","ColorType"]}
|
|
1
|
+
{"version":3,"sources":["../src/pane-orchestrator.ts","../src/chart-grid.ts","../src/indicator-panes.ts","../src/pane-resize.ts","../src/time-scale-bus.ts","../src/bar-smooth-animator.ts"],"sourcesContent":["import {\n CandlestickSeries,\n ColorType,\n createChart,\n HistogramSeries,\n LineSeries,\n type CandlestickData,\n type HistogramData,\n type WhitespaceData,\n type IChartApi,\n type ISeriesApi,\n type IPriceLine,\n type MouseEventParams,\n type Time,\n type UTCTimestamp,\n} from 'lightweight-charts';\nimport type { Bar } from '@coderyo/data';\nimport { lodDecimateBars } from '@coderyo/series';\nimport { gridOptions } from './chart-grid.js';\nimport type { IndicatorConfig } from '@coderyo/indicators';\n\nimport {\n IndicatorPaneStack,\n bollOverlayLines,\n emaOverlayLine,\n maOverlayLine,\n volMaOverlayLine,\n} from './indicator-panes.js';\nimport { attachPaneResizer } from './pane-resize.js';\nimport { TimeScaleBus, type ChartVisibleRange } from './time-scale-bus.js';\n\nexport type { ChartVisibleRange };\nimport { BarSmoothAnimator } from './bar-smooth-animator.js';\n\nexport type ScaleMode = 'linear' | 'log';\n\nexport interface CrosshairPayload {\n time: number;\n price: number | null;\n ohlcv: { o: number; h: number; l: number; c: number; v?: number } | null;\n}\n\nexport interface PinePlotLine {\n title: string;\n color?: string;\n values: (number | null)[];\n}\n\nexport interface PaneOrchestratorOptions {\n container: HTMLElement;\n indicatorRoot?: HTMLElement;\n theme?: 'dark' | 'light';\n scaleMode?: ScaleMode;\n maxRenderPoints?: number;\n /** Show chart grid lines (default false). */\n showGrid?: boolean;\n /** null = no MA overlays and no MACD/RSI/KDJ panes. */\n indicatorConfig?: IndicatorConfig | null;\n /** Pine-lite plot lines on main chart (when pineEnabled). */\n pinePlots?: PinePlotLine[] | null;\n /** Animate last candle + price line toward new OHLC (~150ms). */\n smoothPriceUpdate?: boolean;\n smoothPriceDurationMs?: number;\n}\n\nfunction toUtcSeconds(tMs: number): UTCTimestamp {\n return Math.floor(tMs / 1000) as UTCTimestamp;\n}\n\nfunction barToCandle(b: Bar): CandlestickData {\n return { time: toUtcSeconds(b.t), open: b.o, high: b.h, low: b.l, close: b.c };\n}\n\nfunction barToVolume(b: Bar): HistogramData<UTCTimestamp> {\n return { time: toUtcSeconds(b.t), value: b.v ?? 0 };\n}\n\nexport class PaneOrchestrator {\n readonly bus = new TimeScaleBus();\n private readonly mainChart: IChartApi;\n private readonly volumeChart: IChartApi;\n private readonly mainSeries: ISeriesApi<'Candlestick'>;\n private readonly volumeSeries: ISeriesApi<'Histogram'>;\n private readonly maSeries: ISeriesApi<'Line'>;\n private readonly emaSeries: ISeriesApi<'Line'>;\n private readonly bollUpper: ISeriesApi<'Line'>;\n private readonly bollMiddle: ISeriesApi<'Line'>;\n private readonly bollLower: ISeriesApi<'Line'>;\n private readonly volMaSeries: ISeriesApi<'Line'>;\n private readonly indicatorRoot?: HTMLElement;\n private indicators: IndicatorPaneStack | null;\n private pinePlotSeries: ISeriesApi<'Line'>[] = [];\n private pinePlots: PinePlotLine[] | null = null;\n private overlayCanvas: HTMLCanvasElement | null = null;\n private dark = true;\n private showGrid = false;\n private readonly maxRenderPoints: number;\n private barByTime = new Map<number, Bar>();\n private barTimesOrdered: number[] = [];\n private didInitialFit = false;\n private skipNextInitialFit = false;\n private indicatorConfig: IndicatorConfig | null = null;\n private priceLine: IPriceLine | null = null;\n private barAnimator: BarSmoothAnimator | null = null;\n private smoothPriceDurationMs = 150;\n\n constructor(opts: PaneOrchestratorOptions) {\n this.maxRenderPoints = opts.maxRenderPoints ?? 4000;\n this.dark = opts.theme !== 'light';\n this.showGrid = opts.showGrid ?? false;\n const layout = this.layoutForTheme(this.dark);\n const grid = gridOptions(this.showGrid, this.dark);\n\n const mainEl = document.createElement('div');\n mainEl.style.cssText = 'flex:7;min-height:120px;width:100%;position:relative;';\n const volEl = document.createElement('div');\n volEl.style.cssText = 'flex:2;min-height:64px;width:100%;position:relative;';\n\n opts.container.style.cssText =\n 'display:flex;flex-direction:column;height:100%;width:100%;min-height:240px;overflow:hidden;';\n opts.container.append(mainEl, volEl);\n attachPaneResizer(mainEl, volEl, { storageKey: 'tradview:pane:main-volume' });\n\n this.mainChart = createChart(mainEl, { layout, grid, autoSize: true });\n this.volumeChart = createChart(volEl, {\n layout,\n grid,\n autoSize: true,\n rightPriceScale: { scaleMargins: { top: 0.8, bottom: 0 } },\n });\n\n if (opts.scaleMode === 'log') {\n this.mainChart.priceScale('right').applyOptions({ mode: 1 });\n }\n\n this.mainSeries = this.mainChart.addSeries(CandlestickSeries, {\n upColor: '#26a69a',\n downColor: '#ef5350',\n borderVisible: false,\n wickUpColor: '#26a69a',\n wickDownColor: '#ef5350',\n });\n this.maSeries = this.mainChart.addSeries(LineSeries, {\n color: '#f0b429',\n lineWidth: 1,\n title: 'MA',\n });\n this.emaSeries = this.mainChart.addSeries(LineSeries, {\n color: '#7ee787',\n lineWidth: 1,\n title: 'EMA',\n visible: false,\n });\n this.bollUpper = this.mainChart.addSeries(LineSeries, {\n color: '#8b949e',\n lineWidth: 1,\n title: 'BOLL↑',\n visible: false,\n });\n this.bollMiddle = this.mainChart.addSeries(LineSeries, {\n color: '#8b949e88',\n lineWidth: 1,\n lineStyle: 2,\n title: 'BOLL',\n visible: false,\n });\n this.bollLower = this.mainChart.addSeries(LineSeries, {\n color: '#8b949e',\n lineWidth: 1,\n title: 'BOLL↓',\n visible: false,\n });\n this.volumeSeries = this.volumeChart.addSeries(HistogramSeries, {\n color: '#26a69a55',\n priceFormat: { type: 'volume' },\n });\n this.volMaSeries = this.volumeChart.addSeries(LineSeries, {\n color: '#58a6ff',\n lineWidth: 1,\n title: 'VolMA5',\n });\n\n this.bus.register(this.mainChart);\n this.bus.register(this.volumeChart);\n\n this.indicatorRoot = opts.indicatorRoot;\n this.indicatorConfig = opts.indicatorConfig ?? null;\n this.pinePlots = opts.pinePlots ?? null;\n this.indicators = this.createIndicatorStack();\n\n this.initOverlay(mainEl);\n this.setSmoothPriceUpdate(opts.smoothPriceUpdate ?? false, opts.smoothPriceDurationMs);\n }\n\n setSmoothPriceUpdate(enabled: boolean, durationMs = 150): void {\n this.smoothPriceDurationMs = durationMs;\n if (enabled) {\n if (!this.barAnimator) {\n this.barAnimator = new BarSmoothAnimator(durationMs, (bar) => this.applyLastBarToSeries(bar));\n } else {\n this.barAnimator.setDuration(durationMs);\n }\n return;\n }\n this.barAnimator?.cancel();\n this.barAnimator = null;\n if (this.priceLine) {\n this.mainSeries.removePriceLine(this.priceLine);\n this.priceLine = null;\n }\n }\n\n /** Update the last candle (and price line); optional smooth interpolation. */\n updateLastBar(target: Bar, opts?: { smooth?: boolean; durationMs?: number }): void {\n const prev = this.barByTime.get(target.t);\n const smooth = opts?.smooth ?? !!this.barAnimator;\n const duration = opts?.durationMs ?? this.smoothPriceDurationMs;\n if (smooth && this.barAnimator) {\n this.barAnimator.setDuration(duration);\n this.barAnimator.animateTo(target, prev ?? target);\n return;\n }\n this.barAnimator?.cancel();\n this.applyLastBarToSeries(target);\n }\n\n private applyLastBarToSeries(bar: Bar): void {\n this.barByTime.set(bar.t, bar);\n this.mainSeries.update(barToCandle(bar));\n this.volumeSeries.update(barToVolume(bar));\n this.ensurePriceLine(bar.c);\n if (this.indicatorConfig) {\n const bars = [...this.barByTime.values()].sort((a, b) => a.t - b.t);\n this.applyMainOverlays(bars);\n this.indicators?.setBars(bars);\n }\n }\n\n private ensurePriceLine(price: number): void {\n if (!this.priceLine) {\n this.priceLine = this.mainSeries.createPriceLine({\n price,\n color: '#58a6ff',\n lineWidth: 1,\n lineStyle: 2,\n axisLabelVisible: true,\n title: '',\n });\n } else {\n this.priceLine.applyOptions({ price });\n }\n }\n\n setTheme(theme: 'dark' | 'light'): void {\n this.dark = theme === 'dark';\n const layout = this.layoutForTheme(this.dark);\n const grid = gridOptions(this.showGrid, this.dark);\n this.mainChart.applyOptions({ layout, grid });\n this.volumeChart.applyOptions({ layout, grid });\n this.indicators?.setTheme(theme);\n }\n\n setIndicatorConfig(config: IndicatorConfig | null): void {\n this.indicatorConfig = config;\n if (!config) {\n this.indicators = null;\n this.maSeries.setData([]);\n this.emaSeries.setData([]);\n this.bollUpper.setData([]);\n this.bollMiddle.setData([]);\n this.bollLower.setData([]);\n this.volMaSeries.setData([]);\n this.emaSeries.applyOptions({ visible: false });\n this.bollUpper.applyOptions({ visible: false });\n this.bollMiddle.applyOptions({ visible: false });\n this.bollLower.applyOptions({ visible: false });\n return;\n }\n if (!this.indicators) this.indicators = this.createIndicatorStack();\n const bars = [...this.barByTime.values()].sort((a, b) => a.t - b.t);\n this.indicators?.setConfig(config);\n if (bars.length > 0) {\n this.applyMainOverlays(bars);\n this.indicators?.setBars(bars);\n }\n }\n\n setPinePlots(plots: PinePlotLine[] | null): void {\n this.pinePlots = plots;\n const bars = [...this.barByTime.values()].sort((a, b) => a.t - b.t);\n this.syncPinePlotSeries(bars);\n }\n\n private applyMainOverlays(bars: Bar[]): void {\n const cfg = this.indicatorConfig;\n if (!cfg) return;\n this.maSeries.applyOptions({ title: `MA${cfg.maPeriod}` });\n this.maSeries.setData(maOverlayLine(bars, cfg.maPeriod, cfg.source));\n this.volMaSeries.setData(volMaOverlayLine(bars, cfg.volMaPeriod));\n\n if (cfg.showEma) {\n this.emaSeries.applyOptions({ visible: true, title: `EMA${cfg.emaPeriod}` });\n this.emaSeries.setData(emaOverlayLine(bars, cfg.emaPeriod, cfg.source));\n } else {\n this.emaSeries.applyOptions({ visible: false });\n this.emaSeries.setData([]);\n }\n\n if (cfg.showBoll) {\n const bands = bollOverlayLines(bars, cfg.bollPeriod, cfg.bollMult, cfg.source);\n this.bollUpper.applyOptions({ visible: true });\n this.bollMiddle.applyOptions({ visible: true });\n this.bollLower.applyOptions({ visible: true });\n this.bollUpper.setData(bands.upper);\n this.bollMiddle.setData(bands.middle);\n this.bollLower.setData(bands.lower);\n } else {\n this.bollUpper.applyOptions({ visible: false });\n this.bollMiddle.applyOptions({ visible: false });\n this.bollLower.applyOptions({ visible: false });\n this.bollUpper.setData([]);\n this.bollMiddle.setData([]);\n this.bollLower.setData([]);\n }\n this.syncPinePlotSeries(bars);\n }\n\n private syncPinePlotSeries(bars: Bar[]): void {\n for (const s of this.pinePlotSeries) this.mainChart.removeSeries(s);\n this.pinePlotSeries = [];\n if (!this.pinePlots?.length || bars.length === 0) return;\n\n const palette = ['#58a6ff', '#d2a8ff', '#ff7b72', '#ffa657'];\n for (let i = 0; i < this.pinePlots.length; i++) {\n const plot = this.pinePlots[i]!;\n const series = this.mainChart.addSeries(LineSeries, {\n color: plot.color ?? palette[i % palette.length]!,\n lineWidth: 1,\n title: plot.title,\n });\n const out: { time: UTCTimestamp; value: number }[] = [];\n for (let j = 0; j < bars.length; j++) {\n const v = plot.values[j];\n if (v == null) continue;\n out.push({ time: toUtcSeconds(bars[j]!.t), value: v });\n }\n series.setData(out);\n this.pinePlotSeries.push(series);\n }\n }\n\n setShowGrid(show: boolean): void {\n this.showGrid = show;\n const grid = gridOptions(show, this.dark);\n this.mainChart.applyOptions({ grid });\n this.volumeChart.applyOptions({ grid });\n this.indicators?.setShowGrid(show);\n }\n\n setBars(bars: Bar[], gaps?: number[]): void {\n const renderBars = lodDecimateBars(bars, this.maxRenderPoints);\n this.barByTime = new Map(renderBars.map((b) => [b.t, b]));\n this.barTimesOrdered = renderBars.map((b) => b.t);\n\n const gapSet = new Set(gaps ?? []);\n const seenTimes = new Set<number>();\n type CandlePoint = CandlestickData | WhitespaceData<UTCTimestamp>;\n const candles: CandlePoint[] = [];\n const vols: HistogramData<UTCTimestamp>[] = [];\n\n for (let i = 0; i < renderBars.length; i++) {\n const b = renderBars[i]!;\n const time = toUtcSeconds(b.t);\n if (seenTimes.has(time)) continue;\n seenTimes.add(time);\n if (gapSet.has(b.t)) {\n candles.push({ time });\n }\n candles.push(barToCandle(b));\n vols.push(barToVolume(b));\n }\n\n this.mainSeries.setData(candles);\n this.volumeSeries.setData(vols);\n if (this.indicatorConfig) {\n this.applyMainOverlays(renderBars);\n this.indicators?.setBars(renderBars);\n } else {\n this.maSeries.setData([]);\n this.emaSeries.setData([]);\n this.bollUpper.setData([]);\n this.bollMiddle.setData([]);\n this.bollLower.setData([]);\n this.volMaSeries.setData([]);\n this.syncPinePlotSeries(renderBars);\n }\n\n if (renderBars.length > 0) {\n this.syncChartSize();\n if (!this.didInitialFit && !this.skipNextInitialFit) {\n this.mainChart.timeScale().fitContent();\n this.volumeChart.timeScale().fitContent();\n this.indicators?.fitContent();\n this.didInitialFit = true;\n }\n this.skipNextInitialFit = false;\n }\n }\n\n subscribeCrosshair(listener: (payload: CrosshairPayload | null) => void): () => void {\n const handler = (param: MouseEventParams<Time>) => {\n if (param.time == null || !param.point) {\n listener(null);\n return;\n }\n const tMs = typeof param.time === 'number' ? param.time * 1000 : null;\n if (tMs == null) {\n listener(null);\n return;\n }\n const price = this.mainSeries.coordinateToPrice(param.point.y) ?? null;\n const bar = this.barByTime.get(tMs) ?? this.findNearestBar(tMs);\n listener({\n time: tMs,\n price,\n ohlcv: bar\n ? { o: bar.o, h: bar.h, l: bar.l, c: bar.c, v: bar.v }\n : null,\n });\n };\n this.mainChart.subscribeCrosshairMove(handler);\n return () => this.mainChart.unsubscribeCrosshairMove(handler);\n }\n\n private findNearestBar(tMs: number): Bar | null {\n let best: Bar | null = null;\n let bestDt = Infinity;\n for (const b of this.barByTime.values()) {\n const dt = Math.abs(b.t - tMs);\n if (dt < bestDt) {\n bestDt = dt;\n best = b;\n }\n }\n return bestDt < 120_000 ? best : null;\n }\n\n private createIndicatorStack(): IndicatorPaneStack | null {\n if (!this.indicatorRoot || !this.indicatorConfig) return null;\n return new IndicatorPaneStack(this.indicatorRoot, this.bus, {\n theme: this.dark ? 'dark' : 'light',\n showGrid: this.showGrid,\n config: this.indicatorConfig,\n });\n }\n\n resetViewState(): void {\n this.didInitialFit = false;\n this.skipNextInitialFit = false;\n this.bus.visibleFromMs = 0;\n this.bus.visibleToMs = 0;\n }\n\n /** Skip the next automatic fitContent after setBars (used by reloadHistory). */\n preserveViewportOnNextSetBars(): void {\n this.skipNextInitialFit = true;\n this.didInitialFit = true;\n }\n\n getVisibleRange(): ChartVisibleRange | null {\n return this.bus.getVisibleRange();\n }\n\n getBarSpace(): number {\n return this.bus.getBarSpacing();\n }\n\n setBarSpace(px: number): void {\n this.bus.setBarSpacing(px);\n }\n\n setVisibleRange(range: ChartVisibleRange): void {\n this.bus.setVisibleTimeRange(range);\n this.didInitialFit = true;\n }\n\n scrollToTimestamp(tsMs: number, animationMs?: number): void {\n const time = toUtcSeconds(tsMs);\n const idx = this.mainChart.timeScale().timeToIndex(time, true);\n if (idx == null) {\n const nearest = this.findNearestBar(tsMs);\n if (nearest == null) return;\n const i = this.barTimesOrdered.indexOf(nearest.t);\n if (i < 0) return;\n this.bus.scrollToLogicalPosition(i, (animationMs ?? 0) > 0);\n return;\n }\n this.bus.scrollToLogicalPosition(idx as number, (animationMs ?? 0) > 0);\n }\n\n /** Clear series while symbol/interval data reloads (avoids overlapping candles). */\n clearBars(): void {\n this.barAnimator?.cancel();\n this.barByTime = new Map();\n this.barTimesOrdered = [];\n this.mainSeries.setData([]);\n this.maSeries.setData([]);\n this.volumeSeries.setData([]);\n this.volMaSeries.setData([]);\n this.indicators?.clearBars();\n }\n\n fitContent(): void {\n this.mainChart.timeScale().fitContent();\n this.volumeChart.timeScale().fitContent();\n this.indicators?.fitContent();\n this.didInitialFit = true;\n }\n\n scrollToRealtime(): void {\n this.mainChart.timeScale().scrollToRealTime();\n this.volumeChart.timeScale().scrollToRealTime();\n this.indicators?.scrollToRealtime();\n }\n\n setLogScale(enabled: boolean): void {\n this.mainChart.priceScale('right').applyOptions({ mode: enabled ? 1 : 0 });\n }\n\n resize(): void {\n this.syncChartSize();\n this.syncOverlaySize();\n this.indicators?.resize();\n }\n\n getOverlayCanvas(): HTMLCanvasElement | null {\n return this.overlayCanvas;\n }\n\n timeToX(tMs: number): number | null {\n const coord = this.mainChart.timeScale().timeToCoordinate(toUtcSeconds(tMs));\n if (coord == null) return null;\n return coord * devicePixelRatio;\n }\n\n priceToY(price: number): number | null {\n const coord = this.mainSeries.priceToCoordinate(price);\n if (coord == null) return null;\n return coord * devicePixelRatio;\n }\n\n xToTime(x: number): number | null {\n const t = this.mainChart.timeScale().coordinateToTime(x / devicePixelRatio);\n if (t == null) return null;\n return Number(t) * 1000;\n }\n\n yToPrice(y: number): number | null {\n const p = this.mainSeries.coordinateToPrice(y / devicePixelRatio);\n return p ?? null;\n }\n\n destroy(): void {\n this.barAnimator?.cancel();\n if (this.priceLine) {\n this.mainSeries.removePriceLine(this.priceLine);\n this.priceLine = null;\n }\n this.mainChart.remove();\n this.volumeChart.remove();\n this.indicators?.destroy();\n this.overlayCanvas?.remove();\n }\n\n private initOverlay(parent: HTMLElement) {\n const canvas = document.createElement('canvas');\n canvas.style.cssText =\n 'position:absolute;left:0;top:0;width:100%;height:100%;pointer-events:none;z-index:10;';\n parent.style.position = 'relative';\n parent.appendChild(canvas);\n this.overlayCanvas = canvas;\n this.syncOverlaySize();\n this.bus.subscribeTransform(() => {\n this.syncOverlaySize();\n });\n }\n\n /** Let drawing overlay receive clicks; cursor mode keeps pan/zoom on LWC. */\n setOverlayPointerEvents(mode: 'auto' | 'none'): void {\n if (this.overlayCanvas) this.overlayCanvas.style.pointerEvents = mode;\n }\n\n private syncOverlaySize() {\n if (!this.overlayCanvas?.parentElement) return;\n const parent = this.overlayCanvas.parentElement;\n if (parent.lastElementChild !== this.overlayCanvas) {\n parent.appendChild(this.overlayCanvas);\n }\n const rect = parent.getBoundingClientRect();\n this.overlayCanvas.width = rect.width * devicePixelRatio;\n this.overlayCanvas.height = rect.height * devicePixelRatio;\n }\n\n private syncChartSize(): void {\n const mainEl = this.mainChart.chartElement().parentElement;\n const volEl = this.volumeChart.chartElement().parentElement;\n if (mainEl) {\n const w = mainEl.clientWidth;\n const h = mainEl.clientHeight;\n if (w > 0 && h > 0) this.mainChart.resize(w, h);\n }\n if (volEl) {\n const w = volEl.clientWidth;\n const h = volEl.clientHeight;\n if (w > 0 && h > 0) this.volumeChart.resize(w, h);\n }\n }\n\n private layoutForTheme(dark: boolean) {\n return {\n background: { type: ColorType.Solid, color: dark ? '#0d1117' : '#ffffff' },\n textColor: dark ? '#e6edf3' : '#24292f',\n };\n }\n}","/** LWC grid line options — default off per product spec. */\nexport function gridOptions(showGrid: boolean, dark: boolean) {\n const color = dark ? '#21262d' : '#d0d7de';\n return {\n vertLines: { visible: showGrid, color },\n horzLines: { visible: showGrid, color },\n };\n}","import {\n ColorType,\n createChart,\n HistogramSeries,\n LineSeries,\n type HistogramData,\n type IChartApi,\n type ISeriesApi,\n type LineData,\n type UTCTimestamp,\n} from 'lightweight-charts';\nimport type { Bar } from '@coderyo/data';\nimport {\n type IndicatorConfig,\n DEFAULT_INDICATOR_CONFIG,\n boll,\n kdj,\n macd,\n rsi,\n sma,\n ema,\n} from '@coderyo/indicators';\nimport { gridOptions } from './chart-grid.js';\nimport type { TimeScaleBus } from './time-scale-bus.js';\n\nexport interface IndicatorPaneStackOptions {\n theme?: 'dark' | 'light';\n showGrid?: boolean;\n config?: IndicatorConfig;\n}\n\nfunction barsForSource(bars: Bar[], source: IndicatorConfig['source']): Bar[] {\n if (source === 'close') return bars;\n return bars.map((b) => ({ ...b, c: (b.h + b.l + b.c) / 3 }));\n}\n\nfunction toUtcSeconds(tMs: number): UTCTimestamp {\n return Math.floor(tMs / 1000) as UTCTimestamp;\n}\n\nfunction lineData(bars: Bar[], values: (number | null)[]): LineData<UTCTimestamp>[] {\n const out: LineData<UTCTimestamp>[] = [];\n for (let i = 0; i < bars.length; i++) {\n const v = values[i];\n if (v == null) continue;\n out.push({ time: toUtcSeconds(bars[i]!.t), value: v });\n }\n return out;\n}\n\nfunction histData(bars: Bar[], values: (number | null)[]): HistogramData<UTCTimestamp>[] {\n const out: HistogramData<UTCTimestamp>[] = [];\n for (let i = 0; i < bars.length; i++) {\n const v = values[i];\n if (v == null) continue;\n out.push({\n time: toUtcSeconds(bars[i]!.t),\n value: v,\n color: v >= 0 ? '#26a69a88' : '#ef535088',\n });\n }\n return out;\n}\n\nexport class IndicatorPaneStack {\n private readonly macdChart: IChartApi;\n private readonly rsiChart: IChartApi;\n private readonly kdjChart: IChartApi;\n private readonly macdLine: ISeriesApi<'Line'>;\n private readonly macdSignal: ISeriesApi<'Line'>;\n private readonly macdHist: ISeriesApi<'Histogram'>;\n private readonly rsiLine: ISeriesApi<'Line'>;\n private readonly kdjK: ISeriesApi<'Line'>;\n private readonly kdjD: ISeriesApi<'Line'>;\n private readonly kdjJ: ISeriesApi<'Line'>;\n private dark = true;\n private showGrid = false;\n private config: IndicatorConfig = DEFAULT_INDICATOR_CONFIG;\n private readonly macdWrap: HTMLElement;\n private readonly rsiWrap: HTMLElement;\n private readonly kdjWrap: HTMLElement;\n\n constructor(\n private readonly root: HTMLElement,\n bus: TimeScaleBus,\n opts: IndicatorPaneStackOptions | 'dark' | 'light' = 'dark',\n ) {\n const o = typeof opts === 'string' ? { theme: opts, showGrid: false } : opts;\n this.dark = o.theme !== 'light';\n this.showGrid = o.showGrid ?? false;\n this.config = o.config ?? DEFAULT_INDICATOR_CONFIG;\n this.root.style.display = 'flex';\n this.root.style.flexDirection = 'column';\n this.root.style.flex = '2';\n this.root.style.minHeight = '0';\n this.root.style.overflow = 'hidden';\n\n const macdPane = this.createPaneWrap('MACD');\n const rsiPane = this.createPaneWrap('RSI');\n const kdjPane = this.createPaneWrap('KDJ');\n this.macdWrap = macdPane.wrap;\n this.rsiWrap = rsiPane.wrap;\n this.kdjWrap = kdjPane.wrap;\n this.root.append(macdPane.wrap, rsiPane.wrap, kdjPane.wrap);\n this.applyPaneVisibility();\n\n const layout = this.layoutForTheme(this.dark);\n const grid = gridOptions(this.showGrid, this.dark);\n this.macdChart = createChart(macdPane.el, { layout, grid, autoSize: true });\n this.rsiChart = createChart(rsiPane.el, { layout, grid, autoSize: true });\n this.kdjChart = createChart(kdjPane.el, { layout, grid, autoSize: true });\n\n for (const c of [this.macdChart, this.rsiChart, this.kdjChart]) bus.register(c);\n\n this.macdLine = this.macdChart.addSeries(LineSeries, { color: '#2962ff', lineWidth: 1 });\n this.macdSignal = this.macdChart.addSeries(LineSeries, { color: '#ff9800', lineWidth: 1 });\n this.macdHist = this.macdChart.addSeries(HistogramSeries, {\n priceFormat: { type: 'price', precision: 4, minMove: 0.0001 },\n });\n this.rsiLine = this.rsiChart.addSeries(LineSeries, { color: '#ab47bc', lineWidth: 1 });\n this.kdjK = this.kdjChart.addSeries(LineSeries, { color: '#42a5f5', lineWidth: 1 });\n this.kdjD = this.kdjChart.addSeries(LineSeries, { color: '#ffa726', lineWidth: 1 });\n this.kdjJ = this.kdjChart.addSeries(LineSeries, { color: '#ef5350', lineWidth: 1 });\n }\n\n setConfig(config: IndicatorConfig): void {\n this.config = config;\n this.applyPaneVisibility();\n }\n\n private applyPaneVisibility(): void {\n this.macdWrap.style.display = this.config.showMacd ? '' : 'none';\n this.rsiWrap.style.display = this.config.showRsi ? '' : 'none';\n this.kdjWrap.style.display = this.config.showKdj ? '' : 'none';\n }\n\n clearBars(): void {\n this.macdLine.setData([]);\n this.macdSignal.setData([]);\n this.macdHist.setData([]);\n this.rsiLine.setData([]);\n this.kdjK.setData([]);\n this.kdjD.setData([]);\n this.kdjJ.setData([]);\n }\n\n setBars(bars: Bar[]): void {\n if (bars.length === 0) return;\n const src = barsForSource(bars, this.config.source);\n const m = macd(src, this.config.macdFast, this.config.macdSlow, this.config.macdSignal);\n this.macdLine.setData(lineData(bars, m.macd));\n this.macdSignal.setData(lineData(bars, m.signal));\n this.macdHist.setData(histData(bars, m.histogram));\n\n this.rsiLine.setData(lineData(bars, rsi(src, this.config.rsiPeriod)));\n\n const k = kdj(src, this.config.kdjPeriod, this.config.kdjKSmooth, this.config.kdjDSmooth);\n this.kdjK.setData(lineData(bars, k.k));\n this.kdjD.setData(lineData(bars, k.d));\n this.kdjJ.setData(lineData(bars, k.j));\n\n this.macdChart.timeScale().fitContent();\n this.rsiChart.timeScale().fitContent();\n this.kdjChart.timeScale().fitContent();\n this.resize();\n }\n\n setTheme(theme: 'dark' | 'light'): void {\n this.dark = theme === 'dark';\n const layout = this.layoutForTheme(this.dark);\n const grid = gridOptions(this.showGrid, this.dark);\n this.macdChart.applyOptions({ layout, grid });\n this.rsiChart.applyOptions({ layout, grid });\n this.kdjChart.applyOptions({ layout, grid });\n }\n\n setShowGrid(show: boolean): void {\n this.showGrid = show;\n const grid = gridOptions(show, this.dark);\n this.macdChart.applyOptions({ grid });\n this.rsiChart.applyOptions({ grid });\n this.kdjChart.applyOptions({ grid });\n }\n\n fitContent(): void {\n this.macdChart.timeScale().fitContent();\n this.rsiChart.timeScale().fitContent();\n this.kdjChart.timeScale().fitContent();\n }\n\n scrollToRealtime(): void {\n this.macdChart.timeScale().scrollToRealTime();\n this.rsiChart.timeScale().scrollToRealTime();\n this.kdjChart.timeScale().scrollToRealTime();\n }\n\n resize(): void {\n for (const { chart, el } of [\n { chart: this.macdChart, el: this.macdChart.chartElement().parentElement },\n { chart: this.rsiChart, el: this.rsiChart.chartElement().parentElement },\n { chart: this.kdjChart, el: this.kdjChart.chartElement().parentElement },\n ]) {\n if (!el) continue;\n const w = el.clientWidth;\n const h = el.clientHeight;\n if (w > 0 && h > 0) chart.resize(w, h);\n }\n }\n\n destroy(): void {\n this.macdChart.remove();\n this.rsiChart.remove();\n this.kdjChart.remove();\n this.root.replaceChildren();\n }\n\n private createPaneWrap(label: string): { wrap: HTMLElement; el: HTMLElement } {\n const wrap = document.createElement('div');\n wrap.style.cssText =\n 'flex:1;min-height:72px;width:100%;position:relative;border-top:1px solid #30363d;';\n const tag = document.createElement('span');\n tag.textContent = label;\n tag.style.cssText =\n 'position:absolute;left:6px;top:4px;z-index:2;font-size:10px;color:#8b949e;pointer-events:none;';\n const el = document.createElement('div');\n el.style.cssText = 'width:100%;height:100%;';\n wrap.append(tag, el);\n return { wrap, el };\n }\n\n private layoutForTheme(dark: boolean) {\n return {\n background: { type: ColorType.Solid, color: dark ? '#0d1117' : '#ffffff' },\n textColor: dark ? '#e6edf3' : '#24292f',\n };\n }\n}\n\nexport function maOverlayLine(\n bars: Bar[],\n period = 20,\n source: IndicatorConfig['source'] = 'close',\n): LineData<UTCTimestamp>[] {\n const src = barsForSource(bars, source);\n return lineData(bars, sma(src, period));\n}\n\nexport function volMaOverlayLine(bars: Bar[], period = 5): LineData<UTCTimestamp>[] {\n const volBars = bars.map((b) => ({ ...b, c: b.v ?? 0 }));\n return lineData(bars, sma(volBars, period, 'close'));\n}\n\nexport function emaOverlayLine(\n bars: Bar[],\n period: number,\n source: IndicatorConfig['source'] = 'close',\n): LineData<UTCTimestamp>[] {\n const src = barsForSource(bars, source);\n return lineData(bars, ema(src, period));\n}\n\nexport function bollOverlayLines(\n bars: Bar[],\n period: number,\n mult: number,\n source: IndicatorConfig['source'] = 'close',\n): {\n upper: LineData<UTCTimestamp>[];\n middle: LineData<UTCTimestamp>[];\n lower: LineData<UTCTimestamp>[];\n} {\n const src = barsForSource(bars, source);\n const bands = boll(src, period, mult);\n return {\n upper: lineData(bars, bands.upper),\n middle: lineData(bars, bands.middle),\n lower: lineData(bars, bands.lower),\n };\n}","export function attachPaneResizer(\n topPane: HTMLElement,\n bottomPane: HTMLElement,\n opts: { minTopPx?: number; minBottomPx?: number; storageKey?: string } = {},\n): () => void {\n const minTop = opts.minTopPx ?? 120;\n const minBottom = opts.minBottomPx ?? 60;\n const parent = topPane.parentElement;\n if (!parent) return () => {};\n\n const handle = document.createElement('div');\n handle.style.cssText =\n 'height:4px;cursor:row-resize;background:#30363d;flex-shrink:0;touch-action:none;';\n bottomPane.insertAdjacentElement('beforebegin', handle);\n\n const saved = opts.storageKey ? localStorage.getItem(opts.storageKey) : null;\n if (saved) {\n const ratio = Number(saved);\n if (Number.isFinite(ratio) && ratio > 0 && ratio < 1) {\n topPane.style.flex = `${ratio * 10}`;\n bottomPane.style.flex = `${(1 - ratio) * 10}`;\n }\n }\n\n let dragging = false;\n\n const onMove = (clientY: number) => {\n const rect = parent.getBoundingClientRect();\n const y = clientY - rect.top;\n const ratio = Math.min(0.85, Math.max(0.15, y / rect.height));\n const topPx = ratio * rect.height;\n const bottomPx = rect.height - topPx - handle.offsetHeight;\n if (topPx < minTop || bottomPx < minBottom) return;\n topPane.style.flex = `${ratio * 10}`;\n bottomPane.style.flex = `${(1 - ratio) * 10}`;\n if (opts.storageKey) localStorage.setItem(opts.storageKey, String(ratio));\n };\n\n const stop = () => {\n dragging = false;\n document.body.style.cursor = '';\n };\n\n handle.addEventListener('pointerdown', (e) => {\n dragging = true;\n handle.setPointerCapture(e.pointerId);\n document.body.style.cursor = 'row-resize';\n });\n handle.addEventListener('pointermove', (e) => {\n if (dragging) onMove(e.clientY);\n });\n handle.addEventListener('pointerup', stop);\n handle.addEventListener('pointercancel', stop);\n\n return () => handle.remove();\n}","import type { IChartApi, LogicalRange, UTCTimestamp } from 'lightweight-charts';\n\nexport interface ChartVisibleRange {\n fromMs: number;\n toMs: number;\n}\n\nexport interface TransformState {\n visibleFromMs: number;\n visibleToMs: number;\n width: number;\n height: number;\n}\n\ntype TransformListener = (state: TransformState) => void;\n\n/** Sync visible logical range across multiple LWC panes (§10.4.1). */\nexport class TimeScaleBus {\n private charts: IChartApi[] = [];\n private listeners = new Set<TransformListener>();\n private syncing = false;\n visibleFromMs = 0;\n visibleToMs = 0;\n\n register(chart: IChartApi): void {\n if (this.charts.includes(chart)) return;\n this.charts.push(chart);\n chart.timeScale().subscribeVisibleLogicalRangeChange((range) => {\n if (this.syncing || !range) return;\n const tr = chart.timeScale().getVisibleRange();\n if (tr && typeof tr.from === 'number' && typeof tr.to === 'number') {\n this.visibleFromMs = tr.from * 1000;\n this.visibleToMs = tr.to * 1000;\n }\n this.syncFrom(chart, range);\n });\n }\n\n subscribeTransform(listener: TransformListener): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n setBarsTimeRange(fromMs: number, toMs: number): void {\n this.visibleFromMs = fromMs;\n this.visibleToMs = toMs;\n this.emit();\n }\n\n getVisibleRange(): ChartVisibleRange | null {\n if (this.visibleToMs <= this.visibleFromMs) return null;\n return { fromMs: this.visibleFromMs, toMs: this.visibleToMs };\n }\n\n getBarSpacing(): number {\n const chart = this.charts[0];\n return chart ? chart.timeScale().options().barSpacing : 6;\n }\n\n setBarSpacing(spacing: number): void {\n if (!Number.isFinite(spacing) || spacing <= 0) return;\n this.syncing = true;\n for (const chart of this.charts) {\n chart.timeScale().applyOptions({ barSpacing: spacing });\n }\n this.syncing = false;\n this.emit();\n }\n\n setVisibleTimeRange(range: ChartVisibleRange): void {\n const from = Math.floor(range.fromMs / 1000) as UTCTimestamp;\n const to = Math.floor(range.toMs / 1000) as UTCTimestamp;\n if (to <= from) return;\n this.visibleFromMs = range.fromMs;\n this.visibleToMs = range.toMs;\n this.syncing = true;\n for (const chart of this.charts) {\n chart.timeScale().setVisibleRange({ from, to });\n }\n this.syncing = false;\n this.emit();\n }\n\n scrollToLogicalPosition(position: number, animated = false): void {\n this.syncing = true;\n for (const chart of this.charts) {\n chart.timeScale().scrollToPosition(position, animated);\n }\n this.syncing = false;\n this.emit();\n }\n\n private syncFrom(source: IChartApi, range: LogicalRange) {\n this.syncing = true;\n for (const chart of this.charts) {\n if (chart !== source) {\n chart.timeScale().setVisibleLogicalRange(range);\n }\n }\n this.syncing = false;\n this.emit();\n }\n\n private emit(): void {\n const state: TransformState = {\n visibleFromMs: this.visibleFromMs,\n visibleToMs: this.visibleToMs,\n width: 0,\n height: 0,\n };\n for (const l of this.listeners) l(state);\n }\n}","import type { Bar } from '@coderyo/data';\n\nfunction lerp(a: number, b: number, t: number): number {\n return a + (b - a) * t;\n}\n\nfunction easeOutCubic(t: number): number {\n return 1 - Math.pow(1 - t, 3);\n}\n\n/** Interpolate last candle OHLC toward target over `durationMs` (interrupts on new target). */\nexport class BarSmoothAnimator {\n private raf = 0;\n private start = 0;\n private from: Bar | null = null;\n private to: Bar | null = null;\n\n constructor(\n private durationMs: number,\n private readonly onFrame: (bar: Bar) => void,\n ) {}\n\n setDuration(ms: number): void {\n this.durationMs = ms;\n }\n\n animateTo(target: Bar, from?: Bar): void {\n if (this.raf) cancelAnimationFrame(this.raf);\n const base = from ?? this.to ?? target;\n this.from = { ...base, t: target.t };\n this.to = { ...target };\n this.start = performance.now();\n\n const step = (now: number) => {\n const raw = Math.min(1, (now - this.start) / this.durationMs);\n const p = easeOutCubic(raw);\n const f = this.from!;\n const t = this.to!;\n const frame: Bar = {\n t: t.t,\n o: lerp(f.o, t.o, p),\n h: lerp(f.h, t.h, p),\n l: lerp(f.l, t.l, p),\n c: lerp(f.c, t.c, p),\n v: t.v,\n };\n this.onFrame(frame);\n if (raw < 1) {\n this.raf = requestAnimationFrame(step);\n } else {\n this.raf = 0;\n this.onFrame(t);\n }\n };\n this.raf = requestAnimationFrame(step);\n }\n\n cancel(): void {\n if (this.raf) cancelAnimationFrame(this.raf);\n this.raf = 0;\n }\n}"],"mappings":"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","names":["ColorType","createChart","HistogramSeries","LineSeries","toUtcSeconds","createChart","LineSeries","HistogramSeries","ColorType"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coderyo/renderer-lite",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -11,16 +11,16 @@
|
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"lightweight-charts": "^5.0.7",
|
|
14
|
-
"@coderyo/data": "1.0.
|
|
15
|
-
"@coderyo/
|
|
16
|
-
"@coderyo/
|
|
14
|
+
"@coderyo/data": "1.0.1",
|
|
15
|
+
"@coderyo/series": "1.0.1",
|
|
16
|
+
"@coderyo/indicators": "1.0.1"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
19
|
"tsup": "^8.5.0",
|
|
20
20
|
"typescript": "^5.8.3",
|
|
21
21
|
"vitest": "^3.2.4",
|
|
22
|
-
"@coderyo/
|
|
23
|
-
"@coderyo/
|
|
22
|
+
"@coderyo/tsconfig": "0.0.0",
|
|
23
|
+
"@coderyo/eslint-config": "0.0.0"
|
|
24
24
|
},
|
|
25
25
|
"files": [
|
|
26
26
|
"dist"
|