@funnest/charts 0.6.2 → 0.6.4
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/chart.d.ts +8 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +69 -10
- package/dist/settings.d.ts +21 -0
- package/package.json +1 -1
package/dist/chart.d.ts
CHANGED
|
@@ -209,6 +209,14 @@ export declare class Chart {
|
|
|
209
209
|
private connectionState;
|
|
210
210
|
private readonly displayTimezone;
|
|
211
211
|
private loadingHistory;
|
|
212
|
+
/**
|
|
213
|
+
* Bumped by every data replacement (setData) and history request: a page answers only if it
|
|
214
|
+
* is still the latest request for the bars on screen. (The load token alone isn't enough — a
|
|
215
|
+
* page requested while setSymbol() awaits carries the new token but the old symbol's bars.)
|
|
216
|
+
*/
|
|
217
|
+
private historyRequest;
|
|
218
|
+
/** setSymbol() is between its request and setData(). */
|
|
219
|
+
private symbolLoading;
|
|
212
220
|
private noMoreHistory;
|
|
213
221
|
private historyRequestedFor;
|
|
214
222
|
private countdownLabel;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { Chart, createChart, fallbackResolution } from './chart';
|
|
2
|
-
export { DEFAULT_CHART_SETTINGS, parseChartState } from './settings';
|
|
3
|
-
export type { ChartSettings, ChartState } from './settings';
|
|
2
|
+
export { CHART_THEMES, DEFAULT_CHART_SETTINGS, matchChartTheme, parseChartState } from './settings';
|
|
3
|
+
export type { ChartSettings, ChartState, ChartThemeColors, ChartThemePreset } from './settings';
|
|
4
4
|
export type { ChartContextMenu, ChartEvents, ChartLayout, ChartOptions, ChartPaneLayout, CompareInfo, IndicatorLegendItem, ReplayStatus } from './chart';
|
|
5
5
|
export type { PriceScaleMode } from './model/price-scale';
|
|
6
6
|
export type { CrosshairInfo, PaneId } from './render/renderer';
|
package/dist/index.js
CHANGED
|
@@ -1793,6 +1793,41 @@ function snapToOhlc(bar, y, priceToY) {
|
|
|
1793
1793
|
}
|
|
1794
1794
|
|
|
1795
1795
|
// src/settings.ts
|
|
1796
|
+
var FOLLOW = { upColor: null, downColor: null, background: null, gridColor: null, textColor: null };
|
|
1797
|
+
var CHART_THEMES = [
|
|
1798
|
+
{ id: "default", name: { ko: "\uAE30\uBCF8", en: "Default" }, colors: FOLLOW },
|
|
1799
|
+
{ id: "global", name: { ko: "\uCD08\uB85D\xB7\uBE68\uAC15", en: "Green \xB7 Red" }, colors: { ...FOLLOW, upColor: "#26A69A", downColor: "#EF5350" } },
|
|
1800
|
+
{
|
|
1801
|
+
id: "midnight",
|
|
1802
|
+
name: { ko: "\uBBF8\uB4DC\uB098\uC787", en: "Midnight" },
|
|
1803
|
+
colors: { upColor: "#2EBD85", downColor: "#F6465D", background: "#0E1117", gridColor: "#1A1F29", textColor: "#C9D1D9" }
|
|
1804
|
+
},
|
|
1805
|
+
{
|
|
1806
|
+
id: "navy",
|
|
1807
|
+
name: { ko: "\uB525 \uB124\uC774\uBE44", en: "Deep navy" },
|
|
1808
|
+
colors: { upColor: "#FF5A5F", downColor: "#4C8DFF", background: "#0F1A2E", gridColor: "#1B2A44", textColor: "#C8D3E6" }
|
|
1809
|
+
},
|
|
1810
|
+
{
|
|
1811
|
+
id: "mono",
|
|
1812
|
+
name: { ko: "\uBAA8\uB178", en: "Mono" },
|
|
1813
|
+
colors: { upColor: "#E4E4E7", downColor: "#6B6B75", background: "#121214", gridColor: "#1F1F23", textColor: "#D4D4D8" }
|
|
1814
|
+
},
|
|
1815
|
+
{
|
|
1816
|
+
id: "paper",
|
|
1817
|
+
name: { ko: "\uD398\uC774\uD37C", en: "Paper" },
|
|
1818
|
+
colors: { upColor: "#F04452", downColor: "#3182F6", background: "#FFFFFF", gridColor: "#F0F2F5", textColor: "#333D4B" }
|
|
1819
|
+
},
|
|
1820
|
+
{
|
|
1821
|
+
id: "sepia",
|
|
1822
|
+
name: { ko: "\uC138\uD53C\uC544", en: "Sepia" },
|
|
1823
|
+
colors: { upColor: "#C2410C", downColor: "#2F6690", background: "#F6F0E4", gridColor: "#E9DFCB", textColor: "#4A3F33" }
|
|
1824
|
+
}
|
|
1825
|
+
];
|
|
1826
|
+
function matchChartTheme(settings) {
|
|
1827
|
+
const keys = Object.keys(FOLLOW);
|
|
1828
|
+
const same = (a, b) => (a ?? "").toLowerCase() === (b ?? "").toLowerCase();
|
|
1829
|
+
return CHART_THEMES.find((t) => keys.every((k) => same(t.colors[k], settings[k])));
|
|
1830
|
+
}
|
|
1796
1831
|
var DEFAULT_CHART_SETTINGS = {
|
|
1797
1832
|
highLowMarkers: true,
|
|
1798
1833
|
lastPriceLine: true,
|
|
@@ -1803,7 +1838,10 @@ var DEFAULT_CHART_SETTINGS = {
|
|
|
1803
1838
|
priceScale: "normal",
|
|
1804
1839
|
countdown: true,
|
|
1805
1840
|
upColor: null,
|
|
1806
|
-
downColor: null
|
|
1841
|
+
downColor: null,
|
|
1842
|
+
background: null,
|
|
1843
|
+
gridColor: null,
|
|
1844
|
+
textColor: null
|
|
1807
1845
|
};
|
|
1808
1846
|
var CHART_TYPES = ["candles", "line", "area"];
|
|
1809
1847
|
function parseChartState(input) {
|
|
@@ -2684,6 +2722,14 @@ var Chart = class {
|
|
|
2684
2722
|
connectionState = null;
|
|
2685
2723
|
displayTimezone;
|
|
2686
2724
|
loadingHistory = false;
|
|
2725
|
+
/**
|
|
2726
|
+
* Bumped by every data replacement (setData) and history request: a page answers only if it
|
|
2727
|
+
* is still the latest request for the bars on screen. (The load token alone isn't enough — a
|
|
2728
|
+
* page requested while setSymbol() awaits carries the new token but the old symbol's bars.)
|
|
2729
|
+
*/
|
|
2730
|
+
historyRequest = 0;
|
|
2731
|
+
/** setSymbol() is between its request and setData(). */
|
|
2732
|
+
symbolLoading = false;
|
|
2687
2733
|
noMoreHistory = false;
|
|
2688
2734
|
historyRequestedFor = Number.NaN;
|
|
2689
2735
|
countdownLabel = null;
|
|
@@ -2765,6 +2811,8 @@ var Chart = class {
|
|
|
2765
2811
|
this.volumeScale.autoScale = true;
|
|
2766
2812
|
this.noMoreHistory = false;
|
|
2767
2813
|
this.historyRequestedFor = Number.NaN;
|
|
2814
|
+
this.historyRequest++;
|
|
2815
|
+
this.loadingHistory = false;
|
|
2768
2816
|
this.dataVersion++;
|
|
2769
2817
|
this.invalidate();
|
|
2770
2818
|
}
|
|
@@ -2817,6 +2865,7 @@ var Chart = class {
|
|
|
2817
2865
|
this.quoteSymbol = null;
|
|
2818
2866
|
}
|
|
2819
2867
|
this.emitter.emit("loadingChange", true);
|
|
2868
|
+
this.symbolLoading = true;
|
|
2820
2869
|
let info;
|
|
2821
2870
|
let result;
|
|
2822
2871
|
try {
|
|
@@ -2831,7 +2880,10 @@ var Chart = class {
|
|
|
2831
2880
|
});
|
|
2832
2881
|
if (token !== this.loadToken) return;
|
|
2833
2882
|
} finally {
|
|
2834
|
-
if (token === this.loadToken)
|
|
2883
|
+
if (token === this.loadToken) {
|
|
2884
|
+
this.symbolLoading = false;
|
|
2885
|
+
this.emitter.emit("loadingChange", false);
|
|
2886
|
+
}
|
|
2835
2887
|
}
|
|
2836
2888
|
const previous = this.symbol?.symbol ?? "";
|
|
2837
2889
|
if (previous !== info.symbol) {
|
|
@@ -3994,14 +4046,16 @@ var Chart = class {
|
|
|
3994
4046
|
}
|
|
3995
4047
|
resolvePalette() {
|
|
3996
4048
|
const t = this.theme;
|
|
4049
|
+
const s = this.settingsValue;
|
|
3997
4050
|
const c = (v) => this.colors.color(v);
|
|
4051
|
+
const muted = s.textColor && /^#[0-9a-f]{6}$/i.test(s.textColor) ? `${s.textColor}99` : null;
|
|
3998
4052
|
return {
|
|
3999
|
-
background: c(t.background),
|
|
4000
|
-
text: c(t.text),
|
|
4001
|
-
textSecondary: c(t.textSecondary),
|
|
4002
|
-
grid: c(t.grid),
|
|
4003
|
-
border: c(t.border),
|
|
4004
|
-
crosshair: c(t.crosshair),
|
|
4053
|
+
background: c(s.background ?? t.background),
|
|
4054
|
+
text: c(s.textColor ?? t.text),
|
|
4055
|
+
textSecondary: c(muted ?? t.textSecondary),
|
|
4056
|
+
grid: c(s.gridColor ?? t.grid),
|
|
4057
|
+
border: c(s.gridColor ?? t.border),
|
|
4058
|
+
crosshair: c(muted ?? t.crosshair),
|
|
4005
4059
|
up: c(this.settingsValue.upColor ?? t.up),
|
|
4006
4060
|
down: c(this.settingsValue.downColor ?? t.down),
|
|
4007
4061
|
accent: c(t.accent)
|
|
@@ -4036,6 +4090,7 @@ var Chart = class {
|
|
|
4036
4090
|
requestHistory() {
|
|
4037
4091
|
const oldest = this.store.first();
|
|
4038
4092
|
if (!oldest || this.loadingHistory || this.noMoreHistory || oldest.time === this.historyRequestedFor) return;
|
|
4093
|
+
if (this.symbolLoading) return;
|
|
4039
4094
|
this.historyRequestedFor = oldest.time;
|
|
4040
4095
|
const feed = this.datafeed;
|
|
4041
4096
|
if (!feed || !this.symbol || !this.resolution) {
|
|
@@ -4043,6 +4098,8 @@ var Chart = class {
|
|
|
4043
4098
|
return;
|
|
4044
4099
|
}
|
|
4045
4100
|
const token = this.loadToken;
|
|
4101
|
+
const request = ++this.historyRequest;
|
|
4102
|
+
const current = () => token === this.loadToken && request === this.historyRequest;
|
|
4046
4103
|
this.loadingHistory = true;
|
|
4047
4104
|
const to = oldest.time - 1;
|
|
4048
4105
|
feed.getBars(this.symbol, this.resolution, {
|
|
@@ -4050,13 +4107,13 @@ var Chart = class {
|
|
|
4050
4107
|
to,
|
|
4051
4108
|
countBack: this.historyBatchSize
|
|
4052
4109
|
}).then((result) => {
|
|
4053
|
-
if (
|
|
4110
|
+
if (!current()) return;
|
|
4054
4111
|
this.prependData(result.bars, { noMoreData: result.noMoreData || result.bars.length === 0 });
|
|
4055
4112
|
const first = this.store.first();
|
|
4056
4113
|
if (first) void this.tradingSync.loadOlder(first.time);
|
|
4057
4114
|
for (const entry of this.compares.values()) void this.loadOlderCompare(entry);
|
|
4058
4115
|
}).catch((error) => this.emitter.emit("error", error)).finally(() => {
|
|
4059
|
-
if (
|
|
4116
|
+
if (current()) this.loadingHistory = false;
|
|
4060
4117
|
});
|
|
4061
4118
|
}
|
|
4062
4119
|
// ── Crosshair ──────────────────────────────────────────────────────
|
|
@@ -4497,6 +4554,7 @@ function combineDatafeeds(feeds) {
|
|
|
4497
4554
|
}
|
|
4498
4555
|
export {
|
|
4499
4556
|
BUILTIN_DRAWINGS,
|
|
4557
|
+
CHART_THEMES,
|
|
4500
4558
|
Chart,
|
|
4501
4559
|
DEFAULT_CHART_SETTINGS,
|
|
4502
4560
|
FIB_LEVELS,
|
|
@@ -4522,6 +4580,7 @@ export {
|
|
|
4522
4580
|
lightTheme,
|
|
4523
4581
|
maLines,
|
|
4524
4582
|
macd,
|
|
4583
|
+
matchChartTheme,
|
|
4525
4584
|
monitorLatency,
|
|
4526
4585
|
parseChartState,
|
|
4527
4586
|
priceSource,
|
package/dist/settings.d.ts
CHANGED
|
@@ -22,7 +22,28 @@ export interface ChartSettings {
|
|
|
22
22
|
/** Up/down candle colors; null follows the theme. */
|
|
23
23
|
upColor: string | null;
|
|
24
24
|
downColor: string | null;
|
|
25
|
+
/** Chart canvas colors (a theme from CHART_THEMES or your own); null follows the theme. `textColor` must be #rrggbb. */
|
|
26
|
+
background: string | null;
|
|
27
|
+
gridColor: string | null;
|
|
28
|
+
textColor: string | null;
|
|
25
29
|
}
|
|
30
|
+
/** The settings a chart theme sets. */
|
|
31
|
+
export type ChartThemeColors = Pick<ChartSettings, 'upColor' | 'downColor' | 'background' | 'gridColor' | 'textColor'>;
|
|
32
|
+
export interface ChartThemePreset {
|
|
33
|
+
id: string;
|
|
34
|
+
name: {
|
|
35
|
+
ko: string;
|
|
36
|
+
en: string;
|
|
37
|
+
};
|
|
38
|
+
colors: ChartThemeColors;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Ready-made chart themes for the settings dialog. Applying one sets the five color settings;
|
|
42
|
+
* 'default' clears them so the chart follows the page theme again.
|
|
43
|
+
*/
|
|
44
|
+
export declare const CHART_THEMES: readonly ChartThemePreset[];
|
|
45
|
+
/** The preset whose colors `settings` match, if any. */
|
|
46
|
+
export declare function matchChartTheme(settings: ChartSettings): ChartThemePreset | undefined;
|
|
26
47
|
export declare const DEFAULT_CHART_SETTINGS: ChartSettings;
|
|
27
48
|
/**
|
|
28
49
|
* Everything needed to restore a chart layout: symbol, interval, chart type, settings,
|